import { css } from '@o/css' import { motion } from 'framer-motion' import { Flex, gloss } from 'gloss' import { AnimationStore } from '../Geometry' import { elevationTheme } from './elevation' import { marginTheme } from './marginTheme' import { motionExtraProps, motionStyleProps } from './motionStyleProps' import { paddingTheme } from './paddingTheme' import { ViewPropsPlain } from './types' const shouldRenderToMotion = (props: any) => 'animate' in props || 'drag' in props || 'layoutTransition' in props export const View = gloss(Flex, { display: 'flex', // we handle this with paddingTheme/marginTheme ignorePropsToStyle: { padding: true, margin: true, }, config: { // shouldAvoidProcessingStyles: shouldRenderToMotion, postProcessProps(inProps, outProps, getStyles) { if (shouldRenderToMotion(inProps)) { let style = css(getStyles(), { snakeCase: false }) for (const key in inProps) { const val = inProps[key] if (val instanceof AnimationStore) { style[key] = val.getValue() delete outProps[key] continue } if (motionStyleProps[key]) { style[key] = val delete outProps[key] continue } if (motionExtraProps[key]) { if (key === 'animate' && inProps.animate === true) { continue } outProps[key] = val } } if (inProps.style) { Object.assign(style, inProps.style) } // outProps.className = finalClassName style['willChange'] = 'transform' outProps.style = style outProps['data-is'] = `${outProps['data-is']} is-animated` } }, isDOMElement: true, getElement(props) { return shouldRenderToMotion(props) ? motion[props.tagName] || motion.div : props.tagName || 'div' }, }, }).theme(marginTheme, paddingTheme, elevationTheme) View.staticStyleConfig = { ...View.staticStyleConfig, deoptProps: ['animate', 'drag', 'layoutTransition'], }