import { AllRules , stylePropsText , stylePropsTransform , validStyles , validStylesPseudo , } from '@tamagui/helpers' ; import { ViewStyle } from 'react-native' ; import { isWeb } from '../constants/platform' ; import { mediaQueryConfig , mediaState } from '../hooks/useMedia' ; import { StaticConfigParsed , ThemeObject } from '../types' ; import { createMediaStyle } from './createMediaStyle' ; import { fixNativeShadow } from './fixNativeShadow' ; import { getStylesAtomic } from './getStylesAtomic' ; import { insertStyleRule } from './insertStyleRule' ; export type SplitStyles = ReturnType < typeof getSplitStyles > ; export const getSplitStyles = ( props , staticConfig , theme , isSplittingDefaultProps ? ) => { const validStyleProps = staticConfig . isText ? stylePropsText : validStyles ; const viewProps = { } ; const style = [ ] ; let pseudos = null ; let cur = null ; let classNames = null ; for ( const keyInit in props ) { const valInit = props [ keyInit ] ; if ( keyInit [ 0 ] === '$' ) { const mediaKey = keyInit . slice ( 1 ) ; if ( ! mediaQueryConfig [ mediaKey ] ) { viewProps [ keyInit ] = valInit ; continue ; } const mediaProps = { ... props , ... valInit } ; const mediaStyle = getSubStyle ( valInit , staticConfig , theme , props ) ; if ( isWeb ) { const mediaStyles = getStylesAtomic ( mediaStyle ) ; if ( process . env . NODE_ENV === 'development' ) { if ( props [ 'debug' ] ) { console . log ( 'mediaStyles' , keyInit , { mediaProps , mediaStyle , mediaStyles } ) ; } } for ( const style of mediaStyles ) { const out = createMediaStyle ( style , mediaKey , mediaQueryConfig ) ; classNames = classNames || [ ] ; classNames . push ( out . identifier ) ; AllRules . add ( out . styleRule ) ; insertStyleRule ( out . styleRule ) ; if ( process . env . NODE_ENV === 'development' && props [ 'debug' ] ) { console . log ( 'mediaProp' , style . identifier , out , mediaProps , mediaStyle , mediaStyles ) ; } } } else { if ( mediaState [ mediaKey ] ) { style . push ( mediaStyle ) ; } } continue ; } if ( validStylesPseudo [ keyInit ] ) { if ( ! valInit ) continue ; pseudos = pseudos || { } ; pseudos [ keyInit ] = getSubStyle ( valInit , staticConfig , theme , props ) ; continue ; } const out = staticConfig . propMapper ( keyInit , valInit , theme , props ) ; const expanded = out === true || ! out ? [ [ keyInit , valInit ] ] : Object . entries ( out ) ; for ( const [ key , val ] of expanded ) { const keyFirstChar = key [ 0 ] ; if ( key === 'style' || ( keyFirstChar === '_' && key . startsWith ( '_style' ) ) ) { if ( cur ) { fixNativeShadow ( cur ) ; style . push ( cur ) ; cur = null ; } fixNativeShadow ( val ) ; style . push ( val ) ; continue ; } if ( key === 'flex' ) { cur = cur || { } ; Object . assign ( cur , { flexGrow : val , flexShrink : 1 , } ) ; continue ; } if ( ! isWeb && key === 'pointerEvents' ) { viewProps [ key ] = val ; continue ; } if ( validStyleProps [ key ] ) { if ( key in stylePropsTransform ) { cur = cur || { } ; mergeTransform ( cur , key , val ) ; continue ; } cur = cur || { } ; cur [ key ] = val ; continue ; } if ( ! staticConfig . variants || ! ( key in staticConfig . variants ) ) { viewProps [ key ] = val ; } } } if ( cur ) { fixNativeShadow ( cur ) ; style . push ( cur ) ; } if ( process . env . NODE_ENV === 'development' ) { if ( props [ 'debug' ] ) { console . log ( ' 🥚 splitProps:' , { props , viewProps , style } ) ; } } return { viewProps , style , pseudos , classNames , } ; } ; const getSubStyle = ( styleIn , staticConfig , theme , props ) : ViewStyle => { const styleOut = { } ; for ( const key in styleIn ) { const val = styleIn [ key ] ; const out = staticConfig . propMapper ( key , val , theme , props ) ; const expanded = out === true || ! out ? [ [ key , val ] ] : Object . entries ( out ) ; for ( const [ skey , sval ] of expanded ) { if ( skey in stylePropsTransform ) { mergeTransform ( styleOut , skey , sval ) ; } else { styleOut [ skey ] = sval ; } } } fixNativeShadow ( styleOut ) ; return styleOut ; } ; const mapTransformKeys = { x : 'translateX' , y : 'translateY' , } ; const mergeTransform = ( obj , key , val ) => { const transform = obj . transform ? Array . isArray ( obj . transform ) ? obj . transform : [ obj . transform ] : [ ] ; transform . push ( { [ mapTransformKeys [ key ] || key ] : val } ) ; obj . transform = transform ; } ;