import { oklch } from "culori" import type { Transform } from "style-dictionary/types" import { isShadow } from "../filters/isShadow" import { getValue } from "../helpers/get" import type { TokenUnit } from "../helpers/interfaces" type TokenShadow = { color: string offsetX: TokenUnit offsetY: TokenUnit blur: TokenUnit spread: TokenUnit inset: boolean } const formatShadow = ({ offsetX = { value: 0, unit: "px" }, offsetY = { value: 0, unit: "px" }, blur = { value: 0, unit: "px" }, spread = { value: 0, unit: "px" }, color, inset = false, }: TokenShadow): string => { const oklchColor = oklch(color) if (!oklchColor) { throw new Error("Invalid color value") } const l = Math.round(oklchColor.l * 1000) / 10 const c = Math.round(oklchColor.c * 10000) / 100 const h = Math.round((oklchColor?.h ?? 0) * 10) / 10 const result = `oklch(${l}% ${c} ${h} / ${oklchColor.alpha})` return `${offsetX.value}${offsetX.unit} ${offsetY.value}${offsetY.unit} ${blur.value}${blur.unit} ${spread.value}${spread.unit} ${result} ${inset ? "inset" : ""}`.trim() } export function transformShadow(tokenValue: TokenShadow): string { if (Array.isArray(tokenValue)) { const shadow = tokenValue.map(formatShadow).join(", ") return shadow } if (typeof tokenValue === "object") { const shadow = formatShadow(tokenValue) return shadow } return tokenValue } export const shadowCssTransform: Transform = { name: "shadow/css-shorthand-dtcg", type: "value", transitive: true, filter: isShadow, transform: (token, _, options) => { const tokenValue = getValue(token, options, { useOriginalValue: true }) return transformShadow(tokenValue) }, }