mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-05-22 14:21:44 +00:00
[add] CSS keyframes support via 'animationName' style
Keyframes can be defined using an array of objects as the value of 'animationName'. Each keyframe is transformed into a CSS keyframe rule.
This commit is contained in:
+108
-6
@@ -17,7 +17,24 @@ exports[`components/ActivityIndicator prop "animating" is "false" 1`] = `
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationName": Array [
|
||||
Object {
|
||||
"0%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "0deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
"100%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "360deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
"animationPlayState": "paused",
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 20,
|
||||
@@ -80,7 +97,24 @@ exports[`components/ActivityIndicator prop "animating" is "true" 1`] = `
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationName": Array [
|
||||
Object {
|
||||
"0%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "0deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
"100%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "360deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 20,
|
||||
"width": 20,
|
||||
@@ -177,7 +211,24 @@ exports[`components/ActivityIndicator prop "hidesWhenStopped" is "false" 1`] = `
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationName": Array [
|
||||
Object {
|
||||
"0%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "0deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
"100%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "360deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
"animationPlayState": "paused",
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 20,
|
||||
@@ -239,7 +290,24 @@ exports[`components/ActivityIndicator prop "hidesWhenStopped" is "true" 1`] = `
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationName": Array [
|
||||
Object {
|
||||
"0%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "0deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
"100%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "360deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
"animationPlayState": "paused",
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 20,
|
||||
@@ -302,7 +370,24 @@ exports[`components/ActivityIndicator prop "size" is "large" 1`] = `
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationName": Array [
|
||||
Object {
|
||||
"0%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "0deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
"100%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "360deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 36,
|
||||
"width": 36,
|
||||
@@ -363,7 +448,24 @@ exports[`components/ActivityIndicator prop "size" is a number 1`] = `
|
||||
Object {
|
||||
"animationDuration": "0.75s",
|
||||
"animationIterationCount": "infinite",
|
||||
"animationName": "rn-ActivityIndicator-animation",
|
||||
"animationName": Array [
|
||||
Object {
|
||||
"0%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "0deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
"100%": Object {
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "360deg",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
"animationTimingFunction": "linear",
|
||||
"height": 30,
|
||||
"width": 30,
|
||||
|
||||
@@ -88,7 +88,12 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
animation: {
|
||||
animationDuration: '0.75s',
|
||||
animationName: 'rn-ActivityIndicator-animation',
|
||||
animationName: [
|
||||
{
|
||||
'0%': { transform: [{ rotate: '0deg' }] },
|
||||
'100%': { transform: [{ rotate: '360deg' }] }
|
||||
}
|
||||
],
|
||||
animationTimingFunction: 'linear',
|
||||
animationIterationCount: 'infinite'
|
||||
},
|
||||
|
||||
+1
-5
@@ -23,9 +23,7 @@ html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-webkit-tap-highlig
|
||||
body{margin:0;}
|
||||
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}
|
||||
input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none;}
|
||||
}
|
||||
@keyframes rn-ActivityIndicator-animation{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg);}}
|
||||
@keyframes rn-ProgressBar-animation{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);}100%{-webkit-transform:translateX(400%);transform:translateX(400%);}}</style>"
|
||||
}</style>"
|
||||
`;
|
||||
|
||||
exports[`CSS for an unstyled app 1`] = `
|
||||
@@ -35,8 +33,6 @@ body{margin:0;}
|
||||
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}
|
||||
input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none;}
|
||||
}
|
||||
@keyframes rn-ActivityIndicator-animation{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg);}}
|
||||
@keyframes rn-ProgressBar-animation{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);}100%{-webkit-transform:translateX(400%);transform:translateX(400%);}}
|
||||
.rn-pointerEvents-12vffkv > *{pointer-events:auto}
|
||||
.rn-pointerEvents-12vffkv{pointer-events:none !important}
|
||||
.rn-alignItems-1oszu61{-ms-flex-align:stretch;-webkit-align-items:stretch;-webkit-box-align:stretch;align-items:stretch}
|
||||
|
||||
@@ -96,7 +96,12 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
animation: {
|
||||
animationDuration: '1s',
|
||||
animationName: 'rn-ProgressBar-animation',
|
||||
animationName: [
|
||||
{
|
||||
'0%': { transform: [{ translateX: '-100%' }] },
|
||||
'100%': { transform: [{ translateX: '400%' }] }
|
||||
}
|
||||
],
|
||||
animationTimingFunction: 'linear',
|
||||
animationIterationCount: 'infinite'
|
||||
}
|
||||
|
||||
+8
-3
@@ -25,6 +25,7 @@ const emptyObject = {};
|
||||
export default class ReactNativeStyleResolver {
|
||||
_init() {
|
||||
this.cache = { ltr: {}, rtl: {} };
|
||||
this.injectedCache = { ltr: {}, rtl: {} };
|
||||
this.styleSheetManager = new StyleSheetManager();
|
||||
}
|
||||
|
||||
@@ -43,7 +44,7 @@ export default class ReactNativeStyleResolver {
|
||||
|
||||
_injectRegisteredStyle(id) {
|
||||
const dir = I18nManager.isRTL ? 'rtl' : 'ltr';
|
||||
if (!this.cache[dir][id]) {
|
||||
if (!this.injectedCache[dir][id]) {
|
||||
const style = flattenStyle(id);
|
||||
const domStyle = createReactDOMStyle(i18nStyle(style));
|
||||
Object.keys(domStyle).forEach(styleProp => {
|
||||
@@ -52,7 +53,7 @@ export default class ReactNativeStyleResolver {
|
||||
this.styleSheetManager.injectDeclaration(styleProp, value);
|
||||
}
|
||||
});
|
||||
this.cache[dir][id] = true;
|
||||
this.injectedCache[dir][id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +161,11 @@ export default class ReactNativeStyleResolver {
|
||||
// Certain properties and values are not transformed by 'createReactDOMStyle' as they
|
||||
// require more complex transforms into multiple CSS rules. Here we assume that StyleManager
|
||||
// can bind these styles to a className, and prevent them becoming invalid inline-styles.
|
||||
if (styleProp === 'pointerEvents' || styleProp === 'placeholderTextColor') {
|
||||
if (
|
||||
styleProp === 'pointerEvents' ||
|
||||
styleProp === 'placeholderTextColor' ||
|
||||
styleProp === 'animationName'
|
||||
) {
|
||||
const className = this.styleSheetManager.injectDeclaration(styleProp, value);
|
||||
if (className) {
|
||||
props.classList.push(className);
|
||||
|
||||
@@ -17,10 +17,12 @@ const emptyObject = {};
|
||||
const STYLE_ELEMENT_ID = 'react-native-stylesheet';
|
||||
|
||||
const createClassName = (prop, value) => {
|
||||
const hashed = hash(prop + value);
|
||||
const hashed = hash(prop + normalizeValue(value));
|
||||
return process.env.NODE_ENV !== 'production' ? `rn-${prop}-${hashed}` : `rn-${hashed}`;
|
||||
};
|
||||
|
||||
const normalizeValue = value => (typeof value === 'object' ? JSON.stringify(value) : value);
|
||||
|
||||
export default class StyleSheetManager {
|
||||
_cache = {
|
||||
byClassName: {},
|
||||
@@ -35,8 +37,9 @@ export default class StyleSheetManager {
|
||||
}
|
||||
|
||||
getClassName(prop, value) {
|
||||
const val = normalizeValue(value);
|
||||
const cache = this._cache.byProp;
|
||||
return cache[prop] && cache[prop].hasOwnProperty(value) && cache[prop][value];
|
||||
return cache[prop] && cache[prop].hasOwnProperty(val) && cache[prop][val];
|
||||
}
|
||||
|
||||
getDeclaration(className) {
|
||||
@@ -54,10 +57,11 @@ export default class StyleSheetManager {
|
||||
}
|
||||
|
||||
injectDeclaration(prop, value): string {
|
||||
let className = this.getClassName(prop, value);
|
||||
const val = normalizeValue(value);
|
||||
let className = this.getClassName(prop, val);
|
||||
if (!className) {
|
||||
className = createClassName(prop, value);
|
||||
this._addToCache(className, prop, value);
|
||||
className = createClassName(prop, val);
|
||||
this._addToCache(className, prop, val);
|
||||
const rules = createAtomicRules(`.${className}`, prop, value);
|
||||
rules.forEach(rule => {
|
||||
this._sheet.insertRuleOnce(rule);
|
||||
@@ -66,6 +70,10 @@ export default class StyleSheetManager {
|
||||
return className;
|
||||
}
|
||||
|
||||
injectKeyframe(): string {
|
||||
// return identifier;
|
||||
}
|
||||
|
||||
_addToCache(className, prop, value) {
|
||||
const cache = this._cache;
|
||||
if (!cache.byProp[prop]) {
|
||||
|
||||
-2
@@ -11,8 +11,6 @@ body{margin:0;}
|
||||
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}
|
||||
input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none;}
|
||||
}
|
||||
@keyframes rn-ActivityIndicator-animation{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg);}}
|
||||
@keyframes rn-ProgressBar-animation{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);}100%{-webkit-transform:translateX(400%);transform:translateX(400%);}}
|
||||
.rn---test-property-ax3bxi{--test-property:test-value}",
|
||||
}
|
||||
`;
|
||||
|
||||
+13
-8
@@ -1,17 +1,22 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`StyleSheet/createAtomicRules transforms custom placeholderTextColor declaration 1`] = `
|
||||
exports[`StyleSheet/createAtomicRules transforms custom "animationName" declaration 1`] = `
|
||||
Array [
|
||||
"@media all {
|
||||
.test::-webkit-input-placeholder{color:gray;opacity:1}
|
||||
.test::-moz-placeholder{color:gray;opacity:1}
|
||||
.test:-ms-input-placeholder{color:gray;opacity:1}
|
||||
.test::placeholder{color:gray;opacity:1}
|
||||
}",
|
||||
"@media all {@-webkit-keyframes rn-anim-2k74q5{0%{top:0px}50%{top:5px}100%{top:10px}}}",
|
||||
"@media all {@keyframes rn-anim-2k74q5{0%{top:0px}50%{top:5px}100%{top:10px}}}",
|
||||
"@media all {@-webkit-keyframes rn-anim-zc91cv{from{left:0px}to{left:10px}}}",
|
||||
"@media all {@keyframes rn-anim-zc91cv{from{left:0px}to{left:10px}}}",
|
||||
".test{-webkit-animation-name:rn-anim-2k74q5,rn-anim-zc91cv;animation-name:rn-anim-2k74q5,rn-anim-zc91cv}",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/createAtomicRules transforms custom pointerEvents declaration 1`] = `
|
||||
exports[`StyleSheet/createAtomicRules transforms custom "placeholderTextColor" declaration 1`] = `
|
||||
Array [
|
||||
"@media all {.test::-webkit-input-placeholder{color:gray;opacity:1}.test::-moz-placeholder{color:gray;opacity:1}.test:-ms-input-placeholder{color:gray;opacity:1}.test::placeholder{color:gray;opacity:1}}",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/createAtomicRules transforms custom "pointerEvents" declaration 1`] = `
|
||||
Array [
|
||||
".test > *{pointer-events:none}",
|
||||
".test{pointer-events:auto !important}",
|
||||
|
||||
+10
-2
@@ -7,11 +7,19 @@ describe('StyleSheet/createAtomicRules', () => {
|
||||
expect(createAtomicRules('.test', 'margin', 0)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('transforms custom pointerEvents declaration', () => {
|
||||
test('transforms custom "animationName" declaration', () => {
|
||||
const value = [
|
||||
{ '0%': { top: 0 }, '50%': { top: 5 }, '100%': { top: 10 } },
|
||||
{ from: { left: 0 }, to: { left: 10 } }
|
||||
];
|
||||
expect(createAtomicRules('.test', 'animationName', value)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('transforms custom "pointerEvents" declaration', () => {
|
||||
expect(createAtomicRules('.test', 'pointerEvents', 'box-only')).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('transforms custom placeholderTextColor declaration', () => {
|
||||
test('transforms custom "placeholderTextColor" declaration', () => {
|
||||
expect(createAtomicRules('.test', 'placeholderTextColor', 'gray')).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import createKeyframesRules from './createKeyframesRules';
|
||||
import createRuleBlock from './createRuleBlock';
|
||||
|
||||
const createAtomicRules = (selector, prop, value) => {
|
||||
const rules = [];
|
||||
|
||||
// Handle custom properties and custom values that require additional rules
|
||||
// to be created.
|
||||
switch (prop) {
|
||||
// pointerEvents is a special case that requires custom values and additional rules
|
||||
// See #513
|
||||
case 'pointerEvents': {
|
||||
let val = value;
|
||||
@@ -28,12 +30,43 @@ const createAtomicRules = (selector, prop, value) => {
|
||||
|
||||
case 'placeholderTextColor': {
|
||||
const block = createRuleBlock({ color: value, opacity: 1 });
|
||||
rules.push(`@media all {
|
||||
${selector}::-webkit-input-placeholder{${block}}
|
||||
${selector}::-moz-placeholder{${block}}
|
||||
${selector}:-ms-input-placeholder{${block}}
|
||||
${selector}::placeholder{${block}}
|
||||
}`);
|
||||
rules.push(
|
||||
'@media all {' +
|
||||
`${selector}::-webkit-input-placeholder{${block}}` +
|
||||
`${selector}::-moz-placeholder{${block}}` +
|
||||
`${selector}:-ms-input-placeholder{${block}}` +
|
||||
`${selector}::placeholder{${block}}` +
|
||||
'}'
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'animationName': {
|
||||
if (typeof value === 'string') {
|
||||
// add a className referencing the animation
|
||||
const block = createRuleBlock({ [prop]: value });
|
||||
rules.push(`${selector}{${block}}`);
|
||||
} else {
|
||||
const animationNames = [];
|
||||
|
||||
// add the keyframes needed to implement each value
|
||||
value.forEach(keyframes => {
|
||||
if (typeof keyframes === 'string') {
|
||||
animationNames.push(keyframes);
|
||||
} else {
|
||||
const { identifier, rules: keyframesRules } = createKeyframesRules(keyframes);
|
||||
keyframesRules.forEach(rule => {
|
||||
rules.push(rule);
|
||||
});
|
||||
animationNames.push(identifier);
|
||||
}
|
||||
});
|
||||
|
||||
// add a className referencing the animation identifiers
|
||||
const block = createRuleBlock({ [prop]: animationNames.join(',') });
|
||||
rules.push(`${selector}{${block}}`);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import createRuleBlock from './createRuleBlock';
|
||||
import createReactDOMStyle from './createReactDOMStyle';
|
||||
import i18nStyle from './i18nStyle';
|
||||
import hash from '../../vendor/hash';
|
||||
|
||||
const hashObject = obj => hash(JSON.stringify(obj));
|
||||
|
||||
const createIdentifier = obj => {
|
||||
const hashed = hashObject(obj);
|
||||
return process.env.NODE_ENV !== 'production' ? `rn-anim-${hashed}` : `rn-${hashed}`;
|
||||
};
|
||||
|
||||
const prefixes = ['-webkit-', ''];
|
||||
|
||||
const makeBlock = rule => {
|
||||
const domStyle = createReactDOMStyle(i18nStyle(rule));
|
||||
return createRuleBlock(domStyle);
|
||||
};
|
||||
|
||||
const makeSteps = keyframes =>
|
||||
Object.keys(keyframes)
|
||||
.map(stepName => {
|
||||
const rule = keyframes[stepName];
|
||||
const block = makeBlock(rule);
|
||||
return `${stepName}{${block}}`;
|
||||
})
|
||||
.join('');
|
||||
|
||||
const createKeyframesRules = (keyframes: Object): Array<String> => {
|
||||
const identifier = createIdentifier(keyframes);
|
||||
const rules = prefixes.map(prefix => {
|
||||
return `@media all {@${prefix}keyframes ${identifier}{${makeSteps(keyframes)}}}`;
|
||||
});
|
||||
return { identifier, rules };
|
||||
};
|
||||
|
||||
export default createKeyframesRules;
|
||||
@@ -25,12 +25,12 @@ const createDeclarationString = (prop, val) => {
|
||||
/**
|
||||
* Generates valid CSS rule body from a JS object
|
||||
*
|
||||
* generateCss({ width: 20, color: 'blue' });
|
||||
* createRuleBlock({ width: 20, color: 'blue' });
|
||||
* // => 'color:blue;width:20px'
|
||||
*/
|
||||
const generateCss = style =>
|
||||
const createRuleBlock = style =>
|
||||
mapKeyValue(prefixStyles(style), createDeclarationString)
|
||||
.sort()
|
||||
.join(';');
|
||||
|
||||
export default generateCss;
|
||||
export default createRuleBlock;
|
||||
|
||||
@@ -22,19 +22,6 @@ const resets = [
|
||||
'input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none;}'
|
||||
];
|
||||
|
||||
const reset = safeRule(resets.join('\n'));
|
||||
const reset = [safeRule(resets.join('\n'))];
|
||||
|
||||
const initialRules = [
|
||||
reset,
|
||||
// temporary keyframes
|
||||
'@keyframes rn-ActivityIndicator-animation{' +
|
||||
'0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);}' +
|
||||
'100%{-webkit-transform:rotate(360deg);transform:rotate(360deg);}' +
|
||||
'}',
|
||||
'@keyframes rn-ProgressBar-animation{' +
|
||||
'0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);}' +
|
||||
'100%{-webkit-transform:translateX(400%);transform:translateX(400%);}' +
|
||||
'}'
|
||||
];
|
||||
|
||||
export default initialRules;
|
||||
export default reset;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import { number, oneOf, oneOfType, string } from 'prop-types';
|
||||
import { arrayOf, number, object, oneOf, oneOfType, string } from 'prop-types';
|
||||
|
||||
const AnimationPropTypes = {
|
||||
animationDelay: string,
|
||||
@@ -16,7 +16,7 @@ const AnimationPropTypes = {
|
||||
animationDuration: string,
|
||||
animationFillMode: oneOf(['none', 'forwards', 'backwards', 'both']),
|
||||
animationIterationCount: oneOfType([number, oneOf(['infinite'])]),
|
||||
animationName: string,
|
||||
animationName: oneOfType([string, arrayOf(oneOfType([string, object]))]),
|
||||
animationPlayState: oneOf(['paused', 'running']),
|
||||
animationTimingFunction: string
|
||||
};
|
||||
|
||||
@@ -54,4 +54,5 @@ function murmurhash2_32_gc(str, seed) {
|
||||
}
|
||||
|
||||
const hash = str => murmurhash2_32_gc(str, 1).toString(36);
|
||||
|
||||
export default hash;
|
||||
|
||||
@@ -334,7 +334,7 @@ const stylePropTypes = [
|
||||
{
|
||||
label: 'web',
|
||||
name: 'animationName',
|
||||
typeInfo: 'string'
|
||||
typeInfo: 'string | Array<Object>'
|
||||
},
|
||||
{
|
||||
label: 'web',
|
||||
@@ -776,7 +776,7 @@ const stylePropTypes = [
|
||||
},
|
||||
{
|
||||
name: 'transform',
|
||||
typeInfo: 'array'
|
||||
typeInfo: 'Array<Object>'
|
||||
},
|
||||
{
|
||||
label: 'web',
|
||||
|
||||
Reference in New Issue
Block a user