import * as T from "./types" ; import { BREAKPOINTS } from "./constants" ; import { interpolate } from "./interpolate" ; import { render } from "./render" ; import { mq , get , resolve , isArray , isNil , isFunction , isObject , isPlainObject , isUndefined } from "./utils" ; export function style < P extends T . ThemeProps , S extends T . Style > ( options ) { const { propsKeys , styleKeys , themeKeys , transform , renderers , defaults } = options ; if ( ! isArray ( propsKeys ) || propsKeys . length < 1 ) { throw Error ( "propsKeys must be an array containing at least one key" ) ; } const name = propsKeys [ 0 ] ; const keys = isArray ( styleKeys ) ? styleKeys : propsKeys . slice ( 0 , 1 ) ; const transformer = isArray ( renderers ) && renderers . length > 0 && interpolate < P , S > ( { name , renderers } ) ; if ( isUndefined ( styleKeys ) ) options . styleKeys = keys ; const renderValue = ( value , theme ? ) : any => { let themeValue = resolve ( themeKeys , theme ) ; if ( ! isUndefined ( themeValue ) ) { if ( value !== "." ) { themeValue = resolve ( themeKeys ! . map ( ( k ) => `${ k }.${ value }` ) , theme ) ; } if ( ! isNil ( themeValue ) ) value = themeValue ; } else if ( defaults ) { const defaultValue = get ( value , defaults ) ; if ( ! isNil ( defaultValue ) ) value = defaultValue ; } if ( isFunction ( transform ) ) value = transform ( value ) ; if ( styleKeys === null ) { return isPlainObject ( value ) ? value : null ; } else { return render < S > ( keys , value ) ; } } ; const renderProps = ( props ) => { const propsValue = resolve ( propsKeys , props ) ; if ( isNil ( propsValue ) ) return null ; const { theme } = props ; const styles = [ ] ; const pushStyle = ( value , query ? ) => { let result = renderValue ( value , theme ) ; if ( result ) { if ( transformer ) result = transformer ( result , theme ) ; if ( query ) result = { [ query ] : result } ; styles . push ( result ) ; } } ; if ( isObject ( propsValue ) ) { const themeBreaks = theme && theme . breakpoints ; const breakpoints = isUndefined ( themeBreaks ) ? BREAKPOINTS : themeBreaks ; if ( isArray ( breakpoints ) ) { breakpoints . forEach ( ( value , index ) => { const breakpoint = get ( index , breakpoints ) ; const isZero = parseInt ( breakpoint , 10 ) === 0 ; const query = isZero ? null : mq ( breakpoint ) ; const styleValue = resolve ( [ index , value . alias ] , propsValue ) ; if ( ! isNil ( styleValue ) ) pushStyle ( styleValue , query ) ; } ) ; } } else pushStyle ( propsValue ) ; return styles . length ? styles : null ; } ; Object . defineProperty ( renderProps , "name" , { value : name } ) ; renderProps . type = "style" as "style" ; renderProps . options = options ; if ( transformer ) renderProps . transformer = transformer ; return renderProps ; } export function variant < P extends T . ThemeProps , S extends T . Style > ( options ) { const renderProps = style < P , S > ( { ... options , styleKeys : null } ) ; renderProps . type = "variant" as "variant" ; return renderProps ; } export function extend ( a ) { return < P extends T . ThemeProps , S extends T . Style > ( b ) => style < P , S > ( { ... a , ... b } ) ; }