@hakuna-matata-ui/styled-system
Version:
Style function for css-in-js building component libraries
76 lines (68 loc) • 1.97 kB
text/typescript
import { Dict } from "@hakuna-matata-ui/utils"
import * as CSS from "csstype"
import { createTransform } from "./create-transform"
import { ThemeScale } from "../create-theme-vars"
import type { CssTheme, Transform } from "./types"
type CSSProp = keyof CSS.Properties | (string & {})
type MaybeArray<T> = T | T[]
type MaybeThemeFunction<T> = T | ((theme: CssTheme) => T)
type StringUnion<T> = T | (string & {})
export interface PropConfig {
/**
* This is useful for props that need to leverage CSS variables
* Static styles to append to the computed styles.
*
* It does not get replicated if value is responsive or styles are nested.
*/
static?: Dict
/**
* The theme scale this maps to
*/
scale?: ThemeScale
/**
* Css property or Css variable the prop maps to
*/
property?: MaybeThemeFunction<MaybeArray<StringUnion<CSSProp>>>
/**
* Function to transform the value passed
*/
transform?: Transform
/**
* Useful for `layerStyle`, tex`tStyles and `apply` where their
* transform function returns theme aware styles
*/
processResult?: boolean
}
export type Config = Record<string, PropConfig | true>
export function toConfig(scale: ThemeScale, transform?: Transform) {
return <T extends CSSProp>(property: T | T[]) => {
const result: PropConfig = { property, scale }
result.transform = createTransform({
scale,
transform,
})
return result
}
}
interface Opts {
scale?: ThemeScale
property: { ltr: MaybeArray<CSSProp>; rtl: MaybeArray<CSSProp> }
transform?: Transform
}
const getRtl =
({ rtl, ltr }: Opts["property"]) =>
(theme: Dict) =>
theme.direction === "rtl" ? rtl : ltr
export function logical(options: Opts): PropConfig {
const { property, scale, transform } = options
return {
scale,
property: getRtl(property),
transform: scale
? createTransform({
scale,
compose: transform,
})
: transform,
}
}