import type { TokenCategory } from "../token-types.js"; const TOKEN_CATEGORY_PATTERNS: Array<{ pattern: RegExp; category: TokenCategory; }> = [ { pattern: /color|bg|background|border-color|fill|stroke/i, category: "color" }, { pattern: /spacing|margin|padding|gap|space|inset|(?:^|[-_])sp(?:[-_]|$)/i, category: "spacing", }, { pattern: /font|text|line-height|letter-spacing|typography/i, category: "typography" }, { pattern: /radius|rounded|corner/i, category: "radius" }, { pattern: /shadow|elevation/i, category: "shadow" }, { pattern: /size|width|height|min|max/i, category: "sizing" }, { pattern: /border(?!-color)|stroke-width|outline/i, category: "border" }, { pattern: /animation|transition|duration|timing|delay/i, category: "animation" }, { pattern: /z-index|layer|stack/i, category: "z-index" }, ]; const TOKEN_GROUP_PATTERNS: Array<{ pattern: RegExp; category: string }> = [ { pattern: /--(?:[\w]+-)?(?:font|line-height|letter-spacing|typography)-/, category: "typography", }, { pattern: /--(?:[\w]+-)?(?:sp|space|spacing|padding|gap|margin|inset)-/, category: "spacing" }, { pattern: /--(?:[\w]+-)?(?:radius|rounded|corner)-/, category: "radius" }, { pattern: /--(?:[\w]+-)?color-/, category: "colors" }, { pattern: /--(?:[\w]+-)?(?:bg|background)-/, category: "surfaces" }, { pattern: /--(?:[\w]+-)?text-/, category: "text" }, { pattern: /--(?:[\w]+-)?border/, category: "borders" }, { pattern: /--(?:[\w]+-)?(?:shadow|elevation)-/, category: "shadows" }, { pattern: /--(?:[\w]+-)?focus-/, category: "focus" }, { pattern: /--(?:[\w]+-)?(?:transition|animation|duration|timing|delay)-/, category: "transitions", }, { pattern: /--(?:[\w]+-)?scrollbar-/, category: "scrollbar" }, { pattern: /--(?:[\w]+-)?z-index/, category: "z-index" }, { pattern: /--(?:[\w]+-)?(?:button|input|touch)-/, category: "component-sizing" }, { pattern: /--(?:[\w]+-)?(?:appshell|header)-/, category: "layout" }, { pattern: /--(?:[\w]+-)?code-/, category: "code" }, { pattern: /--(?:[\w]+-)?tooltip-/, category: "tooltip" }, { pattern: /--(?:[\w]+-)?hero-/, category: "marketing" }, ]; export function inferTokenCategory(name: string, value?: string): TokenCategory { const valueCategory = value ? inferTokenCategoryFromValue(value) : null; if (valueCategory) return valueCategory; const lowerName = name.toLowerCase(); for (const { pattern, category } of TOKEN_CATEGORY_PATTERNS) { if (pattern.test(lowerName)) { return category; } } return "other"; } function inferTokenCategoryFromValue(value: string): TokenCategory | null { const normalized = value.trim().toLowerCase(); if ( /^#(?:[0-9a-f]{3,8})$/i.test(normalized) || /^(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color|color-mix)\(/.test(normalized) || normalized === "currentcolor" ) { return "color"; } return null; } export function inferTokenGroup(name: string): string { const lowerName = name.toLowerCase(); for (const { pattern, category } of TOKEN_GROUP_PATTERNS) { if (pattern.test(lowerName)) { return category; } } const category = inferTokenCategory(name); switch (category) { case "color": return "colors"; case "shadow": return "shadows"; case "border": return "borders"; case "animation": return "transitions"; default: return category; } } export function normalizeTokenGroupComment(comment: string): string { const text = comment .trim() .replace(/^\/\/\s*/, "") .replace(/^\/\*+\s*/, "") .replace(/\s*\*+\/$/, "") .trim() .toLowerCase(); const mappings: Record = { "base configuration": "base", typography: "typography", "spacing (micro)": "spacing", spacing: "spacing", "density padding": "spacing", "border radius": "radius", transitions: "transitions", colors: "colors", surfaces: "surfaces", text: "text", borders: "borders", shadows: "shadows", focus: "focus", scrollbar: "scrollbar", "component heights": "component-sizing", "appshell layout": "layout", codeblock: "code", tooltip: "tooltip", "hero/marketing gradient": "marketing", }; return mappings[text] ?? text.replace(/\s+/g, "-"); }