@tenphi/tasty 0.0.0-snapshot.b3fbcbb → 0.0.0-snapshot.bae20d4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/README.md +130 -7
  2. package/dist/chunks/cacheKey.js +16 -8
  3. package/dist/chunks/cacheKey.js.map +1 -1
  4. package/dist/chunks/definitions.js +1 -2
  5. package/dist/chunks/definitions.js.map +1 -1
  6. package/dist/chunks/renderChunk.js +31 -32
  7. package/dist/chunks/renderChunk.js.map +1 -1
  8. package/dist/config.d.ts +45 -10
  9. package/dist/config.js +75 -13
  10. package/dist/config.js.map +1 -1
  11. package/dist/core/index.d.ts +9 -8
  12. package/dist/core/index.js +7 -6
  13. package/dist/hooks/useGlobalStyles.d.ts +3 -0
  14. package/dist/hooks/useGlobalStyles.js +28 -1
  15. package/dist/hooks/useGlobalStyles.js.map +1 -1
  16. package/dist/hooks/useKeyframes.js +18 -3
  17. package/dist/hooks/useKeyframes.js.map +1 -1
  18. package/dist/hooks/useProperty.js +36 -13
  19. package/dist/hooks/useProperty.js.map +1 -1
  20. package/dist/hooks/useRawCSS.js +13 -1
  21. package/dist/hooks/useRawCSS.js.map +1 -1
  22. package/dist/hooks/useStyles.d.ts +5 -0
  23. package/dist/hooks/useStyles.js +87 -7
  24. package/dist/hooks/useStyles.js.map +1 -1
  25. package/dist/index.d.ts +9 -8
  26. package/dist/index.js +7 -6
  27. package/dist/injector/index.d.ts +9 -1
  28. package/dist/injector/index.js +9 -1
  29. package/dist/injector/index.js.map +1 -1
  30. package/dist/injector/injector.d.ts +9 -0
  31. package/dist/injector/injector.js +21 -17
  32. package/dist/injector/injector.js.map +1 -1
  33. package/dist/injector/sheet-manager.d.ts +1 -0
  34. package/dist/injector/sheet-manager.js +1 -0
  35. package/dist/injector/sheet-manager.js.map +1 -1
  36. package/dist/parser/classify.js +2 -1
  37. package/dist/parser/classify.js.map +1 -1
  38. package/dist/parser/parser.js +1 -1
  39. package/dist/pipeline/index.d.ts +1 -1
  40. package/dist/pipeline/index.js +24 -14
  41. package/dist/pipeline/index.js.map +1 -1
  42. package/dist/pipeline/materialize.js +380 -119
  43. package/dist/pipeline/materialize.js.map +1 -1
  44. package/dist/pipeline/parseStateKey.d.ts +1 -1
  45. package/dist/pipeline/parseStateKey.js +20 -11
  46. package/dist/pipeline/parseStateKey.js.map +1 -1
  47. package/dist/plugins/okhsl-plugin.js +2 -275
  48. package/dist/plugins/okhsl-plugin.js.map +1 -1
  49. package/dist/plugins/types.d.ts +9 -2
  50. package/dist/properties/index.js +14 -28
  51. package/dist/properties/index.js.map +1 -1
  52. package/dist/properties/property-type-resolver.js +12 -0
  53. package/dist/properties/property-type-resolver.js.map +1 -1
  54. package/dist/ssr/astro.d.ts +29 -0
  55. package/dist/ssr/astro.js +65 -0
  56. package/dist/ssr/astro.js.map +1 -0
  57. package/dist/ssr/async-storage.d.ts +17 -0
  58. package/dist/ssr/async-storage.js +35 -0
  59. package/dist/ssr/async-storage.js.map +1 -0
  60. package/dist/ssr/collect-auto-properties.js +40 -0
  61. package/dist/ssr/collect-auto-properties.js.map +1 -0
  62. package/dist/ssr/collector.d.ts +85 -0
  63. package/dist/ssr/collector.js +183 -0
  64. package/dist/ssr/collector.js.map +1 -0
  65. package/dist/ssr/context.d.ts +8 -0
  66. package/dist/ssr/context.js +14 -0
  67. package/dist/ssr/context.js.map +1 -0
  68. package/dist/ssr/format-global-rules.js +22 -0
  69. package/dist/ssr/format-global-rules.js.map +1 -0
  70. package/dist/ssr/format-keyframes.js +70 -0
  71. package/dist/ssr/format-keyframes.js.map +1 -0
  72. package/dist/ssr/format-property.js +50 -0
  73. package/dist/ssr/format-property.js.map +1 -0
  74. package/dist/ssr/format-rules.js +70 -0
  75. package/dist/ssr/format-rules.js.map +1 -0
  76. package/dist/ssr/hydrate.d.ts +22 -0
  77. package/dist/ssr/hydrate.js +50 -0
  78. package/dist/ssr/hydrate.js.map +1 -0
  79. package/dist/ssr/index.d.ts +5 -0
  80. package/dist/ssr/index.js +12 -0
  81. package/dist/ssr/index.js.map +1 -0
  82. package/dist/ssr/next.d.ts +45 -0
  83. package/dist/ssr/next.js +71 -0
  84. package/dist/ssr/next.js.map +1 -0
  85. package/dist/ssr/ssr-collector-ref.js +12 -0
  86. package/dist/ssr/ssr-collector-ref.js.map +1 -0
  87. package/dist/states/index.js +10 -257
  88. package/dist/states/index.js.map +1 -1
  89. package/dist/styles/color.js +9 -5
  90. package/dist/styles/color.js.map +1 -1
  91. package/dist/styles/createStyle.js +24 -21
  92. package/dist/styles/createStyle.js.map +1 -1
  93. package/dist/styles/index.js +1 -1
  94. package/dist/styles/predefined.d.ts +0 -2
  95. package/dist/styles/predefined.js +0 -3
  96. package/dist/styles/predefined.js.map +1 -1
  97. package/dist/styles/preset.js +1 -1
  98. package/dist/styles/preset.js.map +1 -1
  99. package/dist/styles/scrollbar.d.ts +9 -5
  100. package/dist/styles/scrollbar.js +25 -89
  101. package/dist/styles/scrollbar.js.map +1 -1
  102. package/dist/styles/transition.js +1 -1
  103. package/dist/styles/transition.js.map +1 -1
  104. package/dist/styles/types.d.ts +24 -14
  105. package/dist/tasty.d.ts +20 -21
  106. package/dist/tasty.js +24 -11
  107. package/dist/tasty.js.map +1 -1
  108. package/dist/types.d.ts +1 -1
  109. package/dist/utils/cache-wrapper.js +4 -8
  110. package/dist/utils/cache-wrapper.js.map +1 -1
  111. package/dist/utils/color-math.d.ts +45 -0
  112. package/dist/utils/color-math.js +749 -0
  113. package/dist/utils/color-math.js.map +1 -0
  114. package/dist/utils/color-space.d.ts +5 -0
  115. package/dist/utils/color-space.js +228 -0
  116. package/dist/utils/color-space.js.map +1 -0
  117. package/dist/utils/colors.js +3 -1
  118. package/dist/utils/colors.js.map +1 -1
  119. package/dist/utils/has-keys.js +13 -0
  120. package/dist/utils/has-keys.js.map +1 -0
  121. package/dist/utils/mod-attrs.js +1 -1
  122. package/dist/utils/process-tokens.d.ts +3 -13
  123. package/dist/utils/process-tokens.js +17 -97
  124. package/dist/utils/process-tokens.js.map +1 -1
  125. package/dist/utils/selector-transform.js +32 -0
  126. package/dist/utils/selector-transform.js.map +1 -0
  127. package/dist/utils/styles.d.ts +2 -79
  128. package/dist/utils/styles.js +26 -554
  129. package/dist/utils/styles.js.map +1 -1
  130. package/dist/utils/typography.d.ts +24 -13
  131. package/dist/utils/typography.js +6 -16
  132. package/dist/utils/typography.js.map +1 -1
  133. package/dist/zero/babel.d.ts +48 -6
  134. package/dist/zero/babel.js +63 -5
  135. package/dist/zero/babel.js.map +1 -1
  136. package/dist/zero/next.d.ts +44 -30
  137. package/dist/zero/next.js +102 -38
  138. package/dist/zero/next.js.map +1 -1
  139. package/docs/PIPELINE.md +519 -0
  140. package/docs/adoption.md +286 -0
  141. package/docs/comparison.md +413 -0
  142. package/docs/configuration.md +263 -0
  143. package/docs/debug.md +505 -0
  144. package/docs/design-system.md +401 -0
  145. package/docs/dsl.md +540 -0
  146. package/docs/getting-started.md +201 -0
  147. package/docs/injector.md +528 -0
  148. package/docs/methodology.md +501 -0
  149. package/docs/runtime.md +291 -0
  150. package/docs/ssr.md +382 -0
  151. package/docs/styles.md +574 -0
  152. package/docs/tasty-static.md +420 -0
  153. package/package.json +50 -30
  154. package/dist/styles/styledScrollbar.d.ts +0 -47
  155. package/dist/styles/styledScrollbar.js +0 -38
  156. package/dist/styles/styledScrollbar.js.map +0 -1
  157. package/dist/tokens/typography.d.ts +0 -19
  158. package/dist/tokens/typography.js +0 -237
  159. package/dist/tokens/typography.js.map +0 -1
  160. package/dist/utils/hsl-to-rgb.js +0 -38
  161. package/dist/utils/hsl-to-rgb.js.map +0 -1
  162. package/dist/utils/okhsl-to-rgb.js +0 -296
  163. package/dist/utils/okhsl-to-rgb.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","names":[],"sources":["../../src/utils/styles.ts"],"sourcesContent":["import { StyleParser } from '../parser/parser';\nimport { okhslFunc } from '../plugins/okhsl-plugin';\nimport { createStateParserContext, parseAdvancedState } from '../states';\nimport type { Styles } from '../styles/types';\n\nimport { cacheWrapper } from './cache-wrapper';\nimport { camelToKebab } from './case-converter';\nimport { hslToRgb } from './hsl-to-rgb';\nimport { okhslToRgb } from './okhsl-to-rgb';\n\nimport type { ProcessedStyle, StyleDetails } from '../parser/types';\nimport type {\n AtRuleContext,\n ParsedAdvancedState,\n StateParserContext,\n} from '../states';\n\nexport type StyleValue<T = string> = T | boolean | number | null | undefined;\n\n/**\n * Normalize a color token value.\n * - Boolean `true` is converted to `'transparent'`\n * - Boolean `false` returns `null` (signals the token should be skipped)\n * - Other values are returned as-is\n *\n * @param value - The raw token value\n * @returns Normalized value or null if the token should be skipped\n */\nexport function normalizeColorTokenValue<T>(\n value: T | boolean,\n): T | 'transparent' | null {\n if (value === true) {\n return 'transparent';\n }\n if (value === false) {\n return null;\n }\n return value as T;\n}\n\nexport type StyleValueStateMap<T = string> = Record<\n string,\n StyleValue<T> | '@inherit'\n>;\n\n/**\n * Combined type for style values that can be either a direct value or a state map.\n * Use this for component props that accept style values.\n */\nexport type StylePropValue<T = string> = StyleValue<T> | StyleValueStateMap<T>;\n\nexport type ComputeModel = string | number;\n\nexport type CSSMap = { $?: string | string[] } & Record<\n string,\n string | string[]\n>;\n\nexport type StyleHandlerResult = CSSMap | CSSMap[] | void;\n\nexport type RawStyleHandler = (value: StyleValueStateMap) => StyleHandlerResult;\n\nexport type StyleHandler = RawStyleHandler & {\n __lookupStyles: string[];\n};\n\n/**\n * Handler definition forms for configure() and plugins.\n * - Function only: lookup styles inferred from key name\n * - Single property tuple: ['styleName', handler]\n * - Multi-property tuple: [['style1', 'style2'], handler]\n */\nexport type StyleHandlerDefinition =\n | RawStyleHandler\n | [string, RawStyleHandler]\n | [string[], RawStyleHandler];\n\nexport interface StyleStateData {\n model?: ComputeModel;\n tokens?: string[];\n value: StyleValue | StyleValueStateMap | StyleStateData;\n /** The list of mods to apply */\n mods: string[];\n /** The list of **not** mods to apply (e.g. `:not(:hover)`) */\n notMods: string[];\n /** Advanced states (media queries, container queries, etc.) */\n advancedStates?: ParsedAdvancedState[];\n /** At-rule context for CSS generation */\n atRuleContext?: AtRuleContext;\n /** Own mods for sub-element states (from @own()) - applied to sub-element selector */\n ownMods?: string[];\n /** Negated own mods for sub-element states */\n negatedOwnMods?: string[];\n}\n\nexport interface ParsedColor {\n color?: string;\n name?: string;\n opacity?: number;\n}\n\nexport type StyleStateDataList = StyleStateData[];\n\nexport type StyleStateDataListMap = Record<string, StyleStateDataList>;\n\nexport type StyleMap = Record<string, StyleValue | StyleValueStateMap>;\n\nexport type StyleStateMap = Record<string, StyleStateData>;\n\nconst devMode = process.env.NODE_ENV !== 'production';\n\n// Precompiled regex patterns for parseColor optimization\n// Match var(--name-color...) and extract the name, regardless of fallbacks\nconst COLOR_VAR_PATTERN = /var\\(--([a-z0-9-]+)-color/;\nconst COLOR_VAR_RGB_PATTERN = /var\\(--([a-z0-9-]+)-color-rgb/;\nconst RGB_ALPHA_PATTERN = /\\/\\s*([0-9.]+)\\)/;\nconst SIMPLE_COLOR_PATTERNS = [\n /^#[0-9a-fA-F]{3,8}$/, // Hex colors: #fff, #ffffff, #ffff, #ffffffff\n /^rgb\\(/, // RGB/RGBA functions\n /^hsl\\(/, // HSL/HSLA functions\n /^lch\\(/, // LCH color functions\n /^oklch\\(/, // OKLCH color functions\n /^okhsl\\(/, // OKHSL color functions\n /^var\\(--[a-z0-9-]+-color/, // CSS custom properties for colors\n /^currentColor$/, // CSS currentColor keyword\n /^transparent$/, // CSS transparent keyword\n];\n\n// Rate limiting for dev warnings to avoid spam\nlet colorWarningCount = 0;\nconst MAX_COLOR_WARNINGS = 10;\n\nexport const CUSTOM_UNITS = {\n r: '6px',\n cr: '10px',\n bw: '1px',\n ow: '3px',\n x: '8px',\n fs: 'var(--font-size)',\n lh: 'var(--line-height)',\n sf: function sf(num: number) {\n return `minmax(0, ${num}fr)`;\n },\n};\n\nexport const DIRECTIONS = ['top', 'right', 'bottom', 'left'];\n\nconst MOD_NAME_CACHE = new Map();\n\nexport function getModSelector(modName: string): string {\n if (!MOD_NAME_CACHE.has(modName)) {\n let selector: string;\n\n // Check if it's a shorthand value mod: key=value, key^=value, key$=value, key*=value\n // Supports: key=value, key=\"value\", key='value', and with ^=, $=, *= operators\n const valueModMatch = modName.match(\n /^([a-z][a-z0-9-]*)(\\^=|\\$=|\\*=|=)(.+)$/i,\n );\n if (valueModMatch) {\n const key = valueModMatch[1];\n const operator = valueModMatch[2];\n let value = valueModMatch[3];\n\n // Remove quotes if present\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n\n // Convert to full attribute selector with the appropriate operator\n selector = `[data-${camelToKebab(key)}${operator}\"${value}\"]`;\n } else if (modName.match(/^[a-z]/)) {\n // Boolean mod: convert camelCase to kebab-case\n selector = `[data-${camelToKebab(modName)}]`;\n } else {\n // Check if it contains :has() with capitalized element names\n if (modName.includes(':has(')) {\n selector = modName.replace(/:has\\(([^)]+)\\)/g, (match, content) => {\n // Validate that combinators have spaces around them\n // Check for capitalized words adjacent to combinators without spaces\n const invalidPattern = /[A-Z][a-z]*[>+~]|[>+~][A-Z][a-z]*/;\n if (invalidPattern.test(content)) {\n console.error(\n `[Tasty] Invalid :has() selector syntax: \"${modName}\"\\n` +\n `Combinators (>, +, ~) must have spaces around them when used with element names.\\n` +\n `Example: Use \":has(Body > Row)\" instead of \":has(Body>Row)\"\\n` +\n `This is a design choice: the parser uses simple whitespace splitting for performance.`,\n );\n }\n\n // Transform capitalized words to [data-element=\"...\"] selectors\n const tokens = content.split(/\\s+/);\n const transformed = tokens.map((token: string) =>\n /^[A-Z]/.test(token) ? `[data-element=\"${token}\"]` : token,\n );\n return `:has(${transformed.join(' ')})`;\n });\n } else {\n // Pass through (e.g., :hover, .class, [attr])\n selector = modName;\n }\n }\n\n MOD_NAME_CACHE.set(modName, selector);\n }\n\n return MOD_NAME_CACHE.get(modName);\n}\n\n// Lazy-initialized to break the circular dependency:\n// parser.ts → classify.ts → utils/styles.ts → parser.ts\nlet __tastyParser: StyleParser | null = null;\n\nfunction getOrCreateParser(): StyleParser {\n if (!__tastyParser) {\n __tastyParser = new StyleParser({ units: CUSTOM_UNITS });\n __tastyParser.setFuncs(__tastyFuncs);\n }\n return __tastyParser;\n}\n\n// Registry for user-provided custom functions that the parser can call.\n// It is updated through the `customFunc` helper exported below.\n// okhsl is registered as a built-in function so it works regardless of\n// tree-shaking or module initialization order.\nconst __tastyFuncs: Record<string, (groups: StyleDetails[]) => string> = {\n okhsl: okhslFunc,\n};\n\nexport function customFunc(\n name: string,\n fn: (groups: StyleDetails[]) => string,\n) {\n __tastyFuncs[name] = fn;\n getOrCreateParser().setFuncs(__tastyFuncs);\n}\n\n/**\n * Get the global StyleParser instance.\n * Used by configure() to apply parser configuration.\n */\nexport function getGlobalParser(): StyleParser {\n return getOrCreateParser();\n}\n\n/**\n * Get the current custom functions registry.\n * Used by configure() to merge with new functions.\n */\nexport function getGlobalFuncs(): Record<\n string,\n (groups: StyleDetails[]) => string\n> {\n return __tastyFuncs;\n}\n\n// ============================================================================\n// Global Predefined Tokens\n// ============================================================================\n\n/**\n * Storage for predefined tokens that are replaced during style parsing.\n * Keys are token names (with $ or # prefix), values are pre-processed CSS values.\n */\nlet __globalPredefinedTokens: Record<string, string> | null = null;\n\n/**\n * Set global predefined tokens.\n * Called from configure() after processing token values.\n * Merges with existing tokens (new tokens override existing ones with same key).\n * Keys are normalized to lowercase (parser lowercases input before classification).\n * @internal\n */\nexport function setGlobalPredefinedTokens(\n tokens: Record<string, string>,\n): void {\n // Normalize keys to lowercase for case-insensitive matching\n const normalizedTokens: Record<string, string> = {};\n for (const [key, value] of Object.entries(tokens)) {\n const lowerKey = key.toLowerCase();\n const lowerValue = value.toLowerCase();\n\n // Warn if trying to use bare #current to define other color tokens\n // #current represents currentcolor which cannot be used as a base for recursive token resolution\n // Note: #current.5 (with opacity) is allowed since it resolves to a concrete color-mix value\n if (lowerKey.startsWith('#') && lowerValue === '#current') {\n console.warn(\n `Tasty: Using #current to define color token \"${key}\" is not supported. ` +\n `The #current token represents currentcolor which cannot be used as a base for other tokens.`,\n );\n continue; // Skip this token\n }\n\n normalizedTokens[lowerKey] = value;\n }\n // Merge with existing tokens (consistent with how states, units, funcs are handled)\n __globalPredefinedTokens = __globalPredefinedTokens\n ? { ...__globalPredefinedTokens, ...normalizedTokens }\n : normalizedTokens;\n // Clear parser cache since token values affect parsing\n getOrCreateParser().clearCache();\n}\n\n/**\n * Get the current global predefined tokens.\n * Returns null if no tokens are configured.\n */\nexport function getGlobalPredefinedTokens(): Record<string, string> | null {\n return __globalPredefinedTokens;\n}\n\n/**\n * Reset global predefined tokens.\n * Used for testing.\n * @internal\n */\nexport function resetGlobalPredefinedTokens(): void {\n __globalPredefinedTokens = null;\n // Clear parser cache since token availability affects parsing\n getOrCreateParser().clearCache();\n}\n\n/**\n *\n * @param {String} value\n * @param {Number} mode\n * @returns {Object<String,String|Array>}\n */\nexport function parseStyle(value: StyleValue): ProcessedStyle {\n let str: string;\n\n if (typeof value === 'string') {\n str = value;\n } else if (typeof value === 'number') {\n str = String(value);\n } else {\n // boolean, null, undefined, objects etc. → empty string\n str = '';\n }\n\n return getOrCreateParser().process(str);\n}\n\n/**\n * Parse color. Find it value, name and opacity.\n * Optimized to avoid heavy parseStyle calls for simple color patterns.\n */\nexport function parseColor(val: string, ignoreError = false): ParsedColor {\n // Early return for non-strings or empty values\n if (typeof val !== 'string') {\n val = String(val ?? '');\n }\n\n val = val.trim();\n if (!val) return {};\n\n // Fast path: Check if it's a simple color pattern that doesn't need full parsing\n const isSimpleColor = SIMPLE_COLOR_PATTERNS.some((pattern) =>\n pattern.test(val),\n );\n\n let firstColor: string;\n if (isSimpleColor) {\n // For simple colors, use the value directly without parsing\n firstColor = val;\n } else {\n const processed = parseStyle(val);\n const extractedColor = processed.groups.find((g) => g.colors.length)\n ?.colors[0];\n\n if (!extractedColor) {\n // Rate-limited warning to avoid spam\n if (!ignoreError && devMode && colorWarningCount < MAX_COLOR_WARNINGS) {\n console.warn('CubeUIKit: unable to parse color:', val);\n colorWarningCount++;\n if (colorWarningCount === MAX_COLOR_WARNINGS) {\n console.warn(\n 'CubeUIKit: color parsing warnings will be suppressed from now on',\n );\n }\n }\n return {};\n }\n\n firstColor = extractedColor;\n }\n\n // Extract color name (if present) from variable pattern using precompiled regex\n let nameMatch = firstColor.match(COLOR_VAR_PATTERN);\n if (!nameMatch) {\n nameMatch = firstColor.match(COLOR_VAR_RGB_PATTERN);\n }\n\n let opacity: number | undefined;\n if (\n firstColor.startsWith('rgb') ||\n firstColor.startsWith('hsl') ||\n firstColor.startsWith('lch') ||\n firstColor.startsWith('oklch') ||\n firstColor.startsWith('okhsl')\n ) {\n const alphaMatch = firstColor.match(RGB_ALPHA_PATTERN);\n if (alphaMatch) {\n const v = parseFloat(alphaMatch[1]);\n if (!isNaN(v)) opacity = v * 100;\n }\n }\n\n return {\n color: firstColor,\n name: nameMatch ? nameMatch[1] : undefined,\n opacity,\n };\n}\n\n/**\n * CSS named color keywords → hex values.\n * Lazy-initialized on first use to avoid up-front cost.\n */\nlet _namedColorHex: Map<string, string> | null = null;\n\nfunction getNamedColorHex(): Map<string, string> {\n if (_namedColorHex) return _namedColorHex;\n _namedColorHex = new Map([\n ['aliceblue', '#f0f8ff'],\n ['antiquewhite', '#faebd7'],\n ['aqua', '#00ffff'],\n ['aquamarine', '#7fffd4'],\n ['azure', '#f0ffff'],\n ['beige', '#f5f5dc'],\n ['bisque', '#ffe4c4'],\n ['black', '#000000'],\n ['blanchedalmond', '#ffebcd'],\n ['blue', '#0000ff'],\n ['blueviolet', '#8a2be2'],\n ['brown', '#a52a2a'],\n ['burlywood', '#deb887'],\n ['cadetblue', '#5f9ea0'],\n ['chartreuse', '#7fff00'],\n ['chocolate', '#d2691e'],\n ['coral', '#ff7f50'],\n ['cornflowerblue', '#6495ed'],\n ['cornsilk', '#fff8dc'],\n ['crimson', '#dc143c'],\n ['cyan', '#00ffff'],\n ['darkblue', '#00008b'],\n ['darkcyan', '#008b8b'],\n ['darkgoldenrod', '#b8860b'],\n ['darkgray', '#a9a9a9'],\n ['darkgreen', '#006400'],\n ['darkgrey', '#a9a9a9'],\n ['darkkhaki', '#bdb76b'],\n ['darkmagenta', '#8b008b'],\n ['darkolivegreen', '#556b2f'],\n ['darkorange', '#ff8c00'],\n ['darkorchid', '#9932cc'],\n ['darkred', '#8b0000'],\n ['darksalmon', '#e9967a'],\n ['darkseagreen', '#8fbc8f'],\n ['darkslateblue', '#483d8b'],\n ['darkslategray', '#2f4f4f'],\n ['darkslategrey', '#2f4f4f'],\n ['darkturquoise', '#00ced1'],\n ['darkviolet', '#9400d3'],\n ['deeppink', '#ff1493'],\n ['deepskyblue', '#00bfff'],\n ['dimgray', '#696969'],\n ['dimgrey', '#696969'],\n ['dodgerblue', '#1e90ff'],\n ['firebrick', '#b22222'],\n ['floralwhite', '#fffaf0'],\n ['forestgreen', '#228b22'],\n ['fuchsia', '#ff00ff'],\n ['gainsboro', '#dcdcdc'],\n ['ghostwhite', '#f8f8ff'],\n ['gold', '#ffd700'],\n ['goldenrod', '#daa520'],\n ['gray', '#808080'],\n ['green', '#008000'],\n ['greenyellow', '#adff2f'],\n ['grey', '#808080'],\n ['honeydew', '#f0fff0'],\n ['hotpink', '#ff69b4'],\n ['indianred', '#cd5c5c'],\n ['indigo', '#4b0082'],\n ['ivory', '#fffff0'],\n ['khaki', '#f0e68c'],\n ['lavender', '#e6e6fa'],\n ['lavenderblush', '#fff0f5'],\n ['lawngreen', '#7cfc00'],\n ['lemonchiffon', '#fffacd'],\n ['lightblue', '#add8e6'],\n ['lightcoral', '#f08080'],\n ['lightcyan', '#e0ffff'],\n ['lightgoldenrodyellow', '#fafad2'],\n ['lightgray', '#d3d3d3'],\n ['lightgreen', '#90ee90'],\n ['lightgrey', '#d3d3d3'],\n ['lightpink', '#ffb6c1'],\n ['lightsalmon', '#ffa07a'],\n ['lightseagreen', '#20b2aa'],\n ['lightskyblue', '#87cefa'],\n ['lightslategray', '#778899'],\n ['lightslategrey', '#778899'],\n ['lightsteelblue', '#b0c4de'],\n ['lightyellow', '#ffffe0'],\n ['lime', '#00ff00'],\n ['limegreen', '#32cd32'],\n ['linen', '#faf0e6'],\n ['magenta', '#ff00ff'],\n ['maroon', '#800000'],\n ['mediumaquamarine', '#66cdaa'],\n ['mediumblue', '#0000cd'],\n ['mediumorchid', '#ba55d3'],\n ['mediumpurple', '#9370db'],\n ['mediumseagreen', '#3cb371'],\n ['mediumslateblue', '#7b68ee'],\n ['mediumspringgreen', '#00fa9a'],\n ['mediumturquoise', '#48d1cc'],\n ['mediumvioletred', '#c71585'],\n ['midnightblue', '#191970'],\n ['mintcream', '#f5fffa'],\n ['mistyrose', '#ffe4e1'],\n ['moccasin', '#ffe4b5'],\n ['navajowhite', '#ffdead'],\n ['navy', '#000080'],\n ['oldlace', '#fdf5e6'],\n ['olive', '#808000'],\n ['olivedrab', '#6b8e23'],\n ['orange', '#ffa500'],\n ['orangered', '#ff4500'],\n ['orchid', '#da70d6'],\n ['palegoldenrod', '#eee8aa'],\n ['palegreen', '#98fb98'],\n ['paleturquoise', '#afeeee'],\n ['palevioletred', '#db7093'],\n ['papayawhip', '#ffefd5'],\n ['peachpuff', '#ffdab9'],\n ['peru', '#cd853f'],\n ['pink', '#ffc0cb'],\n ['plum', '#dda0dd'],\n ['powderblue', '#b0e0e6'],\n ['purple', '#800080'],\n ['rebeccapurple', '#663399'],\n ['red', '#ff0000'],\n ['rosybrown', '#bc8f8f'],\n ['royalblue', '#4169e1'],\n ['saddlebrown', '#8b4513'],\n ['salmon', '#fa8072'],\n ['sandybrown', '#f4a460'],\n ['seagreen', '#2e8b57'],\n ['seashell', '#fff5ee'],\n ['sienna', '#a0522d'],\n ['silver', '#c0c0c0'],\n ['skyblue', '#87ceeb'],\n ['slateblue', '#6a5acd'],\n ['slategray', '#708090'],\n ['slategrey', '#708090'],\n ['snow', '#fffafa'],\n ['springgreen', '#00ff7f'],\n ['steelblue', '#4682b4'],\n ['tan', '#d2b48c'],\n ['teal', '#008080'],\n ['thistle', '#d8bfd8'],\n ['tomato', '#ff6347'],\n ['turquoise', '#40e0d0'],\n ['violet', '#ee82ee'],\n ['wheat', '#f5deb3'],\n ['white', '#ffffff'],\n ['whitesmoke', '#f5f5f5'],\n ['yellow', '#ffff00'],\n ['yellowgreen', '#9acd32'],\n ]);\n return _namedColorHex;\n}\n\nexport function strToRgb(\n color: string,\n _ignoreAlpha = false,\n): string | null | undefined {\n if (!color) return undefined;\n\n if (color.startsWith('rgb')) return color;\n\n if (color.startsWith('#')) return hexToRgb(color);\n\n if (color.startsWith('okhsl(')) return okhslToRgb(color);\n\n if (color.startsWith('hsl')) return hslToRgb(color);\n\n // Named CSS colors\n const namedHex = getNamedColorHex().get(color.toLowerCase());\n if (namedHex) return hexToRgb(namedHex);\n\n return null;\n}\n\n/**\n * Extract RGB values from an rgb()/rgba() string.\n * Supports all modern CSS syntax variations:\n * - Comma-separated: rgb(255, 128, 0)\n * - Space-separated: rgb(255 128 0)\n * - Fractional: rgb(128.5, 64.3, 32.1)\n * - Percentages: rgb(50%, 25%, 75%)\n * - Slash alpha notation: rgb(255 128 0 / 0.5)\n *\n * Returns array of RGB values (0-255 range), converting percentages as needed.\n */\nexport function getRgbValuesFromRgbaString(str: string): number[] {\n // Extract content inside rgb()/rgba()\n const match = str.match(/rgba?\\(([^)]+)\\)/i);\n if (!match) return [];\n\n const inner = match[1].trim();\n // Split by slash first (for alpha), then handle color components\n const [colorPart] = inner.split('/');\n // Split by comma or whitespace\n const parts = colorPart\n .trim()\n .split(/[,\\s]+/)\n .filter(Boolean);\n\n return parts.slice(0, 3).map((part) => {\n part = part.trim();\n if (part.endsWith('%')) {\n // Convert percentage to 0-255 range\n return (parseFloat(part) / 100) * 255;\n }\n return parseFloat(part);\n });\n}\n\nexport function hexToRgb(hex: string): string | null {\n const matched = hex\n .replace(\n /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i,\n (_m: string, r: string, g: string, b: string) =>\n '#' + r + r + g + g + b + b,\n )\n .substring(1)\n .match(/.{2}/g);\n\n if (!matched) return null;\n\n const rgba = matched.map(\n (x: string, i: number) => parseInt(x, 16) * (i === 3 ? 1 / 255 : 1),\n );\n\n if (rgba.some((v) => Number.isNaN(v))) {\n return null;\n }\n\n if (rgba.length >= 3) {\n return `rgb(${rgba.slice(0, 3).join(' ')}${rgba.length > 3 ? ` / ${rgba[3]}` : ''})`;\n }\n\n return null;\n}\n\nexport function filterMods(mods: string[], allowedMods: string[]): string[] {\n return mods.filter((mod) => allowedMods.includes(mod));\n}\n\nexport function extendStyles(\n defaultStyles?: Record<string, unknown> | null,\n newStyles?: Record<string, unknown> | null,\n): Record<string, unknown> {\n let styles: Record<string, unknown> = {};\n\n if (!defaultStyles) {\n if (!newStyles) {\n return styles;\n }\n } else {\n styles = Object.assign({}, defaultStyles);\n }\n\n if (newStyles) {\n Object.keys(newStyles).forEach((key) => {\n if (newStyles[key] != null) {\n styles[key] = newStyles[key];\n }\n });\n }\n\n return styles;\n}\n\n/**\n * Split properties into style and non-style properties.\n * @param props - Component prop map.\n * @param [styleList] - List of all style properties.\n * @param [defaultStyles] - Default style map of the component.\n * @param [propMap] - Props to style alias map.\n * @param [ignoreList] - A list of properties to ignore.\n */\nexport function extractStyles(\n props: Record<string, unknown>,\n styleList: readonly string[] = [],\n defaultStyles?: Styles,\n propMap?: Record<string, string>,\n ignoreList: readonly string[] = [],\n): Styles {\n const styles: Styles = {\n ...defaultStyles,\n ...(ignoreList.includes('styles')\n ? undefined\n : props.styles && typeof props.styles === 'object'\n ? (props.styles as Styles)\n : undefined),\n };\n\n Object.keys(props).forEach((prop) => {\n const propName = propMap ? propMap[prop] || prop : prop;\n const value = props[prop];\n\n if (ignoreList && ignoreList.includes(prop)) {\n // do nothing\n } else if (styleList.includes(propName)) {\n styles[propName] = value as Styles[keyof Styles];\n }\n }, {});\n\n return styles;\n}\n\n// Enhanced regex that includes advanced state patterns\n// Matches: operators, parentheses, @media(...), @(...), @root(...), @own(...), @starting, @predefined,\n// value mods, boolean mods, pseudo-classes, classes, attribute selectors\nconst STATES_REGEXP =\n /([&|!^])|([()])|(@media:[a-z]+)|(@media\\([^)]+\\))|(@root\\([^)]+\\))|(@own\\([^)]+\\))|(@\\([^)]+\\))|(@starting)|(@[A-Za-z][A-Za-z0-9-]*)|([a-z][a-z0-9-]+=(?:\"[^\"]*\"|'[^']*'|[^\\s&|!^()]+))|([a-z][a-z0-9-]+)|(:[a-z][a-z0-9-]+\\([^)]+\\)|:[a-z][a-z0-9-]+)|(\\.[a-z][a-z0-9-]+)|(\\[[^\\]]+])/gi;\n\n/**\n * Check if a token is an advanced state (starts with @)\n */\nexport function isAdvancedStateToken(token: string): boolean {\n return token.startsWith('@') || token.startsWith('!@');\n}\nexport const STATE_OPERATORS = {\n NOT: '!',\n AND: '&',\n OR: '|',\n XOR: '^',\n};\n\nexport const STATE_OPERATOR_LIST = ['!', '&', '|', '^'];\n\n/**\n * Convert state notation tokens to a compute model (string, or nested [op, lhs, rhs]).\n */\nfunction convertTokensToComputeUnits(tokens: unknown[]): unknown {\n if (tokens.length === 1) {\n return tokens[0];\n }\n\n const hasLength = (x: unknown): x is string | unknown[] =>\n typeof x === 'string' || Array.isArray(x);\n\n STATE_OPERATOR_LIST.forEach((operator) => {\n let i;\n\n while ((i = tokens.indexOf(operator)) !== -1) {\n const token = tokens[i];\n\n if (token === '!') {\n const next = tokens[i + 1];\n if (next !== undefined && hasLength(next) && next.length !== 1) {\n tokens.splice(i, 2, ['!', next]);\n } else {\n tokens.splice(i, 1);\n }\n } else {\n const prev = tokens[i - 1];\n const next = tokens[i + 1];\n if (\n prev !== undefined &&\n next !== undefined &&\n hasLength(prev) &&\n hasLength(next) &&\n prev.length !== 1 &&\n next.length !== 1\n ) {\n tokens.splice(i - 1, 3, [token, prev, next]);\n } else {\n tokens.splice(i, 1);\n }\n }\n }\n });\n\n return tokens.length === 1 ? tokens[0] : tokens;\n}\n\n/**\n * Replace commas with | only outside of parentheses.\n * This preserves commas in advanced states like @(card, w < 600px)\n */\nfunction replaceCommasOutsideParens(str: string): string {\n let result = '';\n let depth = 0;\n\n for (const char of str) {\n if (char === '(') {\n depth++;\n result += char;\n } else if (char === ')') {\n depth--;\n result += char;\n } else if (char === ',' && depth === 0) {\n // Only replace commas at the top level (outside parentheses)\n result += '|';\n } else {\n result += char;\n }\n }\n\n return result;\n}\n\n/**\n * Parse state notation and return tokens, modifiers and compute model.\n */\nfunction parseStateNotationInner(\n notation: string,\n value: StyleValue | StyleValueStateMap | StyleStateData,\n): StyleStateData {\n const tokens = replaceCommasOutsideParens(notation).match(STATES_REGEXP);\n\n if (!tokens || !tokens.length) {\n return {\n model: undefined,\n mods: [],\n notMods: [],\n tokens: [],\n value,\n };\n } else if (tokens.length === 1) {\n return {\n model: tokens[0],\n mods: tokens.slice(0),\n notMods: [],\n tokens,\n value,\n };\n }\n\n const mods: string[] = [];\n\n const operations: unknown[][] = [[]];\n let list = operations[0];\n let position = 0;\n let operation: unknown[];\n\n tokens.forEach((token) => {\n switch (token) {\n case '(':\n operation = [];\n position++;\n list = operations[position] = operation;\n break;\n case ')':\n position--;\n operations[position].push(\n convertTokensToComputeUnits(list as unknown[]),\n );\n list = operations[position];\n break;\n default:\n if (token.length > 1) {\n if (!mods.includes(token)) {\n mods.push(token);\n }\n }\n list.push(token);\n }\n });\n\n while (position) {\n position--;\n operations[position].push(convertTokensToComputeUnits(list as unknown[]));\n list = operations[position];\n }\n\n return {\n tokens,\n mods,\n notMods: [],\n model: convertTokensToComputeUnits(operations[0] as unknown[]) as\n | ComputeModel\n | undefined,\n value,\n };\n}\n\nexport const parseStateNotation = cacheWrapper(parseStateNotationInner);\n\n/**\n * Build an AtRuleContext from parsed advanced states\n */\nexport function buildAtRuleContext(\n advancedStates: ParsedAdvancedState[],\n negatedStates: Set<string>,\n): AtRuleContext | undefined {\n if (advancedStates.length === 0) return undefined;\n\n const ctx: AtRuleContext = {};\n\n for (const state of advancedStates) {\n const isNegated = negatedStates.has(state.raw);\n\n switch (state.type) {\n case 'media': {\n if (!ctx.media) ctx.media = [];\n let mediaCondition = '';\n\n if (state.mediaType) {\n // @media:print, @media:screen, etc.\n mediaCondition = state.mediaType;\n } else if (state.condition) {\n // @media(width < 920px)\n mediaCondition = `(${state.condition})`;\n }\n\n if (mediaCondition) {\n if (isNegated) {\n ctx.media.push(`not ${mediaCondition}`);\n } else {\n ctx.media.push(mediaCondition);\n }\n }\n break;\n }\n\n case 'container': {\n if (!ctx.container) ctx.container = [];\n let condition = state.condition;\n if (isNegated) {\n condition = `not (${condition})`;\n }\n ctx.container.push({\n name: state.containerName,\n condition,\n });\n break;\n }\n\n case 'root': {\n if (!ctx.rootStates) ctx.rootStates = [];\n // Parse the condition to generate the proper selector\n const rootSelector = buildRootSelector(state.condition, isNegated);\n ctx.rootStates.push(rootSelector);\n break;\n }\n\n case 'starting': {\n if (!isNegated) {\n ctx.startingStyle = true;\n }\n break;\n }\n\n // 'own' and 'predefined' are handled differently (selector-based, not at-rule)\n // 'modifier' is a regular state\n }\n }\n\n // Return undefined if no at-rules were added\n if (\n !ctx.media?.length &&\n !ctx.container?.length &&\n !ctx.rootStates?.length &&\n !ctx.startingStyle\n ) {\n return undefined;\n }\n\n return ctx;\n}\n\n/**\n * Build a root state selector from a condition\n */\nfunction buildRootSelector(condition: string, isNegated: boolean): string {\n // Handle different condition formats:\n // - theme=dark -> [data-theme=\"dark\"]\n // - .className -> .className\n // - [attr] -> [attr]\n // - booleanMod -> [data-boolean-mod]\n\n let selector: string;\n\n if (condition.startsWith('.')) {\n // Class selector\n selector = condition;\n } else if (condition.startsWith('[')) {\n // Attribute selector\n selector = condition;\n } else if (condition.includes('=')) {\n // Value mod: theme=dark -> [data-theme=\"dark\"]\n const [key, value] = condition.split('=');\n selector = `[data-${camelToKebab(key.trim())}=\"${value.trim()}\"]`;\n } else {\n // Boolean mod: camelCase -> [data-camel-case]\n selector = `[data-${camelToKebab(condition)}]`;\n }\n\n if (isNegated) {\n return `:not(${selector})`;\n }\n return selector;\n}\n\n/**\n * Parse state notation and return tokens, modifiers and compute model.\n * Enhanced to detect and extract advanced states.\n */\nexport function styleStateMapToStyleStateDataList(\n styleStateMap: StyleStateMap | StyleValue | StyleValueStateMap,\n parserContext?: StateParserContext,\n): { states: StyleStateDataList; mods: string[]; hasAdvancedStates: boolean } {\n if (typeof styleStateMap !== 'object' || !styleStateMap) {\n return {\n states: [\n {\n model: undefined,\n mods: [],\n notMods: [],\n value: styleStateMap,\n },\n ],\n mods: [],\n hasAdvancedStates: false,\n };\n }\n\n const stateDataList: StyleStateDataList = [];\n let hasAdvancedStates = false;\n\n Object.keys(styleStateMap).forEach((stateNotation) => {\n const state = parseStateNotation(\n stateNotation,\n styleStateMap[stateNotation],\n );\n\n // Check if this state contains any advanced states\n const advancedStates: ParsedAdvancedState[] = [];\n const negatedAdvancedStates = new Set<string>();\n const regularMods: string[] = [];\n const ownMods: string[] = [];\n const negatedOwnMods: string[] = [];\n\n // Scan tokens for advanced states\n if (state.tokens) {\n let isNegated = false;\n for (const token of state.tokens) {\n if (token === '!') {\n isNegated = true;\n continue;\n }\n\n if (isAdvancedStateToken(token)) {\n hasAdvancedStates = true;\n const ctx = parserContext || createStateParserContext(undefined);\n const parsed = parseAdvancedState(token, ctx);\n advancedStates.push(parsed);\n\n // Handle @own states specially - extract condition as ownMod\n if (parsed.type === 'own' && parsed.condition) {\n if (isNegated) {\n negatedOwnMods.push(parsed.condition);\n } else {\n ownMods.push(parsed.condition);\n }\n } else if (isNegated) {\n negatedAdvancedStates.add(token);\n }\n isNegated = false;\n } else if (\n token.length > 1 &&\n !['&', '|', '^', '(', ')'].includes(token)\n ) {\n regularMods.push(token);\n isNegated = false;\n } else {\n isNegated = false;\n }\n }\n }\n\n // If there are advanced states, build the atRuleContext\n if (advancedStates.length > 0) {\n state.advancedStates = advancedStates;\n state.atRuleContext = buildAtRuleContext(\n advancedStates,\n negatedAdvancedStates,\n );\n // Filter mods to only include regular mods (not advanced states)\n state.mods = regularMods;\n }\n\n // Store own mods for sub-element selector generation\n if (ownMods.length > 0) {\n state.ownMods = ownMods;\n }\n if (negatedOwnMods.length > 0) {\n state.negatedOwnMods = negatedOwnMods;\n }\n\n stateDataList.push(state);\n });\n\n stateDataList.reverse();\n\n let initialState;\n\n const allMods: string[] = stateDataList.reduce((all: string[], state) => {\n if (!state.mods.length && !state.advancedStates?.length) {\n initialState = state;\n } else {\n state.mods.forEach((mod) => {\n if (!all.includes(mod)) {\n all.push(mod);\n }\n });\n }\n\n return all;\n }, []);\n\n if (!initialState) {\n stateDataList.push({\n mods: [],\n notMods: allMods,\n value: true,\n });\n }\n\n return { states: stateDataList, mods: allMods, hasAdvancedStates };\n}\n\nexport const COMPUTE_FUNC_MAP: Record<\n string,\n (a: unknown, b?: unknown) => unknown\n> = {\n '!': (a: unknown) => !a,\n '^': (a: unknown, b?: unknown) => (a && !b) || (!a && b),\n '|': (a: unknown, b?: unknown) => a || b,\n '&': (a: unknown, b?: unknown) => a && b,\n};\n\n/**\n * Compute a result based on a model and incoming map.\n */\nexport function computeState(\n computeModel: ComputeModel,\n valueMap:\n | (number | boolean)[]\n | Record<string, boolean>\n | ((...args: unknown[]) => unknown),\n) {\n if (!computeModel) return true;\n\n const map = valueMap as Record<string | number, unknown>;\n\n if (!Array.isArray(computeModel)) {\n if (typeof valueMap === 'function') {\n return !!valueMap(computeModel);\n } else {\n return !!map[computeModel];\n }\n }\n\n const func = COMPUTE_FUNC_MAP[computeModel[0]];\n\n if (!func) {\n console.warn(\n 'CubeUIKit: unexpected compute method in the model',\n computeModel,\n );\n // return false;\n }\n\n let a: unknown = computeModel[1];\n\n if (typeof a === 'object') {\n a = !!computeState(a as unknown as ComputeModel, valueMap);\n } else if (typeof valueMap === 'function') {\n a = !!valueMap(a);\n } else {\n a = !!map[a as string | number];\n }\n\n if (computeModel.length === 2) {\n return func(a);\n }\n\n let b: unknown = computeModel[2];\n\n if (typeof b === 'object') {\n b = !!computeState(b as unknown as ComputeModel, valueMap);\n } else if (typeof valueMap === 'function') {\n b = !!valueMap(b);\n } else {\n b = !!map[b as string | number];\n }\n\n return !!func(a, b);\n}\n\nconst _innerCache = new WeakMap();\n\nexport function stringifyStyles(styles: unknown): string {\n if (styles == null || typeof styles !== 'object') return '';\n const obj = styles as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const v = obj[k];\n if (v === undefined || typeof v === 'function' || typeof v === 'symbol')\n continue;\n\n const c0 = k.charCodeAt(0);\n const needsInnerSort =\n ((c0 >= 65 && c0 <= 90) || c0 === 38) &&\n v &&\n typeof v === 'object' &&\n !Array.isArray(v);\n\n let sv: string;\n if (needsInnerSort) {\n sv = _innerCache.get(v);\n if (sv === undefined) {\n const innerObj = v as Record<string, unknown>;\n const innerKeys = Object.keys(innerObj).sort();\n const innerParts: string[] = [];\n for (const ik of innerKeys) {\n const ivs = JSON.stringify(innerObj[ik]);\n if (ivs !== undefined)\n innerParts.push(JSON.stringify(ik) + ':' + ivs);\n }\n sv = '{' + innerParts.join(',') + '}';\n _innerCache.set(v, sv);\n }\n } else {\n sv = JSON.stringify(v);\n }\n parts.push(JSON.stringify(k) + ':' + sv);\n }\n return '{' + parts.join(',') + '}';\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"styles.js","names":[],"sources":["../../src/utils/styles.ts"],"sourcesContent":["import { StyleParser } from '../parser/parser';\nimport { okhslFunc } from '../plugins/okhsl-plugin';\n\nimport type { ProcessedStyle, StyleDetails } from '../parser/types';\n\nexport { getRgbValuesFromRgbaString, hexToRgb, strToRgb } from './color-math';\n\nexport type StyleValue<T = string> = T | boolean | number | null | undefined;\n\n/**\n * Normalize a color token value.\n * - Boolean `true` is converted to `'transparent'`\n * - Boolean `false` returns `null` (signals the token should be skipped)\n * - Other values are returned as-is\n *\n * @param value - The raw token value\n * @returns Normalized value or null if the token should be skipped\n */\nexport function normalizeColorTokenValue<T>(\n value: T | boolean,\n): T | 'transparent' | null {\n if (value === true) {\n return 'transparent';\n }\n if (value === false) {\n return null;\n }\n return value as T;\n}\n\nexport type StyleValueStateMap<T = string> = Record<\n string,\n StyleValue<T> | '@inherit'\n>;\n\n/**\n * Combined type for style values that can be either a direct value or a state map.\n * Use this for component props that accept style values.\n */\nexport type StylePropValue<T = string> = StyleValue<T> | StyleValueStateMap<T>;\n\nexport type CSSMap = { $?: string | string[] } & Record<\n string,\n string | string[]\n>;\n\nexport type StyleHandlerResult = CSSMap | CSSMap[] | void;\n\nexport type RawStyleHandler = (value: StyleValueStateMap) => StyleHandlerResult;\n\nexport type StyleHandler = RawStyleHandler & {\n __lookupStyles: string[];\n};\n\n/**\n * Handler definition forms for configure() and plugins.\n * - Function only: lookup styles inferred from key name\n * - Single property tuple: ['styleName', handler]\n * - Multi-property tuple: [['style1', 'style2'], handler]\n */\nexport type StyleHandlerDefinition =\n | RawStyleHandler\n | [string, RawStyleHandler]\n | [string[], RawStyleHandler];\n\nexport interface ParsedColor {\n color?: string;\n name?: string;\n opacity?: number;\n}\n\nexport type StyleMap = Record<string, StyleValue | StyleValueStateMap>;\n\nconst devMode = process.env.NODE_ENV !== 'production';\n\n// Precompiled regex patterns for parseColor optimization\n// Match var(--name-color...) and extract the name, regardless of fallbacks\nconst COLOR_VAR_PATTERN = /var\\(--([a-z0-9-]+)-color/;\nconst COLOR_VAR_COMPONENTS_PATTERN =\n /var\\(--([a-z0-9-]+)-color-(?:rgb|hsl|oklch)/;\nconst RGB_ALPHA_PATTERN = /\\/\\s*([0-9.]+)\\)/;\nconst RE_HEX_COLOR = /^#[0-9a-fA-F]{3,8}$/;\nconst RE_VAR_COLOR = /^var\\(--[a-z0-9-]+-color/;\n\nfunction isSimpleColorFast(val: string): boolean {\n const c0 = val.charCodeAt(0);\n\n switch (c0) {\n case 35: // '#'\n return RE_HEX_COLOR.test(val);\n case 114: // 'r'\n return val.charCodeAt(1) === 103 && val.charCodeAt(2) === 98; // 'rgb'\n case 104: // 'h'\n return val.charCodeAt(1) === 115 && val.charCodeAt(2) === 108; // 'hsl'\n case 108: // 'l'\n return val.charCodeAt(1) === 99 && val.charCodeAt(2) === 104; // 'lch'\n case 111: // 'o'\n return val.startsWith('oklch(') || val.startsWith('okhsl(');\n case 118: // 'v'\n return RE_VAR_COLOR.test(val);\n case 99: // 'c'\n return val === 'currentColor' || val === 'currentcolor';\n case 116: // 't'\n return val === 'transparent';\n default:\n return false;\n }\n}\n\n// Rate limiting for dev warnings to avoid spam\nlet colorWarningCount = 0;\nconst MAX_COLOR_WARNINGS = 10;\n\nexport const CUSTOM_UNITS = {\n r: '6px',\n cr: '10px',\n bw: '1px',\n ow: '3px',\n x: '8px',\n fs: 'var(--font-size)',\n lh: 'var(--line-height)',\n sf: function sf(num: number) {\n return `minmax(0, ${num}fr)`;\n },\n};\n\nexport const DIRECTIONS = ['top', 'right', 'bottom', 'left'];\n\n// Lazy-initialized to break the circular dependency:\n// parser.ts → classify.ts → utils/styles.ts → parser.ts\nlet __tastyParser: StyleParser | null = null;\n\nfunction getOrCreateParser(): StyleParser {\n if (!__tastyParser) {\n __tastyParser = new StyleParser({ units: CUSTOM_UNITS });\n __tastyParser.setFuncs(__tastyFuncs);\n }\n return __tastyParser;\n}\n\n// Registry for user-provided custom functions that the parser can call.\n// It is updated through the `customFunc` helper exported below.\n// okhsl is registered as a built-in function so it works regardless of\n// tree-shaking or module initialization order.\nconst __tastyFuncs: Record<string, (groups: StyleDetails[]) => string> = {\n okhsl: okhslFunc,\n};\n\nexport function customFunc(\n name: string,\n fn: (groups: StyleDetails[]) => string,\n) {\n __tastyFuncs[name] = fn;\n getOrCreateParser().setFuncs(__tastyFuncs);\n}\n\n/**\n * Get the global StyleParser instance.\n * Used by configure() to apply parser configuration.\n */\nexport function getGlobalParser(): StyleParser {\n return getOrCreateParser();\n}\n\n/**\n * Get the current custom functions registry.\n * Used by configure() to merge with new functions.\n */\nexport function getGlobalFuncs(): Record<\n string,\n (groups: StyleDetails[]) => string\n> {\n return __tastyFuncs;\n}\n\n// ============================================================================\n// Global Predefined Tokens\n// ============================================================================\n\n/**\n * Storage for predefined tokens that are replaced during style parsing.\n * Keys are token names (with $ or # prefix), values are pre-processed CSS values.\n */\nlet __globalPredefinedTokens: Record<string, string> | null = null;\n\n/**\n * Set global predefined tokens.\n * Called from configure() after processing token values.\n * Merges with existing tokens (new tokens override existing ones with same key).\n * Keys are normalized to lowercase (parser lowercases input before classification).\n * @internal\n */\nexport function setGlobalPredefinedTokens(\n tokens: Record<string, string>,\n): void {\n // Normalize keys to lowercase for case-insensitive matching\n const normalizedTokens: Record<string, string> = {};\n for (const [key, value] of Object.entries(tokens)) {\n const lowerKey = key.toLowerCase();\n const lowerValue = value.toLowerCase();\n\n // Warn if trying to use bare #current to define other color tokens\n // #current represents currentcolor which cannot be used as a base for recursive token resolution\n // Note: #current.5 (with opacity) is allowed since it resolves to a concrete color-mix value\n if (lowerKey.startsWith('#') && lowerValue === '#current') {\n console.warn(\n `Tasty: Using #current to define color token \"${key}\" is not supported. ` +\n `The #current token represents currentcolor which cannot be used as a base for other tokens.`,\n );\n continue; // Skip this token\n }\n\n normalizedTokens[lowerKey] = value;\n }\n // Merge with existing tokens (consistent with how states, units, funcs are handled)\n __globalPredefinedTokens = __globalPredefinedTokens\n ? { ...__globalPredefinedTokens, ...normalizedTokens }\n : normalizedTokens;\n // Clear parser cache since token values affect parsing\n getOrCreateParser().clearCache();\n}\n\n/**\n * Get the current global predefined tokens.\n * Returns null if no tokens are configured.\n */\nexport function getGlobalPredefinedTokens(): Record<string, string> | null {\n return __globalPredefinedTokens;\n}\n\n/**\n * Reset global predefined tokens.\n * Used for testing.\n * @internal\n */\nexport function resetGlobalPredefinedTokens(): void {\n __globalPredefinedTokens = null;\n // Clear parser cache since token availability affects parsing\n getOrCreateParser().clearCache();\n}\n\n/**\n *\n * @param {String} value\n * @param {Number} mode\n * @returns {Object<String,String|Array>}\n */\nexport function parseStyle(value: StyleValue): ProcessedStyle {\n let str: string;\n\n if (typeof value === 'string') {\n str = value;\n } else if (typeof value === 'number') {\n str = String(value);\n } else {\n // boolean, null, undefined, objects etc. → empty string\n str = '';\n }\n\n return getOrCreateParser().process(str);\n}\n\n/**\n * Parse color. Find it value, name and opacity.\n * Optimized to avoid heavy parseStyle calls for simple color patterns.\n */\nexport function parseColor(val: string, ignoreError = false): ParsedColor {\n // Early return for non-strings or empty values\n if (typeof val !== 'string') {\n val = String(val ?? '');\n }\n\n val = val.trim();\n if (!val) return {};\n\n // Fast path: Check if it's a simple color pattern that doesn't need full parsing\n const isSimpleColor = isSimpleColorFast(val);\n\n let firstColor: string;\n if (isSimpleColor) {\n // For simple colors, use the value directly without parsing\n firstColor = val;\n } else {\n const processed = parseStyle(val);\n const extractedColor = processed.groups.find((g) => g.colors.length)\n ?.colors[0];\n\n if (!extractedColor) {\n // Rate-limited warning to avoid spam\n if (!ignoreError && devMode && colorWarningCount < MAX_COLOR_WARNINGS) {\n console.warn('CubeUIKit: unable to parse color:', val);\n colorWarningCount++;\n if (colorWarningCount === MAX_COLOR_WARNINGS) {\n console.warn(\n 'CubeUIKit: color parsing warnings will be suppressed from now on',\n );\n }\n }\n return {};\n }\n\n firstColor = extractedColor;\n }\n\n // Extract color name (if present) from variable pattern using precompiled regex\n let nameMatch = firstColor.match(COLOR_VAR_PATTERN);\n if (!nameMatch) {\n nameMatch = firstColor.match(COLOR_VAR_COMPONENTS_PATTERN);\n }\n\n let opacity: number | undefined;\n if (\n firstColor.startsWith('rgb') ||\n firstColor.startsWith('hsl') ||\n firstColor.startsWith('lch') ||\n firstColor.startsWith('oklch') ||\n firstColor.startsWith('okhsl')\n ) {\n const alphaMatch = firstColor.match(RGB_ALPHA_PATTERN);\n if (alphaMatch) {\n const v = parseFloat(alphaMatch[1]);\n if (!isNaN(v)) opacity = v * 100;\n }\n }\n\n return {\n color: firstColor,\n name: nameMatch ? nameMatch[1] : undefined,\n opacity,\n };\n}\n\nexport function filterMods(mods: string[], allowedMods: string[]): string[] {\n return mods.filter((mod) => allowedMods.includes(mod));\n}\n\n// ============================================================================\n// Style Stringification\n// ============================================================================\n\nconst _innerCache = new WeakMap();\nconst _topLevelCache = new WeakMap<object, string>();\n\nexport function stringifyStyles(styles: unknown): string {\n if (styles == null || typeof styles !== 'object') return '';\n\n const cached = _topLevelCache.get(styles as object);\n if (cached !== undefined) return cached;\n\n const obj = styles as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const v = obj[k];\n if (v === undefined || typeof v === 'function' || typeof v === 'symbol')\n continue;\n\n const c0 = k.charCodeAt(0);\n const needsInnerSort =\n ((c0 >= 65 && c0 <= 90) || c0 === 38) &&\n v &&\n typeof v === 'object' &&\n !Array.isArray(v);\n\n let sv: string;\n if (needsInnerSort) {\n sv = _innerCache.get(v);\n if (sv === undefined) {\n const innerObj = v as Record<string, unknown>;\n const innerKeys = Object.keys(innerObj).sort();\n const innerParts: string[] = [];\n for (const ik of innerKeys) {\n const ivs = JSON.stringify(innerObj[ik]);\n if (ivs !== undefined)\n innerParts.push(JSON.stringify(ik) + ':' + ivs);\n }\n sv = '{' + innerParts.join(',') + '}';\n _innerCache.set(v, sv);\n }\n } else {\n sv = JSON.stringify(v);\n }\n parts.push(JSON.stringify(k) + ':' + sv);\n }\n const result = '{' + parts.join(',') + '}';\n _topLevelCache.set(styles as object, result);\n return result;\n}\n"],"mappings":"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"}
@@ -1,7 +1,23 @@
1
- import { Styles } from "../styles/types.js";
2
- import { TypographyPreset } from "../tokens/typography.js";
1
+ import { ConfigTokens } from "../styles/types.js";
3
2
 
4
3
  //#region src/utils/typography.d.ts
4
+ /**
5
+ * Typography preset configuration.
6
+ * Each preset defines font properties that get expanded into CSS custom properties.
7
+ *
8
+ * Use with `generateTypographyTokens()` to create typography tokens for your design system.
9
+ */
10
+ interface TypographyPreset {
11
+ fontSize: string;
12
+ lineHeight: string;
13
+ letterSpacing?: string;
14
+ fontWeight: string | number;
15
+ boldFontWeight?: string | number;
16
+ iconSize?: string;
17
+ textTransform?: string;
18
+ fontFamily?: string;
19
+ fontStyle?: string;
20
+ }
5
21
  /**
6
22
  * Generate typography tokens with $ prefix for CSS custom properties.
7
23
  *
@@ -16,21 +32,16 @@ import { TypographyPreset } from "../tokens/typography.js";
16
32
  * - `${name}-font-family` (if defined)
17
33
  * - `${name}-font-style` (if defined)
18
34
  *
19
- * @param presets - Typography presets object (defaults to TYPOGRAPHY_PRESETS)
20
- * @returns Styles object with $ prefixed keys
21
- *
22
- * @example
23
- * // Using default presets
24
- * const tokens = generateTypographyTokens();
25
- * // tokens['$h1-font-size'] === '36px'
35
+ * @param presets - Typography presets object
36
+ * @returns ConfigTokens object with $ prefixed keys
26
37
  *
27
38
  * @example
28
- * // Using custom presets
29
39
  * const customTokens = generateTypographyTokens({
30
- * myHeading: { fontSize: '24px', lineHeight: '32px', fontWeight: '700' }
40
+ * myHeading: { fontSize: '24px', lineHeight: '32px', fontWeight: '700' },
41
+ * body: { fontSize: '16px', lineHeight: '24px', fontWeight: '400' },
31
42
  * });
32
43
  */
33
- declare function generateTypographyTokens(presets?: Record<string, TypographyPreset>): Styles;
44
+ declare function generateTypographyTokens(presets: Record<string, TypographyPreset>): ConfigTokens;
34
45
  //#endregion
35
- export { generateTypographyTokens };
46
+ export { TypographyPreset, generateTypographyTokens };
36
47
  //# sourceMappingURL=typography.d.ts.map
@@ -1,5 +1,3 @@
1
- import { TYPOGRAPHY_PRESETS } from "../tokens/typography.js";
2
-
3
1
  //#region src/utils/typography.ts
4
2
  /**
5
3
  * Generate typography tokens with $ prefix for CSS custom properties.
@@ -15,31 +13,23 @@ import { TYPOGRAPHY_PRESETS } from "../tokens/typography.js";
15
13
  * - `${name}-font-family` (if defined)
16
14
  * - `${name}-font-style` (if defined)
17
15
  *
18
- * @param presets - Typography presets object (defaults to TYPOGRAPHY_PRESETS)
19
- * @returns Styles object with $ prefixed keys
20
- *
21
- * @example
22
- * // Using default presets
23
- * const tokens = generateTypographyTokens();
24
- * // tokens['$h1-font-size'] === '36px'
16
+ * @param presets - Typography presets object
17
+ * @returns ConfigTokens object with $ prefixed keys
25
18
  *
26
19
  * @example
27
- * // Using custom presets
28
20
  * const customTokens = generateTypographyTokens({
29
- * myHeading: { fontSize: '24px', lineHeight: '32px', fontWeight: '700' }
21
+ * myHeading: { fontSize: '24px', lineHeight: '32px', fontWeight: '700' },
22
+ * body: { fontSize: '16px', lineHeight: '24px', fontWeight: '400' },
30
23
  * });
31
24
  */
32
- function generateTypographyTokens(presets = TYPOGRAPHY_PRESETS) {
25
+ function generateTypographyTokens(presets) {
33
26
  const tokens = {};
34
27
  for (const [name, preset] of Object.entries(presets)) {
35
28
  tokens[`$${name}-font-size`] = preset.fontSize;
36
29
  tokens[`$${name}-line-height`] = preset.lineHeight;
37
30
  tokens[`$${name}-letter-spacing`] = preset.letterSpacing ?? "0";
38
31
  tokens[`$${name}-font-weight`] = preset.fontWeight;
39
- if (preset.boldFontWeight !== void 0) {
40
- const boldKey = name === "c1" ? `$${name}-font-bold-weight` : `$${name}-bold-font-weight`;
41
- tokens[boldKey] = preset.boldFontWeight;
42
- }
32
+ if (preset.boldFontWeight !== void 0) tokens[`$${name}-bold-font-weight`] = preset.boldFontWeight;
43
33
  if (preset.iconSize !== void 0) tokens[`$${name}-icon-size`] = preset.iconSize;
44
34
  if (preset.textTransform !== void 0) tokens[`$${name}-text-transform`] = preset.textTransform;
45
35
  if (preset.fontFamily !== void 0) tokens[`$${name}-font-family`] = preset.fontFamily;
@@ -1 +1 @@
1
- {"version":3,"file":"typography.js","names":[],"sources":["../../src/utils/typography.ts"],"sourcesContent":["import type { TypographyPreset } from '../tokens/typography';\nimport { TYPOGRAPHY_PRESETS } from '../tokens/typography';\n\nimport type { Styles } from '../styles/types';\n\n// Re-export types for convenience\nexport type { TypographyPreset };\n\n/**\n * Generate typography tokens with $ prefix for CSS custom properties.\n *\n * Each preset generates the following CSS custom properties:\n * - `${name}-font-size`\n * - `${name}-line-height`\n * - `${name}-letter-spacing`\n * - `${name}-font-weight`\n * - `${name}-bold-font-weight` (if defined)\n * - `${name}-icon-size` (if defined)\n * - `${name}-text-transform` (if defined)\n * - `${name}-font-family` (if defined)\n * - `${name}-font-style` (if defined)\n *\n * @param presets - Typography presets object (defaults to TYPOGRAPHY_PRESETS)\n * @returns Styles object with $ prefixed keys\n *\n * @example\n * // Using default presets\n * const tokens = generateTypographyTokens();\n * // tokens['$h1-font-size'] === '36px'\n *\n * @example\n * // Using custom presets\n * const customTokens = generateTypographyTokens({\n * myHeading: { fontSize: '24px', lineHeight: '32px', fontWeight: '700' }\n * });\n */\nexport function generateTypographyTokens(\n presets: Record<string, TypographyPreset> = TYPOGRAPHY_PRESETS,\n): Styles {\n const tokens: Record<string, string | number> = {};\n\n for (const [name, preset] of Object.entries(presets)) {\n tokens[`$${name}-font-size`] = preset.fontSize;\n tokens[`$${name}-line-height`] = preset.lineHeight;\n tokens[`$${name}-letter-spacing`] = preset.letterSpacing ?? '0';\n tokens[`$${name}-font-weight`] = preset.fontWeight;\n\n if (preset.boldFontWeight !== undefined) {\n // Handle different property naming for c1 (uses font-bold-weight instead of bold-font-weight)\n const boldKey =\n name === 'c1'\n ? `$${name}-font-bold-weight`\n : `$${name}-bold-font-weight`;\n tokens[boldKey] = preset.boldFontWeight;\n }\n\n if (preset.iconSize !== undefined) {\n tokens[`$${name}-icon-size`] = preset.iconSize;\n }\n\n if (preset.textTransform !== undefined) {\n tokens[`$${name}-text-transform`] = preset.textTransform;\n }\n\n if (preset.fontFamily !== undefined) {\n tokens[`$${name}-font-family`] = preset.fontFamily;\n }\n\n if (preset.fontStyle !== undefined) {\n tokens[`$${name}-font-style`] = preset.fontStyle;\n }\n }\n\n return tokens as Styles;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAgB,yBACd,UAA4C,oBACpC;CACR,MAAM,SAA0C,EAAE;AAElD,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,QAAQ,EAAE;AACpD,SAAO,IAAI,KAAK,eAAe,OAAO;AACtC,SAAO,IAAI,KAAK,iBAAiB,OAAO;AACxC,SAAO,IAAI,KAAK,oBAAoB,OAAO,iBAAiB;AAC5D,SAAO,IAAI,KAAK,iBAAiB,OAAO;AAExC,MAAI,OAAO,mBAAmB,QAAW;GAEvC,MAAM,UACJ,SAAS,OACL,IAAI,KAAK,qBACT,IAAI,KAAK;AACf,UAAO,WAAW,OAAO;;AAG3B,MAAI,OAAO,aAAa,OACtB,QAAO,IAAI,KAAK,eAAe,OAAO;AAGxC,MAAI,OAAO,kBAAkB,OAC3B,QAAO,IAAI,KAAK,oBAAoB,OAAO;AAG7C,MAAI,OAAO,eAAe,OACxB,QAAO,IAAI,KAAK,iBAAiB,OAAO;AAG1C,MAAI,OAAO,cAAc,OACvB,QAAO,IAAI,KAAK,gBAAgB,OAAO;;AAI3C,QAAO"}
1
+ {"version":3,"file":"typography.js","names":[],"sources":["../../src/utils/typography.ts"],"sourcesContent":["import type { ConfigTokens } from '../styles/types';\n\n/**\n * Typography preset configuration.\n * Each preset defines font properties that get expanded into CSS custom properties.\n *\n * Use with `generateTypographyTokens()` to create typography tokens for your design system.\n */\nexport interface TypographyPreset {\n fontSize: string;\n lineHeight: string;\n letterSpacing?: string;\n fontWeight: string | number;\n boldFontWeight?: string | number;\n iconSize?: string;\n textTransform?: string;\n fontFamily?: string;\n fontStyle?: string;\n}\n\n/**\n * Generate typography tokens with $ prefix for CSS custom properties.\n *\n * Each preset generates the following CSS custom properties:\n * - `${name}-font-size`\n * - `${name}-line-height`\n * - `${name}-letter-spacing`\n * - `${name}-font-weight`\n * - `${name}-bold-font-weight` (if defined)\n * - `${name}-icon-size` (if defined)\n * - `${name}-text-transform` (if defined)\n * - `${name}-font-family` (if defined)\n * - `${name}-font-style` (if defined)\n *\n * @param presets - Typography presets object\n * @returns ConfigTokens object with $ prefixed keys\n *\n * @example\n * const customTokens = generateTypographyTokens({\n * myHeading: { fontSize: '24px', lineHeight: '32px', fontWeight: '700' },\n * body: { fontSize: '16px', lineHeight: '24px', fontWeight: '400' },\n * });\n */\nexport function generateTypographyTokens(\n presets: Record<string, TypographyPreset>,\n): ConfigTokens {\n const tokens: Record<`$${string}`, string | number> = {};\n\n for (const [name, preset] of Object.entries(presets)) {\n tokens[`$${name}-font-size`] = preset.fontSize;\n tokens[`$${name}-line-height`] = preset.lineHeight;\n tokens[`$${name}-letter-spacing`] = preset.letterSpacing ?? '0';\n tokens[`$${name}-font-weight`] = preset.fontWeight;\n\n if (preset.boldFontWeight !== undefined) {\n tokens[`$${name}-bold-font-weight`] = preset.boldFontWeight;\n }\n\n if (preset.iconSize !== undefined) {\n tokens[`$${name}-icon-size`] = preset.iconSize;\n }\n\n if (preset.textTransform !== undefined) {\n tokens[`$${name}-text-transform`] = preset.textTransform;\n }\n\n if (preset.fontFamily !== undefined) {\n tokens[`$${name}-font-family`] = preset.fontFamily;\n }\n\n if (preset.fontStyle !== undefined) {\n tokens[`$${name}-font-style`] = preset.fontStyle;\n }\n }\n\n return tokens as ConfigTokens;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA2CA,SAAgB,yBACd,SACc;CACd,MAAM,SAAgD,EAAE;AAExD,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,QAAQ,EAAE;AACpD,SAAO,IAAI,KAAK,eAAe,OAAO;AACtC,SAAO,IAAI,KAAK,iBAAiB,OAAO;AACxC,SAAO,IAAI,KAAK,oBAAoB,OAAO,iBAAiB;AAC5D,SAAO,IAAI,KAAK,iBAAiB,OAAO;AAExC,MAAI,OAAO,mBAAmB,OAC5B,QAAO,IAAI,KAAK,sBAAsB,OAAO;AAG/C,MAAI,OAAO,aAAa,OACtB,QAAO,IAAI,KAAK,eAAe,OAAO;AAGxC,MAAI,OAAO,kBAAkB,OAC3B,QAAO,IAAI,KAAK,oBAAoB,OAAO;AAG7C,MAAI,OAAO,eAAe,OACxB,QAAO,IAAI,KAAK,iBAAiB,OAAO;AAG1C,MAAI,OAAO,cAAc,OACvB,QAAO,IAAI,KAAK,gBAAgB,OAAO;;AAI3C,QAAO"}
@@ -1,7 +1,7 @@
1
1
  import { KeyframesSteps } from "../injector/types.js";
2
2
  import { StyleDetails, UnitHandler } from "../parser/types.js";
3
3
  import { StyleHandlerDefinition } from "../utils/styles.js";
4
- import { RecipeStyles } from "../styles/types.js";
4
+ import { ConfigTokens, RecipeStyles } from "../styles/types.js";
5
5
  import { TastyPlugin } from "../plugins/types.js";
6
6
  import * as _babel_core0 from "@babel/core";
7
7
  import { PluginPass } from "@babel/core";
@@ -40,7 +40,7 @@ interface TastyZeroConfig {
40
40
  */
41
41
  funcs?: Record<string, (groups: StyleDetails[]) => string>;
42
42
  /**
43
- * Plugins that extend tasty with custom functions, units, states, handlers, or tokens.
43
+ * Plugins that extend tasty with custom functions, units, states, and handlers.
44
44
  * Plugins are processed in order, with later plugins overriding earlier ones.
45
45
  * @example
46
46
  * ```ts
@@ -78,11 +78,17 @@ interface TastyZeroConfig {
78
78
  */
79
79
  handlers?: Record<string, StyleHandlerDefinition>;
80
80
  /**
81
- * Predefined tokens that are replaced during style parsing.
81
+ * Design tokens injected as CSS custom properties on `:root`.
82
+ * Values are parsed through the Tasty DSL. Supports state maps.
83
+ * @example { '$gap': '4px', '#primary': { '': '#purple', '@dark': '#light-purple' } }
84
+ */
85
+ tokens?: ConfigTokens;
86
+ /**
87
+ * Predefined tokens replaced during style parsing (parse-time substitution).
82
88
  * Use `$name` for custom properties and `#name` for color tokens.
83
89
  * @example { $spacing: '2x', '#accent': '#purple' }
84
90
  */
85
- tokens?: Record<`$${string}` | `#${string}`, string | number>;
91
+ replaceTokens?: Record<`$${string}` | `#${string}`, string | number>;
86
92
  /**
87
93
  * Predefined style recipes -- named style bundles that can be applied via `recipe` style property.
88
94
  * Recipe values are flat tasty styles (no sub-element keys).
@@ -104,8 +110,44 @@ interface TastyZeroConfig {
104
110
  interface TastyZeroBabelOptions {
105
111
  /** Output path for generated CSS (default: 'tasty.css') */
106
112
  output?: string;
107
- /** Tasty configuration for build-time processing */
108
- config?: TastyZeroConfig;
113
+ /**
114
+ * Tasty configuration for build-time processing.
115
+ * Can be a static object or a factory function that returns fresh config.
116
+ * A factory is called on each plugin invocation, enabling hot reload
117
+ * of config values that depend on external files (e.g. theme tokens).
118
+ */
119
+ config?: TastyZeroConfig | (() => TastyZeroConfig);
120
+ /**
121
+ * Absolute path to a TypeScript/JavaScript module that default-exports
122
+ * a `TastyZeroConfig` object. The module is loaded via jiti on each
123
+ * plugin invocation, enabling hot reload when the file changes.
124
+ *
125
+ * This option is JSON-serializable and is the primary way Turbopack
126
+ * passes config to the Babel plugin (since Turbopack loader options
127
+ * must be plain primitives/objects/arrays).
128
+ *
129
+ * When both `config` and `configFile` are set, `config` takes precedence.
130
+ *
131
+ * @example '/absolute/path/to/tasty-zero.config.ts'
132
+ */
133
+ configFile?: string;
134
+ /**
135
+ * Absolute file paths whose content affects the generated CSS.
136
+ * When any of these files change, babel-loader invalidates its cache
137
+ * and re-runs the plugin with fresh config values.
138
+ *
139
+ * Typically includes theme files that define Glaze palettes or token values.
140
+ * Paths must be absolute (resolved by the Next.js wrapper).
141
+ */
142
+ configDeps?: string[];
143
+ /**
144
+ * Automatically replace `@tenphi/tasty/static` imports with an import
145
+ * of the generated CSS file. This eliminates the need for users to
146
+ * manually import the CSS in their app entry point.
147
+ *
148
+ * @default true
149
+ */
150
+ injectImport?: boolean;
109
151
  }
110
152
  declare const _default: (api: object, options: TastyZeroBabelOptions | null | undefined, dirname: string) => _babel_core0.PluginObj<PluginPass>;
111
153
  //#endregion
@@ -1,10 +1,14 @@
1
- import { configure } from "../config.js";
1
+ import { __require } from "../_virtual/_rolldown/runtime.js";
2
+ import { configure, getGlobalConfigTokens } from "../config.js";
2
3
  import { mergeStyles } from "../utils/merge-styles.js";
3
4
  import { resolveRecipes } from "../utils/resolve-recipes.js";
4
5
  import { extractKeyframesFromStyles, extractPropertiesFromStyles, extractStylesForSelector, extractStylesWithChunks } from "./extractor.js";
5
6
  import { CSSWriter } from "./css-writer.js";
7
+ import * as fs from "fs";
8
+ import * as path from "path";
6
9
  import { declare } from "@babel/helper-plugin-utils";
7
10
  import * as t from "@babel/types";
11
+ import { createJiti } from "jiti";
8
12
 
9
13
  //#region src/zero/babel.ts
10
14
  /**
@@ -25,13 +29,59 @@ import * as t from "@babel/types";
25
29
  * };
26
30
  * ```
27
31
  */
32
+ function mtime(filePath) {
33
+ try {
34
+ return fs.statSync(filePath).mtimeMs;
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+ function clearRequireCacheTree(filePath) {
40
+ let resolved;
41
+ try {
42
+ resolved = __require.resolve(filePath);
43
+ } catch {
44
+ return;
45
+ }
46
+ const mod = __require.cache[resolved];
47
+ if (!mod) return;
48
+ const dir = resolved.substring(0, resolved.lastIndexOf("/"));
49
+ if (mod.children) {
50
+ for (const child of mod.children) if (child.id.startsWith(dir) && !child.id.includes("node_modules")) clearRequireCacheTree(child.id);
51
+ }
52
+ delete __require.cache[resolved];
53
+ }
28
54
  var babel_default = declare((api, options) => {
29
55
  api.assertVersion(7);
30
56
  const outputPath = options.output || "tasty.css";
31
- const config = options.config || {};
57
+ const resolvedOutputPath = path.resolve(outputPath);
58
+ const injectImport = options.injectImport ?? true;
59
+ if (injectImport) {
60
+ const dir = path.dirname(resolvedOutputPath);
61
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
62
+ if (!fs.existsSync(resolvedOutputPath)) fs.writeFileSync(resolvedOutputPath, "/* Generated by @tenphi/tasty/zero - DO NOT EDIT */\n");
63
+ }
64
+ const configDeps = [...options.configFile ? [options.configFile] : [], ...options.configDeps || []];
65
+ if (configDeps.length > 0) {
66
+ api.cache.using(() => configDeps.map(mtime).join(","));
67
+ for (const dep of configDeps) try {
68
+ api.addExternalDependency(dep);
69
+ } catch {}
70
+ } else api.cache.forever();
71
+ if (configDeps.length > 0) for (const dep of configDeps) clearRequireCacheTree(dep);
72
+ const configOption = options.config;
73
+ let config;
74
+ if (configOption) config = typeof configOption === "function" ? configOption() : configOption;
75
+ else if (options.configFile) config = createJiti(path.dirname(options.configFile), { moduleCache: false })(options.configFile);
76
+ else config = {};
32
77
  const devMode = config.devMode ?? false;
33
78
  configure(config);
34
79
  const cssWriter = new CSSWriter(outputPath, { devMode });
80
+ const tokenStyles = getGlobalConfigTokens();
81
+ if (tokenStyles && Object.keys(tokenStyles).length > 0) {
82
+ const result = extractStylesForSelector(":root", tokenStyles);
83
+ if (result.css) cssWriter.add(":root:tokens", result.css);
84
+ }
35
85
  const globalRegistry = {};
36
86
  return {
37
87
  name: "tasty-zero",
@@ -40,9 +90,17 @@ var babel_default = declare((api, options) => {
40
90
  if (devMode && this.filename) this.sourceFile = this.filename.split("/").pop() || this.filename;
41
91
  },
42
92
  visitor: {
43
- ImportDeclaration(path) {
44
- const source = path.node.source.value;
45
- if (source === "@tenphi/tasty/static" || source.endsWith("/tasty/static")) path.remove();
93
+ ImportDeclaration(nodePath, state) {
94
+ const source = nodePath.node.source.value;
95
+ if (source === "@tenphi/tasty/static" || source.endsWith("/tasty/static")) if (injectImport) {
96
+ let importPath = resolvedOutputPath;
97
+ if (state.filename) {
98
+ const sourceDir = path.dirname(state.filename);
99
+ importPath = path.relative(sourceDir, resolvedOutputPath);
100
+ if (!importPath.startsWith(".")) importPath = "./" + importPath;
101
+ }
102
+ nodePath.replaceWith(t.importDeclaration([], t.stringLiteral(importPath)));
103
+ } else nodePath.remove();
46
104
  },
47
105
  CallExpression(path, state) {
48
106
  const callee = path.node.callee;