Skip to content

Commit 8a16ecb

Browse files
author
Henri
authored
Add support for dynamic keyframes (#1043)
* Add support for dynamic keyframes * Fix replacing the ref * Add a failing test * Update size-snapshot * Add more tests * Update changelog * Run prettier * Remove unnecessary condition * Update size-snapshot
1 parent 2cc1077 commit 8a16ecb

4 files changed

Lines changed: 124 additions & 32 deletions

File tree

changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
### Bug fixes
44

5+
- [jss] Fix using function values with scoped keyframes ([#1043](https://github.com/cssinjs/jss/pull/1043))
56
- [jss] Fix removing styles from function rules ([#1046](https://github.com/cssinjs/jss/pull/1046))
67

78
## 10.0.0-alpha.11 (2019-2-24)
89

910
### Bug fixes
1011

11-
- [jss] Fix dynamic values inside of @global plugin ([#1040](https://github.com/cssinjs/jss/pull/1040))
12+
- [jss] Fix dynamic values inside of @global plugin ([#664](https://github.com/cssinjs/jss/pull/664))
1213

1314
### Improvements
1415

packages/jss-plugin-rule-value-function/src/function-values.test.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,68 @@ describe('jss-plugin-rule-value-function: Function values', () => {
360360
})
361361
})
362362

363+
describe('keyframe names', () => {
364+
it('should work with animation-name', () => {
365+
const sheet = jss.createStyleSheet({
366+
'@keyframes animateIn': {},
367+
368+
'@keyframes animateOut': {},
369+
370+
a: {'animation-name': ({name}) => name}
371+
})
372+
373+
sheet.update({name: '$animateIn'})
374+
375+
expect(sheet.toString()).to.be(stripIndent`
376+
@keyframes keyframes-animateIn-id {}
377+
@keyframes keyframes-animateOut-id {}
378+
.a-id {
379+
animation-name: keyframes-animateIn-id;
380+
}
381+
`)
382+
383+
sheet.update({name: '$animateOut'})
384+
385+
expect(sheet.toString()).to.be(stripIndent`
386+
@keyframes keyframes-animateIn-id {}
387+
@keyframes keyframes-animateOut-id {}
388+
.a-id {
389+
animation-name: keyframes-animateOut-id;
390+
}
391+
`)
392+
})
393+
394+
it('should work with animation prop', () => {
395+
const sheet = jss.createStyleSheet({
396+
'@keyframes animateIn': {},
397+
398+
'@keyframes animateOut': {},
399+
400+
a: {animation: ({name}) => `${name} 5s`}
401+
})
402+
403+
sheet.update({name: '$animateIn'})
404+
405+
expect(sheet.toString()).to.be(stripIndent`
406+
@keyframes keyframes-animateIn-id {}
407+
@keyframes keyframes-animateOut-id {}
408+
.a-id {
409+
animation: keyframes-animateIn-id 5s;
410+
}
411+
`)
412+
413+
sheet.update({name: '$animateOut'})
414+
415+
expect(sheet.toString()).to.be(stripIndent`
416+
@keyframes keyframes-animateIn-id {}
417+
@keyframes keyframes-animateOut-id {}
418+
.a-id {
419+
animation: keyframes-animateOut-id 5s;
420+
}
421+
`)
422+
})
423+
})
424+
363425
describe('rule.toJSON()', () => {
364426
it('should handle function values', () => {
365427
const sheet = jss.createStyleSheet({

packages/jss/.size-snapshot.json

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
{
22
"dist/jss.js": {
3-
"bundled": 59048,
4-
"minified": 21980,
5-
"gzipped": 6562
3+
"bundled": 59675,
4+
"minified": 22216,
5+
"gzipped": 6638
66
},
77
"dist/jss.min.js": {
8-
"bundled": 57866,
9-
"minified": 21066,
10-
"gzipped": 6117
8+
"bundled": 58509,
9+
"minified": 21298,
10+
"gzipped": 6195
1111
},
1212
"dist/jss.cjs.js": {
13-
"bundled": 54490,
14-
"minified": 23905,
15-
"gzipped": 6613
13+
"bundled": 55077,
14+
"minified": 24175,
15+
"gzipped": 6694
1616
},
1717
"dist/jss.esm.js": {
18-
"bundled": 53994,
19-
"minified": 23501,
20-
"gzipped": 6533,
18+
"bundled": 54581,
19+
"minified": 23771,
20+
"gzipped": 6613,
2121
"treeshaked": {
2222
"rollup": {
23-
"code": 19125,
23+
"code": 19358,
2424
"import_statements": 281
2525
},
2626
"webpack": {
27-
"code": 20541
27+
"code": 20773
2828
}
2929
}
3030
}

packages/jss/src/plugins/keyframesRule.js

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
/* @flow */
22
import warning from 'tiny-warning'
33
import RuleList from '../RuleList'
4-
import type StyleSheet from '../StyleSheet'
54
import type {
65
CSSKeyframesRule,
76
JssStyle,
8-
Rule,
97
RuleOptions,
108
ToCssOptions,
119
ContainerRule,
12-
KeyframesMap
10+
KeyframesMap,
11+
Plugin
1312
} from '../types'
1413

1514
const defaultToStringOptions = {
@@ -82,36 +81,66 @@ const keyRegExp = /@keyframes\s+/
8281

8382
const refRegExp = /\$([\w-]+)/
8483

84+
const findReferencedKeyframe = (val, keyframes) => {
85+
if (typeof val === 'string') {
86+
const ref = refRegExp.exec(val)
87+
88+
if (!ref) return val
89+
90+
if (ref[1] in keyframes) {
91+
return val.replace(ref[0], keyframes[ref[1]])
92+
}
93+
94+
warning(false, `[JSS] Referenced keyframes rule "${ref[1]}" is not defined.`)
95+
}
96+
97+
return val
98+
}
99+
85100
/**
86101
* Replace the reference for a animation name.
87102
*/
88103
const replaceRef = (style: JssStyle, prop: string, keyframes: KeyframesMap) => {
89104
const value = style[prop]
105+
const refKeyframe = findReferencedKeyframe(value, keyframes)
90106

91-
if (typeof value === 'string') {
92-
const ref = refRegExp.exec(value)
93-
94-
if (!ref) return
95-
96-
if (ref[1] in keyframes) {
97-
style[prop] = value.replace(ref[0], keyframes[ref[1]])
98-
} else {
99-
warning(false, `[JSS] Referenced keyframes rule "${ref[1]}" is not defined.`)
100-
}
107+
if (refKeyframe !== value) {
108+
style[prop] = refKeyframe
101109
}
102110
}
103111

104-
export default {
105-
onCreateRule(key: string, frames: JssStyle, options: RuleOptions): KeyframesRule | null {
106-
return keyRegExp.test(key) ? new KeyframesRule(key, frames, options) : null
112+
const plugin: Plugin = {
113+
onCreateRule(key, frames, options) {
114+
return typeof key === 'string' && keyRegExp.test(key)
115+
? new KeyframesRule(key, frames, options)
116+
: null
107117
},
108118

109119
// Animation name ref replacer.
110-
onProcessStyle: (style: JssStyle, rule: Rule, sheet?: StyleSheet): JssStyle => {
120+
onProcessStyle: (style, rule, sheet) => {
111121
if (rule.type !== 'style' || !sheet) return style
112122

113123
if ('animation-name' in style) replaceRef(style, 'animation-name', sheet.keyframes)
114124
if ('animation' in style) replaceRef(style, 'animation', sheet.keyframes)
115125
return style
126+
},
127+
128+
onChangeValue(val, prop, rule) {
129+
const {sheet} = rule.options
130+
131+
if (!sheet) {
132+
return val
133+
}
134+
135+
switch (prop) {
136+
case 'animation':
137+
return findReferencedKeyframe(val, sheet.keyframes)
138+
case 'animation-name':
139+
return findReferencedKeyframe(val, sheet.keyframes)
140+
default:
141+
return val
142+
}
116143
}
117144
}
145+
146+
export default plugin

0 commit comments

Comments
 (0)