import { formatHsl } from "culori" import type StyleDictionary from "style-dictionary" import type { FormatFnArguments, TransformedToken } from "style-dictionary/types" import { isColor } from "../filters/isColor" import { getColorValue, getType } from "../helpers/get" import { transformCubicBezier } from "../transformers/cubic-bezier" import { transformGradient } from "../transformers/gradient" import { hexToOklchColor } from "../transformers/oklch" import { transformShadow } from "../transformers/shadow" import { transformTransition } from "../transformers/transition" const mapTransformedToken = (token: TransformedToken, _options: FormatFnArguments["options"]) => { const type = getType(token) switch (type) { case "shadow": return transformShadow(token.$value) case "gradient": return transformGradient(token.$value, token) case "cubic-bezier": return transformCubicBezier(token.$value) case "transition": return transformTransition(token.$value) default: return token.$value } } function addCustomVariants({ dictionary: _, options: __ }: FormatFnArguments) { return ` @variant dark { &:where(.dark, .dark *) { @slot; } @media (prefers-color-scheme: dark) { &:where(.system, .system *) { @slot; } } } ` } function addUtilities({ dictionary: _, options: __ }: FormatFnArguments) { return `@layer utilities { @tailwind utilities; html { color-scheme: light; } html[data-color-scheme="dark"] { color-scheme: dark; } html:where([data-scaling="0.9"]) { --scaling: 0.9; } html:where([data-scaling="0.95"]) { --scaling: 0.95; } html:where([data-scaling="1"]) { --scaling: 1; } html:where([data-scaling="1.05"]) { --scaling: 1.05; } html:where([data-scaling="1.1"]) { --scaling: 1.1; } :where(html) { --isLTR: 1; --isRTL: -1; &:dir(rtl) { --isLTR: -1; --isRTL: 1; } } .animate-accordion-down { animation: accordion-down 0.2s ease-out; } .animate-accordion-up { animation: accordion-up 0.2s ease-out; } } ` } function addKeyframes() { return ` @keyframes accordion-down { from { height: 0; } to { height: var(--radix-accordion-content-height); } } @keyframes accordion-up { from { height: var(--radix-accordion-content-height); } to { height: 0; } } ` } /** * Exports tailwind plugin for declaring root CSS vars * @see https://tailwindcss.com/docs/plugins#overview */ function cssVarsFormatter({ dictionary, options }: FormatFnArguments) { const vars = dictionary.allTokens .filter(token => !isColor(token)) .map(token => { const value = mapTransformedToken(token, options) return `--${token.name}: ${value}` }) .join(";\n\t\t") return `${vars};` } function cssThemeVarsColorFormatter({ dictionary, options: _ }: FormatFnArguments) { const vars = dictionary.allTokens .filter(token => isColor(token)) .map(token => { return `--color-${token.name}: var(--${token.name})` }) .join(";\n\t\t") return `${vars};` } function cssVarsColorHslFormatter({ dictionary, options }: FormatFnArguments) { const vars = dictionary.allTokens .filter(token => isColor(token)) .map(token => { const value = getColorValue(token, options) const hslColor = formatHsl(value) return `--${token.name}: ${hslColor}` }) .join(";\n\t\t") return `${vars};` } function cssVarsColorOklchFormatter({ dictionary, options, platform }: FormatFnArguments) { const vars = dictionary.allTokens .filter(token => isColor(token)) .map(token => { return `--${token.name}: oklch(${hexToOklchColor(token, platform, options)})` }) .join(";\n\t\t") return `${vars};` } export function registerTailwind(styleDictionary: StyleDictionary): StyleDictionary { styleDictionary.registerTransformGroup({ name: "tailwind", transforms: ["name/kebab"], }) styleDictionary.registerFormat({ name: "tailwind/css-theme-vars-color", format: cssThemeVarsColorFormatter, }) styleDictionary.registerFormat({ name: "tailwind/css-vars-color-hsl", format: cssVarsColorHslFormatter, }) styleDictionary.registerFormat({ name: "tailwind/css-vars-color-oklch", format: cssVarsColorOklchFormatter, }) styleDictionary.registerFormat({ name: "tailwind/css-vars", format: cssVarsFormatter, }) styleDictionary.registerFormat({ name: "tailwind/custom-variants", format: addCustomVariants, }) styleDictionary.registerFormat({ name: "tailwind/keyframes", format: addKeyframes, }) styleDictionary.registerFormat({ name: "tailwind/utilities", format: addUtilities, }) return styleDictionary }