UNPKG

@hakuna-matata-ui/styled-system

Version:

Style function for css-in-js building component libraries

87 lines (83 loc) 2.82 kB
import { Dict, isCssVar, isNumber, isString } from "@hakuna-matata-ui/utils" import { backdropFilterTemplate, filterTemplate, getRingTemplate, getTransformGpuTemplate, getTransformTemplate, flexDirectionTemplate, } from "./templates" import { gradientTransform, globalSet, isCSSFunction } from "./parse-gradient" const analyzeCSSValue = (value: number | string) => { const num = parseFloat(value.toString()) const unit = value.toString().replace(String(num), "") return { unitless: !unit, value: num, unit } } const wrap = (str: string) => (value: any) => `${str}(${value})` export const transformFunctions = { filter(value: any) { return value !== "auto" ? value : filterTemplate }, backdropFilter(value: any) { return value !== "auto" ? value : backdropFilterTemplate }, ring(value: string) { return getRingTemplate(transformFunctions.px(value)) }, bgClip(value: string) { return value === "text" ? { color: "transparent", backgroundClip: "text" } : { backgroundClip: value } }, transform(value: any) { if (value === "auto") return getTransformTemplate() if (value === "auto-gpu") return getTransformGpuTemplate() return value }, px(value: number | string) { if (value == null) return value const { unitless } = analyzeCSSValue(value) return unitless || isNumber(value) ? `${value}px` : value }, fraction(value: any) { return !isNumber(value) || value > 1 ? value : `${value * 100}%` }, float(value: any, theme: Dict) { const map = { left: "right", right: "left" } return theme.direction === "rtl" ? map[value] : value }, degree(value: any) { if (isCssVar(value) || value == null) return value const unitless = isString(value) && !value.endsWith("deg") return isNumber(value) || unitless ? `${value}deg` : value }, gradient: gradientTransform, blur: wrap("blur"), opacity: wrap("opacity"), brightness: wrap("brightness"), contrast: wrap("contrast"), dropShadow: wrap("drop-shadow"), grayscale: wrap("grayscale"), hueRotate: wrap("hue-rotate"), invert: wrap("invert"), saturate: wrap("saturate"), sepia: wrap("sepia"), bgImage(value: any) { if (value == null) return value const prevent = isCSSFunction(value) || globalSet.has(value) return !prevent ? `url(${value})` : value }, outline(value: any) { const isNoneOrZero = String(value) === "0" || String(value) === "none" return value !== null && isNoneOrZero ? { outline: "2px solid transparent", outlineOffset: "2px" } : { outline: value } }, flexDirection(value: any) { const { space, divide } = flexDirectionTemplate[value] ?? {} const result = { flexDirection: value } if (space) result[space] = 1 if (divide) result[divide] = 1 return result }, }