UNPKG

@hakuna-matata-ui/styled-system

Version:

Style function for css-in-js building component libraries

98 lines (83 loc) 2.29 kB
import { Dict, walkObject } from "@hakuna-matata-ui/utils" import { ThemeScale } from "./theme-tokens" import { calc, Operand } from "./calc" import { cssVar } from "./css-var" export interface CreateThemeVarsOptions { cssVarPrefix?: string } export interface ThemeVars { cssVars: Dict cssMap: Dict } export function createThemeVars(target: Dict, options: CreateThemeVarsOptions) { const context: ThemeVars = { cssMap: {}, cssVars: {}, } walkObject(target, (value, path) => { // firstKey will be e.g. "space" const [firstKey] = path const handler = tokenHandlerMap[firstKey] ?? tokenHandlerMap.defaultHandler const { cssVars, cssMap } = handler(path, value, options) Object.assign(context.cssVars, cssVars) Object.assign(context.cssMap, cssMap) }) return context } type TokenHandler = ( keys: string[], value: unknown | { reference: string }, options: CreateThemeVarsOptions, ) => ThemeVars /** * Define transformation handlers for ThemeScale */ const tokenHandlerMap: Partial<Record<ThemeScale, TokenHandler>> & { defaultHandler: TokenHandler } = { space: (keys, value, options) => { const properties = tokenHandlerMap.defaultHandler(keys, value, options) const [firstKey, ...referenceKeys] = keys const negativeLookupKey = `${firstKey}.-${referenceKeys.join(".")}` const negativeVarKey = keys.join("-") const { variable, reference } = cssVar( negativeVarKey, undefined, options.cssVarPrefix, ) const negativeValue = calc.negate(value as Operand) const varRef = calc.negate(reference) return { cssVars: properties.cssVars, cssMap: { ...properties.cssMap, [negativeLookupKey]: { value: `${negativeValue}`, var: `${variable}`, varRef, }, }, } }, defaultHandler: (keys, value, options) => { const lookupKey = keys.join(".") const varKey = keys.join("-") const { variable, reference } = cssVar( varKey, undefined, options.cssVarPrefix, ) return { cssVars: { [variable]: value, }, cssMap: { [lookupKey]: { value, var: variable, varRef: reference, }, }, } }, }