UNPKG

react-native-reanimated

Version:

More powerful alternative to Animated library for React Native.

107 lines (97 loc) 3.63 kB
'use strict'; import { logger } from '../../common'; import { isSharedValue } from '../../isSharedValue'; import type { AnyRecord, CSSAnimationProperties, CSSStyle, CSSTransitionProperties, ExistingCSSAnimationProperties, PlainStyle, } from '../types'; import { isAnimationProp, isCSSKeyframesObject, isCSSKeyframesRule, isTransitionProp, } from './guards'; export function filterCSSAndStyleProperties<S extends AnyRecord>( style: CSSStyle<S> ): [ ExistingCSSAnimationProperties | null, CSSTransitionProperties | null, PlainStyle, ] { const animationProperties: Partial<CSSAnimationProperties> = {}; let transitionProperties: Partial<CSSTransitionProperties> = {}; const filteredStyle: AnyRecord = {}; for (const [prop, value] of Object.entries(style)) { if (isAnimationProp(prop)) { // TODO - add support for animation shorthand animationProperties[prop] = value; } else if (isTransitionProp(prop)) { // If there is a shorthand `transition` property, all properties specified // before are ignored and only these specified later are taken into account // and override ones from the shorthand if (prop === 'transition') { transitionProperties = { transition: value }; } else { transitionProperties[prop] = value; } } else if (!isSharedValue(value)) { filteredStyle[prop] = value; } } // Return animationProperties only if at least one animationName contains // valid keyframes const animationName = animationProperties.animationName; const hasAnimationName = animationName && (Array.isArray(animationName) ? animationName : [animationName]).every( (keyframes) => keyframes === 'none' ? false : isCSSKeyframesRule(keyframes) || isCSSKeyframesObject(keyframes) ); const finalAnimationConfig = hasAnimationName ? ({ ...animationProperties, animationName, } as ExistingCSSAnimationProperties) : null; // Return transitionProperties only if the transitionProperty is present const hasTransitionConfig = Object.keys(transitionProperties).length > 0; const finalTransitionConfig = hasTransitionConfig ? transitionProperties : null; if (__DEV__) { validateCSSAnimationProps(animationProperties); validateCSSTransitionProps(transitionProperties); } return [finalAnimationConfig, finalTransitionConfig, filteredStyle]; } function validateCSSAnimationProps(props: Partial<CSSAnimationProperties>) { // Check if any animation properties are present but animationName is missing if (!('animationName' in props) && Object.keys(props).length > 0) { logger.warn( 'CSS animation properties were provided without specifying animationName.\n' + 'If unintended, add animationName or remove unnecessary animation properties.' ); } // Check if animationDuration is missing when animationName is present if (!('animationDuration' in props) && 'animationName' in props) { logger.warn( 'animationDuration was not specified for CSS animation. The default duration is 0s.\n' + 'Have you forgotten to pass the animationDuration?' ); } } function validateCSSTransitionProps(props: Partial<CSSTransitionProperties>) { // Check if transitionDuration is missing when transitionProperty is present if (!('transitionDuration' in props) && 'transitionProperty' in props) { logger.warn( 'transitionDuration was not specified for CSS transition. The default duration is 0s.\n' + 'Have you forgotten to pass the transitionDuration?' ); } }