import _kebabCase from 'lodash/kebabCase' ; import { altitude , border , borderRadius , font , fontSize , lineHeight , palette , space , fontWeight , letterSpacing , } from './theme' ; import { Platform } from 'react-native' ; const FLEX_HORIZONTAL_ALIGN_MAP = { left : 'flex-start' , center : 'center' , right : 'flex-end' , } ; const FLEX_VERTICAL_ALIGN_MAP = { top : 'flex-start' , center : 'center' , bottom : 'flex-end' , } ; const alignAttributes = [ 'alignX' , 'alignY' ] ; const altitudeAttributes = [ 'altitude' ] ; const borderAttributes = [ 'border' ] ; const borderRadiusAttributes = [ 'borderRadius' , 'borderLeftRadius' , 'borderRightRadius' , 'borderTopRadius' , 'borderBottomRadius' , 'borderTopLeftRadius' , 'borderBottomLeftRadius' , 'borderTopRightRadius' , 'borderBottomRightRadius' , ] ; const colorAttributes = [ 'color' , 'backgroundColor' , 'borderBlockEndColor' , 'borderBlockStartColor' , 'borderBottomColor' , 'borderColor' , 'borderInlineEndColor' , 'borderInlineStartColor' , 'borderLeftColor' , 'borderRightColor' , 'borderTopColor' , 'borderBottomColor' , 'caretColor' , 'columnRuleColor' , 'outlineColor' , 'textDecorationColor' , 'textEmphasisColor' , ] ; const spaceAttributes = [ 'margin' , 'marginLeft' , 'marginRight' , 'marginTop' , 'marginBottom' , 'marginX' , 'marginY' , 'padding' , 'paddingLeft' , 'paddingRight' , 'paddingTop' , 'paddingBottom' , 'paddingX' , 'paddingY' , 'top' , 'left' , 'bottom' , 'right' , 'grid-gap' , 'grid-column-gap' , 'grid-row-gap' , 'height' , 'width' , 'minWidth' , 'minHeight' , 'maxWidth' , 'maxHeight' , ] ; const fontAttributes = [ 'font' , 'fontFamily' ] ; const fontSizeAttributes = [ 'fontSize' ] ; const fontWeightAttributes = [ 'fontWeight' ] ; const lineHeightAttributes = [ 'lineHeight' ] ; const letterSpacingAttributes = [ 'letterSpacing' ] ; const attributeMaps = { font : [ 'fontFamily' ] , marginY : [ 'marginTop' , 'marginBottom' ] , paddingY : [ 'paddingTop' , 'paddingBottom' ] , marginX : [ 'marginLeft' , 'marginRight' ] , paddingX : [ 'paddingLeft' , 'paddingRight' ] , borderTopRadius : [ 'borderTopLeftRadius' , 'borderTopRightRadius' ] , borderBottomRadius : [ 'borderBottomLeftRadius' , 'borderBottomRightRadius' ] , borderLeftRadius : [ 'borderTopLeftRadius' , 'borderBottomLeftRadius' ] , borderRightRadius : [ 'borderTopRightRadius' , 'borderBottomRightRadius' ] , } ; const platforms = [ 'web' , 'native' , 'ios' , 'android' ] ; function isPlatform ( selector ) { return platforms . includes ( selector ) ; } const states = [ 'hover' , 'hoveractive' , 'focus' , 'active' ] ; function isPseudo ( selector ) { return states . includes ( selector ) ; } export function getAlignmentStyles ( { attribute , value , props } ) { const alignYAttribute = props . display && props . display . includes ( 'flex' ) ? 'align-items' : 'justify-content' ; const alignXAttribute = props . display && props . display . includes ( 'flex' ) ? 'justify-content' : 'align-items' ; return `
      display: flex;

      ${ ! props . display && `
          flex-direction: column;
        ` }

      ${ attribute === 'alignY' && `
          ${ alignYAttribute }: ${ FLEX_VERTICAL_ALIGN_MAP [ value ] };
        ` }

      ${ attribute === 'alignX' && `
          ${ alignXAttribute }: ${ FLEX_HORIZONTAL_ALIGN_MAP [ value ] };
        ` }
    ` ; } function getAltitudeStyles ( { theme , value } ) { const altitudeStyle = altitude ( value ) ( { theme } ) ; if ( altitudeStyle ) { return altitudeStyle ; } return value ; } function getBorderValue ( { theme , value } ) { const borderValue = border ( value ) ( { theme } ) ; if ( borderValue ) { const borderColor = palette ( borderValue . color ) ( { theme } ) ; return `${ borderValue . width } ${ borderValue . style } ${ borderColor }` ; } return value ; } function getBorderRadiusValue ( { theme , value } ) { const borderRadiusValue = borderRadius ( value ) ( { theme } ) ; if ( borderRadiusValue ) { return borderRadiusValue ; } return value ; } function getColorValue ( { colorMode , theme , value } ) { const color = palette ( value ) ( { colorMode , theme } ) ; if ( color ) { return color ; } return value ; } function getSpaceValue ( { theme , value } ) { const spacing = space ( value ) ( { theme } ) ; if ( spacing ) { return `${ spacing }px` ; } return value ; } function getFontValue ( { theme , value } ) { const fontValue = font ( value ) ( { theme } ) ; if ( fontValue ) { return fontValue ; } return value ; } function getFontSizeValue ( { theme , value } ) { const size = fontSize ( value ) ( { theme } ) ; if ( size ) { return `${ size }px` ; } return value ; } function getFontWeightValue ( { theme , value , fontFamily } ) { const weight = fontWeight ( { fontFamily , fontWeight : value } ) ( { theme } ) ; if ( weight ) { return weight ; } return value ; } function getLineHeightValue ( { theme , value } ) { const height = lineHeight ( value ) ( { theme } ) ; if ( height ) { return height ; } return value ; } function getLetterSpacingValue ( { theme , value } ) { const spacing = letterSpacing ( value ) ( { theme } ) ; if ( spacing ) { return spacing ; } return value ; } export function getCSSFromStyleObject ( props , theme , colorMode , { fromProps = false , disableCSSProps = [ ] , events = { } } = { } ) { let style = { ... props } ; if ( style ) { let styleEntries = Object . entries ( style ) ; styleEntries = styleEntries . reduce ( ( prevStyle , [ attribute , value ] ) => { let entries = [ [ attribute , value ] ] ; if ( attributeMaps [ attribute ] ) { entries = attributeMaps [ attribute ] . map ( ( attribute ) => [ attribute , value ] ) ; } return [ ... prevStyle , ... entries ] ; } , [ ] ) ; style = styleEntries . reduce ( ( prevStyle , [ attribute , value ] ) => { let newValue = value ; if ( typeof value === 'function' ) { newValue = value ( { colorMode , theme } ) ; } if ( attribute . includes ( ':' ) ) { return `
          ${ prevStyle ? `${ prevStyle };` : '' }

          ${ attribute } {
            ${ getCSSFromStyleObject ( value , theme , colorMode , { fromProps } ) };
          }
        ` ; } if ( typeof newValue === 'string' ) { newValue = { default : newValue } ; } if ( attribute . includes ( '_' ) ) { const selector = attribute . slice ( 1 ) ; if ( isPlatform ( selector ) ) { const platform = selector ; return `
            ${ prevStyle ? `${ prevStyle };` : '' }
            ${ ( Platform . OS === platform || ( platform === 'native' && Platform . OS !== 'web' ) ) && getCSSFromStyleObject ( value , theme , colorMode , { fromProps } ) }
          ` ; } if ( isPseudo ( selector ) ) { return `
            ${ prevStyle ? `${ prevStyle };` : '' }
            ${ events [ selector ] ? getCSSFromStyleObject ( value , theme , colorMode , { fromProps } ) : '' }
          ` ; } } const newStyle = Object . entries ( newValue || { } ) . reduce ( ( prevStyle , [ platform , value ] ) => { let newStyle ; let newValue = value ; if ( alignAttributes . includes ( attribute ) ) { newStyle = getAlignmentStyles ( { attribute , value , props } ) ; newValue = undefined ; } if ( altitudeAttributes . includes ( attribute ) ) { newStyle = getAltitudeStyles ( { theme , value } ) ; newValue = undefined ; } if ( borderAttributes . includes ( attribute ) ) { newValue = getBorderValue ( { theme , value } ) ; } if ( borderRadiusAttributes . includes ( attribute ) ) { newValue = getBorderRadiusValue ( { theme , value } ) ; } if ( colorAttributes . includes ( attribute ) ) { newValue = getColorValue ( { colorMode , theme , value } ) ; } if ( spaceAttributes . includes ( attribute ) ) { newValue = getSpaceValue ( { theme , value } ) ; } if ( fontAttributes . includes ( attribute ) ) { newValue = '' ; } if ( fontSizeAttributes . includes ( attribute ) ) { if ( disableCSSProps . includes ( 'fontSize' ) ) { return { } ; } newValue = getFontSizeValue ( { theme , value } ) ; } if ( fontWeightAttributes . includes ( attribute ) ) { const fontFamilyKey = props . font || props . fontFamily || 'default' ; newValue = getFontWeightValue ( { theme , value , fontFamily : fontFamilyKey } ) ; const fontFamily = font ( fontFamilyKey ) ( { theme } ) ; if ( typeof newValue === 'object' ) { newStyle = `
              font-family: ${ fontFamily }${ newValue . fontFamilySuffix ? `${ newValue . fontFamilySuffix }` : '' };
            ` ; newValue = newValue . fontWeight ; } else if ( fontFamily ) { newStyle = `
              font-family: ${ fontFamily };
            ` ; } } if ( lineHeightAttributes . includes ( attribute ) ) { newValue = getLineHeightValue ( { theme , value } ) ; } if ( letterSpacingAttributes . includes ( attribute ) ) { newValue = getLetterSpacingValue ( { theme , value } ) ; } if ( platform === 'default' || Platform . OS === platform || ( platform === 'native' && Platform . OS !== 'web' ) ) { return `
            ${ newStyle ? `${ newStyle };` : '' }
            ${ prevStyle ? `${ prevStyle };` : '' }
            ${ newValue ? `
                  ${ _kebabCase ( attribute ) }: ${ newValue };
                ` : '' }
          ` ; } return `
          ${ newStyle ? `${ newStyle };` : '' }
          ${ prevStyle ? `${ prevStyle };` : '' }
        ` ; } , `` ) ; return `
        ${ newStyle ? `${ newStyle };` : '' }
        ${ prevStyle ? `${ prevStyle };` : '' }
      ` ; } , `` ) ; } return style ; }