@tenphi/tasty 0.13.0 → 0.14.0

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 (92) hide show
  1. package/README.md +117 -28
  2. package/dist/chunks/cacheKey.js +16 -8
  3. package/dist/chunks/cacheKey.js.map +1 -1
  4. package/dist/chunks/renderChunk.js +31 -32
  5. package/dist/chunks/renderChunk.js.map +1 -1
  6. package/dist/config.d.ts +14 -2
  7. package/dist/config.js +11 -4
  8. package/dist/config.js.map +1 -1
  9. package/dist/core/index.d.ts +6 -4
  10. package/dist/core/index.js +5 -4
  11. package/dist/debug.d.ts +26 -141
  12. package/dist/debug.js +356 -635
  13. package/dist/debug.js.map +1 -1
  14. package/dist/hooks/useStyles.js +4 -3
  15. package/dist/hooks/useStyles.js.map +1 -1
  16. package/dist/index.d.ts +6 -4
  17. package/dist/index.js +5 -4
  18. package/dist/parser/classify.js +2 -1
  19. package/dist/parser/classify.js.map +1 -1
  20. package/dist/parser/parser.js +1 -1
  21. package/dist/pipeline/index.d.ts +1 -1
  22. package/dist/pipeline/index.js +24 -14
  23. package/dist/pipeline/index.js.map +1 -1
  24. package/dist/pipeline/materialize.js +328 -79
  25. package/dist/pipeline/materialize.js.map +1 -1
  26. package/dist/pipeline/parseStateKey.d.ts +1 -1
  27. package/dist/pipeline/parseStateKey.js +2 -6
  28. package/dist/pipeline/parseStateKey.js.map +1 -1
  29. package/dist/plugins/okhsl-plugin.js +2 -275
  30. package/dist/plugins/okhsl-plugin.js.map +1 -1
  31. package/dist/plugins/types.d.ts +1 -1
  32. package/dist/properties/index.js +2 -15
  33. package/dist/properties/index.js.map +1 -1
  34. package/dist/ssr/format-property.js +9 -7
  35. package/dist/ssr/format-property.js.map +1 -1
  36. package/dist/states/index.js +10 -257
  37. package/dist/states/index.js.map +1 -1
  38. package/dist/styles/color.js +9 -5
  39. package/dist/styles/color.js.map +1 -1
  40. package/dist/styles/createStyle.js +24 -21
  41. package/dist/styles/createStyle.js.map +1 -1
  42. package/dist/styles/index.js +1 -1
  43. package/dist/styles/predefined.js +1 -1
  44. package/dist/styles/predefined.js.map +1 -1
  45. package/dist/styles/types.d.ts +1 -1
  46. package/dist/tasty.d.ts +6 -6
  47. package/dist/tasty.js +24 -11
  48. package/dist/tasty.js.map +1 -1
  49. package/dist/types.d.ts +1 -1
  50. package/dist/utils/cache-wrapper.js +4 -8
  51. package/dist/utils/cache-wrapper.js.map +1 -1
  52. package/dist/utils/color-math.d.ts +46 -0
  53. package/dist/utils/color-math.js +749 -0
  54. package/dist/utils/color-math.js.map +1 -0
  55. package/dist/utils/color-space.d.ts +5 -0
  56. package/dist/utils/color-space.js +229 -0
  57. package/dist/utils/color-space.js.map +1 -0
  58. package/dist/utils/colors.js +3 -1
  59. package/dist/utils/colors.js.map +1 -1
  60. package/dist/utils/has-keys.js +13 -0
  61. package/dist/utils/has-keys.js.map +1 -0
  62. package/dist/utils/mod-attrs.js +2 -2
  63. package/dist/utils/mod-attrs.js.map +1 -1
  64. package/dist/utils/process-tokens.d.ts +3 -13
  65. package/dist/utils/process-tokens.js +18 -98
  66. package/dist/utils/process-tokens.js.map +1 -1
  67. package/dist/utils/styles.d.ts +2 -78
  68. package/dist/utils/styles.js +28 -535
  69. package/dist/utils/styles.js.map +1 -1
  70. package/dist/zero/babel.d.ts +8 -0
  71. package/dist/zero/babel.js +18 -3
  72. package/dist/zero/babel.js.map +1 -1
  73. package/dist/zero/next.js +9 -1
  74. package/dist/zero/next.js.map +1 -1
  75. package/docs/PIPELINE.md +519 -0
  76. package/docs/README.md +30 -0
  77. package/docs/adoption.md +10 -2
  78. package/docs/comparison.md +11 -6
  79. package/docs/configuration.md +26 -3
  80. package/docs/debug.md +152 -339
  81. package/docs/dsl.md +3 -1
  82. package/docs/getting-started.md +21 -7
  83. package/docs/injector.md +2 -2
  84. package/docs/runtime.md +59 -9
  85. package/docs/ssr.md +2 -2
  86. package/docs/styles.md +1 -1
  87. package/docs/tasty-static.md +19 -9
  88. package/package.json +4 -3
  89. package/dist/utils/hsl-to-rgb.js +0 -38
  90. package/dist/utils/hsl-to-rgb.js.map +0 -1
  91. package/dist/utils/okhsl-to-rgb.js +0 -296
  92. package/dist/utils/okhsl-to-rgb.js.map +0 -1
@@ -1,102 +1,21 @@
1
- import { okhslToRgb } from "./okhsl-to-rgb.js";
2
- import { getRgbValuesFromRgbaString, hexToRgb, normalizeColorTokenValue, parseStyle } from "./styles.js";
1
+ import { hslToRgbValues } from "./color-math.js";
2
+ import { getColorSpaceComponents, getColorSpaceSuffix } from "./color-space.js";
3
+ import { normalizeColorTokenValue, parseStyle } from "./styles.js";
3
4
 
4
5
  //#region src/utils/process-tokens.ts
5
6
  /**
6
- * Parse HSL values from an hsl()/hsla() string.
7
- * Supports both comma-separated (legacy) and space-separated (modern) syntax:
8
- * hsl(200, 40%, 50%)
9
- * hsl(200 40% 50%)
10
- * hsl(200 40% 50% / 0.5)
11
- *
12
- * Returns [h, s, l] where h is 0-360, s and l are 0-1, or null if parsing fails.
13
- */
14
- function parseHslValues(str) {
15
- const match = str.match(/hsla?\(([^)]+)\)/i);
16
- if (!match) return null;
17
- const [colorPart] = match[1].trim().split("/");
18
- const parts = colorPart.trim().split(/[,\s]+/).filter(Boolean);
19
- if (parts.length < 3) return null;
20
- let h = parseFloat(parts[0]);
21
- const hueStr = parts[0].toLowerCase();
22
- if (hueStr.endsWith("turn")) h = parseFloat(hueStr) * 360;
23
- else if (hueStr.endsWith("rad")) h = parseFloat(hueStr) * 180 / Math.PI;
24
- else if (hueStr.endsWith("grad")) h = parseFloat(hueStr) * .9;
25
- h = h % 360;
26
- if (h < 0) h += 360;
27
- const parsePercent = (val) => {
28
- const num = parseFloat(val);
29
- return val.includes("%") ? num / 100 : num;
30
- };
31
- const s = Math.max(0, Math.min(1, parsePercent(parts[1])));
32
- const l = Math.max(0, Math.min(1, parsePercent(parts[2])));
33
- return [
34
- h,
35
- s,
36
- l
37
- ];
38
- }
39
- /**
40
- * Convert HSL to RGB (sRGB).
41
- * Algorithm from: https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB_alternative
42
- * Same as used in CSS Color 4 spec.
43
- *
44
- * @param h - Hue in degrees (0-360)
45
- * @param s - Saturation (0-1)
46
- * @param l - Lightness (0-1)
47
- * @returns RGB values in 0-255 range (may have fractional values)
48
- */
49
- function hslToRgbValues(h, s, l) {
50
- const a = s * Math.min(l, 1 - l);
51
- const f = (n) => {
52
- const k = (n + h / 30) % 12;
53
- return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));
54
- };
55
- return [
56
- f(0) * 255,
57
- f(8) * 255,
58
- f(4) * 255
59
- ];
60
- }
61
- /**
62
- * Format a number to a string with up to 1 decimal place, removing trailing zeros.
63
- */
64
- function formatRgbComponent(n) {
65
- return parseFloat(n.toFixed(1)).toString();
66
- }
67
- /**
68
- * Extract RGB triplet from a color value.
69
- * Returns the RGB values as a space-separated string (e.g., "255 128 0")
70
- * or a CSS variable reference for token colors.
7
+ * Extract color components in the configured color space.
8
+ * Returns a CSS variable reference for token colors, or decomposed
9
+ * components as a space-separated string.
71
10
  */
72
- function extractRgbValue(colorValue, parsedOutput) {
11
+ function extractColorSpaceValue(colorValue, parsedOutput) {
12
+ const suffix = getColorSpaceSuffix();
73
13
  const varMatch = parsedOutput.match(/var\(--([a-z0-9-]+)-color\)/);
74
- if (varMatch) return `var(--${varMatch[1]}-color-rgb)`;
75
- if (parsedOutput.startsWith("rgb(")) {
76
- const rgbValues = getRgbValuesFromRgbaString(parsedOutput);
77
- if (rgbValues && rgbValues.length >= 3) return rgbValues.join(" ");
78
- }
79
- if (parsedOutput.startsWith("hsl(") || parsedOutput.startsWith("hsla(") || colorValue.startsWith("hsl(") || colorValue.startsWith("hsla(")) {
80
- const hslValues = parseHslValues(parsedOutput) || parseHslValues(colorValue);
81
- if (hslValues) {
82
- const [r, g, b] = hslToRgbValues(hslValues[0], hslValues[1], hslValues[2]);
83
- return `${formatRgbComponent(r)} ${formatRgbComponent(g)} ${formatRgbComponent(b)}`;
84
- }
85
- }
86
- if (parsedOutput.startsWith("okhsl(") || colorValue.startsWith("okhsl(")) {
87
- const rgbResult = okhslToRgb(parsedOutput) || okhslToRgb(colorValue);
88
- if (rgbResult) {
89
- const rgbValues = getRgbValuesFromRgbaString(rgbResult);
90
- if (rgbValues && rgbValues.length >= 3) return rgbValues.join(" ");
91
- }
92
- }
93
- if (colorValue.startsWith("#") && /^#[0-9a-fA-F]{3,8}$/.test(colorValue)) {
94
- const rgbResult = hexToRgb(colorValue);
95
- if (rgbResult) {
96
- const rgbValues = getRgbValuesFromRgbaString(rgbResult);
97
- if (rgbValues && rgbValues.length >= 3) return rgbValues.join(" ");
98
- }
99
- }
14
+ if (varMatch) return `var(--${varMatch[1]}-color-${suffix})`;
15
+ const components = getColorSpaceComponents(colorValue);
16
+ if (components !== colorValue) return components;
17
+ const componentsFromParsed = getColorSpaceComponents(parsedOutput);
18
+ if (componentsFromParsed !== parsedOutput) return componentsFromParsed;
100
19
  return parsedOutput;
101
20
  }
102
21
  /**
@@ -106,7 +25,7 @@ function extractRgbValue(colorValue, parsedOutput) {
106
25
  function isValidTokenValue(value) {
107
26
  if (value === void 0 || value === null || value === false) return false;
108
27
  if (typeof value === "object") {
109
- console.warn("CubeUIKit: Object values are not allowed in tokens prop. Tokens do not support state-based styling. Use a primitive value instead.");
28
+ console.warn("Tasty: Object values are not allowed in tokens prop. Tokens do not support state-based styling. Use a primitive value instead.");
110
29
  return false;
111
30
  }
112
31
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
@@ -125,7 +44,7 @@ function processTokenValue(value) {
125
44
  /**
126
45
  * Process tokens object into inline style properties.
127
46
  * - $name -> --name with parsed value
128
- * - #name -> --name-color AND --name-color-rgb with parsed values
47
+ * - #name -> --name-color AND --name-color-{colorSpace} with parsed values
129
48
  *
130
49
  * @param tokens - The tokens object to process
131
50
  * @returns CSSProperties object or undefined if no tokens to process
@@ -145,6 +64,7 @@ function processTokens(tokens) {
145
64
  result[propName] = processedValue;
146
65
  } else if (key.startsWith("#")) {
147
66
  const colorName = key.slice(1);
67
+ const suffix = getColorSpaceSuffix();
148
68
  const effectiveValue = normalizeColorTokenValue(value);
149
69
  if (effectiveValue === null) continue;
150
70
  const originalValue = typeof effectiveValue === "number" ? String(effectiveValue) : effectiveValue;
@@ -153,7 +73,7 @@ function processTokens(tokens) {
153
73
  if (!result) result = {};
154
74
  result[`--${colorName}-color`] = processedValue;
155
75
  if (/^#current(?:\.|$)/i.test(lowerValue)) continue;
156
- result[`--${colorName}-color-rgb`] = extractRgbValue(originalValue, processedValue);
76
+ result[`--${colorName}-color-${suffix}`] = extractColorSpaceValue(originalValue, processedValue);
157
77
  }
158
78
  }
159
79
  return result;
@@ -167,5 +87,5 @@ function stringifyTokens(tokens) {
167
87
  }
168
88
 
169
89
  //#endregion
170
- export { hslToRgbValues, processTokens, stringifyTokens };
90
+ export { processTokens, stringifyTokens };
171
91
  //# sourceMappingURL=process-tokens.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"process-tokens.js","names":[],"sources":["../../src/utils/process-tokens.ts"],"sourcesContent":["import type { Tokens, TokenValue } from '../types';\n\nimport type { CSSProperties } from './css-types';\n\nimport { okhslToRgb } from './okhsl-to-rgb';\nimport {\n getRgbValuesFromRgbaString,\n hexToRgb,\n normalizeColorTokenValue,\n parseStyle,\n} from './styles';\n\nconst devMode = process.env.NODE_ENV !== 'production';\n\n/**\n * Parse HSL values from an hsl()/hsla() string.\n * Supports both comma-separated (legacy) and space-separated (modern) syntax:\n * hsl(200, 40%, 50%)\n * hsl(200 40% 50%)\n * hsl(200 40% 50% / 0.5)\n *\n * Returns [h, s, l] where h is 0-360, s and l are 0-1, or null if parsing fails.\n */\nfunction parseHslValues(str: string): [number, number, number] | null {\n const match = str.match(/hsla?\\(([^)]+)\\)/i);\n if (!match) return null;\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 if (parts.length < 3) return null;\n\n // Parse hue (can be unitless degrees, deg, turn, rad, or grad)\n let h = parseFloat(parts[0]);\n const hueStr = parts[0].toLowerCase();\n if (hueStr.endsWith('turn')) {\n h = parseFloat(hueStr) * 360;\n } else if (hueStr.endsWith('rad')) {\n h = (parseFloat(hueStr) * 180) / Math.PI;\n } else if (hueStr.endsWith('grad')) {\n h = parseFloat(hueStr) * 0.9; // 400 grad = 360 deg\n }\n // deg or unitless are already in degrees\n\n // Normalize hue to 0-360 range\n h = h % 360;\n if (h < 0) h += 360;\n\n // Parse saturation and lightness (percentages)\n const parsePercent = (val: string): number => {\n const num = parseFloat(val);\n return val.includes('%') ? num / 100 : num;\n };\n\n const s = Math.max(0, Math.min(1, parsePercent(parts[1])));\n const l = Math.max(0, Math.min(1, parsePercent(parts[2])));\n\n return [h, s, l];\n}\n\n/**\n * Convert HSL to RGB (sRGB).\n * Algorithm from: https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB_alternative\n * Same as used in CSS Color 4 spec.\n *\n * @param h - Hue in degrees (0-360)\n * @param s - Saturation (0-1)\n * @param l - Lightness (0-1)\n * @returns RGB values in 0-255 range (may have fractional values)\n */\nexport function hslToRgbValues(\n h: number,\n s: number,\n l: number,\n): [number, number, number] {\n const a = s * Math.min(l, 1 - l);\n\n const f = (n: number): number => {\n const k = (n + h / 30) % 12;\n return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));\n };\n\n // Convert 0-1 range to 0-255\n return [f(0) * 255, f(8) * 255, f(4) * 255];\n}\n\n/**\n * Format a number to a string with up to 1 decimal place, removing trailing zeros.\n */\nfunction formatRgbComponent(n: number): string {\n return parseFloat(n.toFixed(1)).toString();\n}\n\n/**\n * Extract RGB triplet from a color value.\n * Returns the RGB values as a space-separated string (e.g., \"255 128 0\")\n * or a CSS variable reference for token colors.\n */\nfunction extractRgbValue(colorValue: string, parsedOutput: string): string {\n // If the parsed output references a color variable, use the -rgb variant\n const varMatch = parsedOutput.match(/var\\(--([a-z0-9-]+)-color\\)/);\n if (varMatch) {\n return `var(--${varMatch[1]}-color-rgb)`;\n }\n\n // For rgb(...) values, extract the triplet\n if (parsedOutput.startsWith('rgb(')) {\n const rgbValues = getRgbValuesFromRgbaString(parsedOutput);\n if (rgbValues && rgbValues.length >= 3) {\n return rgbValues.join(' ');\n }\n }\n\n // For hsl(...) values, convert to RGB triplet\n if (\n parsedOutput.startsWith('hsl(') ||\n parsedOutput.startsWith('hsla(') ||\n colorValue.startsWith('hsl(') ||\n colorValue.startsWith('hsla(')\n ) {\n // Try parsedOutput first, then original colorValue\n const hslValues =\n parseHslValues(parsedOutput) || parseHslValues(colorValue);\n if (hslValues) {\n const [r, g, b] = hslToRgbValues(\n hslValues[0],\n hslValues[1],\n hslValues[2],\n );\n return `${formatRgbComponent(r)} ${formatRgbComponent(g)} ${formatRgbComponent(b)}`;\n }\n }\n\n // For okhsl(...) values, convert to RGB triplet\n if (parsedOutput.startsWith('okhsl(') || colorValue.startsWith('okhsl(')) {\n // Try parsedOutput first, then original colorValue\n const rgbResult = okhslToRgb(parsedOutput) || okhslToRgb(colorValue);\n if (rgbResult) {\n const rgbValues = getRgbValuesFromRgbaString(rgbResult);\n if (rgbValues && rgbValues.length >= 3) {\n return rgbValues.join(' ');\n }\n }\n }\n\n // For hex values, convert to RGB triplet\n if (colorValue.startsWith('#') && /^#[0-9a-fA-F]{3,8}$/.test(colorValue)) {\n const rgbResult = hexToRgb(colorValue);\n if (rgbResult) {\n const rgbValues = getRgbValuesFromRgbaString(rgbResult);\n if (rgbValues && rgbValues.length >= 3) {\n return rgbValues.join(' ');\n }\n }\n }\n\n // Fallback: return the parsed output (may not be ideal but covers edge cases)\n return parsedOutput;\n}\n\n/**\n * Check if a value is a valid token value (string, number, or boolean - not object).\n * Returns false for `false` values (they mean \"skip this token\").\n */\nfunction isValidTokenValue(\n value: unknown,\n): value is Exclude<TokenValue, undefined | null | false> {\n if (value === undefined || value === null || value === false) {\n return false;\n }\n\n if (typeof value === 'object') {\n if (devMode) {\n console.warn(\n 'CubeUIKit: Object values are not allowed in tokens prop. ' +\n 'Tokens do not support state-based styling. Use a primitive value instead.',\n );\n }\n return false;\n }\n\n return (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n );\n}\n\n/**\n * Process a single token value through the tasty parser.\n * Numbers are converted to strings; 0 stays as \"0\".\n */\nfunction processTokenValue(value: string | number): string {\n if (typeof value === 'number') {\n // 0 should remain as \"0\", not converted to any unit\n if (value === 0) {\n return '0';\n }\n return parseStyle(String(value)).output;\n }\n return parseStyle(value).output;\n}\n\n/**\n * Process tokens object into inline style properties.\n * - $name -> --name with parsed value\n * - #name -> --name-color AND --name-color-rgb with parsed values\n *\n * @param tokens - The tokens object to process\n * @returns CSSProperties object or undefined if no tokens to process\n */\nexport function processTokens(\n tokens: Tokens | undefined,\n): CSSProperties | undefined {\n if (!tokens) {\n return undefined;\n }\n\n const keys = Object.keys(tokens);\n if (keys.length === 0) {\n return undefined;\n }\n\n let result: Record<string, string> | undefined;\n\n for (const key of keys) {\n const value = tokens[key as keyof Tokens];\n\n // Skip undefined/null values\n if (!isValidTokenValue(value)) {\n continue;\n }\n\n if (key.startsWith('$')) {\n // Custom property token: $name -> --name\n const propName = `--${key.slice(1)}`;\n // Boolean true for custom properties converts to empty string (valid CSS value)\n const effectiveValue = value === true ? '' : value;\n const processedValue = processTokenValue(effectiveValue);\n\n if (!result) result = {};\n result[propName] = processedValue;\n } else if (key.startsWith('#')) {\n // Color token: #name -> --name-color and --name-color-rgb\n const colorName = key.slice(1);\n\n // Normalize color token value (true → 'transparent', false is already filtered by isValidTokenValue)\n const effectiveValue = normalizeColorTokenValue(value);\n // Skip if normalized to null (shouldn't happen since false is filtered by isValidTokenValue)\n if (effectiveValue === null) continue;\n\n const originalValue =\n typeof effectiveValue === 'number'\n ? String(effectiveValue)\n : effectiveValue;\n const lowerValue = originalValue.toLowerCase();\n const processedValue = processTokenValue(effectiveValue);\n\n if (!result) result = {};\n result[`--${colorName}-color`] = processedValue;\n\n // Skip RGB generation for #current values (currentcolor is dynamic, cannot extract RGB)\n // Match only #current or #current.opacity, not #current-theme or #currently-used\n if (/^#current(?:\\.|$)/i.test(lowerValue)) {\n continue;\n }\n\n result[`--${colorName}-color-rgb`] = extractRgbValue(\n originalValue,\n processedValue,\n );\n }\n }\n\n return result as CSSProperties | undefined;\n}\n\n/**\n * Stringify tokens for memoization key.\n */\nexport function stringifyTokens(tokens: Tokens | undefined): string {\n if (!tokens) return '';\n return JSON.stringify(tokens);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"process-tokens.js","names":[],"sources":["../../src/utils/process-tokens.ts"],"sourcesContent":["import type { Tokens, TokenValue } from '../types';\n\nimport type { CSSProperties } from './css-types';\n\nimport { getColorSpaceComponents, getColorSpaceSuffix } from './color-space';\nimport { normalizeColorTokenValue, parseStyle } from './styles';\n\nexport { hslToRgbValues } from './color-math';\n\nconst devMode = process.env.NODE_ENV !== 'production';\n\n/**\n * Extract color components in the configured color space.\n * Returns a CSS variable reference for token colors, or decomposed\n * components as a space-separated string.\n */\nfunction extractColorSpaceValue(\n colorValue: string,\n parsedOutput: string,\n): string {\n const suffix = getColorSpaceSuffix();\n\n // If the parsed output references a color variable, use the companion variant\n const varMatch = parsedOutput.match(/var\\(--([a-z0-9-]+)-color\\)/);\n if (varMatch) {\n return `var(--${varMatch[1]}-color-${suffix})`;\n }\n\n // Try the original color value first, then parsed output\n const components = getColorSpaceComponents(colorValue);\n if (components !== colorValue) return components;\n\n const componentsFromParsed = getColorSpaceComponents(parsedOutput);\n if (componentsFromParsed !== parsedOutput) return componentsFromParsed;\n\n // Fallback: return the parsed output\n return parsedOutput;\n}\n\n/**\n * Check if a value is a valid token value (string, number, or boolean - not object).\n * Returns false for `false` values (they mean \"skip this token\").\n */\nfunction isValidTokenValue(\n value: unknown,\n): value is Exclude<TokenValue, undefined | null | false> {\n if (value === undefined || value === null || value === false) {\n return false;\n }\n\n if (typeof value === 'object') {\n if (devMode) {\n console.warn(\n 'Tasty: Object values are not allowed in tokens prop. ' +\n 'Tokens do not support state-based styling. Use a primitive value instead.',\n );\n }\n return false;\n }\n\n return (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n );\n}\n\n/**\n * Process a single token value through the tasty parser.\n * Numbers are converted to strings; 0 stays as \"0\".\n */\nfunction processTokenValue(value: string | number): string {\n if (typeof value === 'number') {\n // 0 should remain as \"0\", not converted to any unit\n if (value === 0) {\n return '0';\n }\n return parseStyle(String(value)).output;\n }\n return parseStyle(value).output;\n}\n\n/**\n * Process tokens object into inline style properties.\n * - $name -> --name with parsed value\n * - #name -> --name-color AND --name-color-{colorSpace} with parsed values\n *\n * @param tokens - The tokens object to process\n * @returns CSSProperties object or undefined if no tokens to process\n */\nexport function processTokens(\n tokens: Tokens | undefined,\n): CSSProperties | undefined {\n if (!tokens) {\n return undefined;\n }\n\n const keys = Object.keys(tokens);\n if (keys.length === 0) {\n return undefined;\n }\n\n let result: Record<string, string> | undefined;\n\n for (const key of keys) {\n const value = tokens[key as keyof Tokens];\n\n // Skip undefined/null values\n if (!isValidTokenValue(value)) {\n continue;\n }\n\n if (key.startsWith('$')) {\n // Custom property token: $name -> --name\n const propName = `--${key.slice(1)}`;\n // Boolean true for custom properties converts to empty string (valid CSS value)\n const effectiveValue = value === true ? '' : value;\n const processedValue = processTokenValue(effectiveValue);\n\n if (!result) result = {};\n result[propName] = processedValue;\n } else if (key.startsWith('#')) {\n const colorName = key.slice(1);\n const suffix = getColorSpaceSuffix();\n\n // Normalize color token value (true → 'transparent', false is already filtered by isValidTokenValue)\n const effectiveValue = normalizeColorTokenValue(value);\n // Skip if normalized to null (shouldn't happen since false is filtered by isValidTokenValue)\n if (effectiveValue === null) continue;\n\n const originalValue =\n typeof effectiveValue === 'number'\n ? String(effectiveValue)\n : effectiveValue;\n const lowerValue = originalValue.toLowerCase();\n const processedValue = processTokenValue(effectiveValue);\n\n if (!result) result = {};\n result[`--${colorName}-color`] = processedValue;\n\n // Skip component generation for #current values (currentcolor is dynamic, cannot decompose)\n if (/^#current(?:\\.|$)/i.test(lowerValue)) {\n continue;\n }\n\n result[`--${colorName}-color-${suffix}`] = extractColorSpaceValue(\n originalValue,\n processedValue,\n );\n }\n }\n\n return result as CSSProperties | undefined;\n}\n\n/**\n * Stringify tokens for memoization key.\n */\nexport function stringifyTokens(tokens: Tokens | undefined): string {\n if (!tokens) return '';\n return JSON.stringify(tokens);\n}\n"],"mappings":";;;;;;;;;;AAgBA,SAAS,uBACP,YACA,cACQ;CACR,MAAM,SAAS,qBAAqB;CAGpC,MAAM,WAAW,aAAa,MAAM,8BAA8B;AAClE,KAAI,SACF,QAAO,SAAS,SAAS,GAAG,SAAS,OAAO;CAI9C,MAAM,aAAa,wBAAwB,WAAW;AACtD,KAAI,eAAe,WAAY,QAAO;CAEtC,MAAM,uBAAuB,wBAAwB,aAAa;AAClE,KAAI,yBAAyB,aAAc,QAAO;AAGlD,QAAO;;;;;;AAOT,SAAS,kBACP,OACwD;AACxD,KAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,MACrD,QAAO;AAGT,KAAI,OAAO,UAAU,UAAU;AAE3B,UAAQ,KACN,iIAED;AAEH,SAAO;;AAGT,QACE,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU;;;;;;AAQrB,SAAS,kBAAkB,OAAgC;AACzD,KAAI,OAAO,UAAU,UAAU;AAE7B,MAAI,UAAU,EACZ,QAAO;AAET,SAAO,WAAW,OAAO,MAAM,CAAC,CAAC;;AAEnC,QAAO,WAAW,MAAM,CAAC;;;;;;;;;;AAW3B,SAAgB,cACd,QAC2B;AAC3B,KAAI,CAAC,OACH;CAGF,MAAM,OAAO,OAAO,KAAK,OAAO;AAChC,KAAI,KAAK,WAAW,EAClB;CAGF,IAAI;AAEJ,MAAK,MAAM,OAAO,MAAM;EACtB,MAAM,QAAQ,OAAO;AAGrB,MAAI,CAAC,kBAAkB,MAAM,CAC3B;AAGF,MAAI,IAAI,WAAW,IAAI,EAAE;GAEvB,MAAM,WAAW,KAAK,IAAI,MAAM,EAAE;GAGlC,MAAM,iBAAiB,kBADA,UAAU,OAAO,KAAK,MACW;AAExD,OAAI,CAAC,OAAQ,UAAS,EAAE;AACxB,UAAO,YAAY;aACV,IAAI,WAAW,IAAI,EAAE;GAC9B,MAAM,YAAY,IAAI,MAAM,EAAE;GAC9B,MAAM,SAAS,qBAAqB;GAGpC,MAAM,iBAAiB,yBAAyB,MAAM;AAEtD,OAAI,mBAAmB,KAAM;GAE7B,MAAM,gBACJ,OAAO,mBAAmB,WACtB,OAAO,eAAe,GACtB;GACN,MAAM,aAAa,cAAc,aAAa;GAC9C,MAAM,iBAAiB,kBAAkB,eAAe;AAExD,OAAI,CAAC,OAAQ,UAAS,EAAE;AACxB,UAAO,KAAK,UAAU,WAAW;AAGjC,OAAI,qBAAqB,KAAK,WAAW,CACvC;AAGF,UAAO,KAAK,UAAU,SAAS,YAAY,uBACzC,eACA,eACD;;;AAIL,QAAO;;;;;AAMT,SAAgB,gBAAgB,QAAoC;AAClE,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,KAAK,UAAU,OAAO"}
@@ -1,7 +1,6 @@
1
1
  import { ProcessedStyle, StyleDetails } from "../parser/types.js";
2
2
  import { StyleParser } from "../parser/parser.js";
3
- import { AtRuleContext, ParsedAdvancedState, StateParserContext } from "../states/index.js";
4
- import { Styles } from "../styles/types.js";
3
+ import { getNamedColorHex, getRgbValuesFromRgbaString, hexToRgb, strToRgb } from "./color-math.js";
5
4
 
6
5
  //#region src/utils/styles.d.ts
7
6
  type StyleValue<T = string> = T | boolean | number | null | undefined;
@@ -21,7 +20,6 @@ type StyleValueStateMap<T = string> = Record<string, StyleValue<T> | '@inherit'>
21
20
  * Use this for component props that accept style values.
22
21
  */
23
22
  type StylePropValue<T = string> = StyleValue<T> | StyleValueStateMap<T>;
24
- type ComputeModel = string | number;
25
23
  type CSSMap = {
26
24
  $?: string | string[];
27
25
  } & Record<string, string | string[]>;
@@ -37,32 +35,12 @@ type StyleHandler = RawStyleHandler & {
37
35
  * - Multi-property tuple: [['style1', 'style2'], handler]
38
36
  */
39
37
  type StyleHandlerDefinition = RawStyleHandler | [string, RawStyleHandler] | [string[], RawStyleHandler];
40
- interface StyleStateData {
41
- model?: ComputeModel;
42
- tokens?: string[];
43
- value: StyleValue | StyleValueStateMap | StyleStateData;
44
- /** The list of mods to apply */
45
- mods: string[];
46
- /** The list of **not** mods to apply (e.g. `:not(:hover)`) */
47
- notMods: string[];
48
- /** Advanced states (media queries, container queries, etc.) */
49
- advancedStates?: ParsedAdvancedState[];
50
- /** At-rule context for CSS generation */
51
- atRuleContext?: AtRuleContext;
52
- /** Own mods for sub-element states (from @own()) - applied to sub-element selector */
53
- ownMods?: string[];
54
- /** Negated own mods for sub-element states */
55
- negatedOwnMods?: string[];
56
- }
57
38
  interface ParsedColor {
58
39
  color?: string;
59
40
  name?: string;
60
41
  opacity?: number;
61
42
  }
62
- type StyleStateDataList = StyleStateData[];
63
- type StyleStateDataListMap = Record<string, StyleStateDataList>;
64
43
  type StyleMap = Record<string, StyleValue | StyleValueStateMap>;
65
- type StyleStateMap = Record<string, StyleStateData>;
66
44
  declare const CUSTOM_UNITS: {
67
45
  r: string;
68
46
  cr: string;
@@ -116,62 +94,8 @@ declare function parseStyle(value: StyleValue): ProcessedStyle;
116
94
  * Optimized to avoid heavy parseStyle calls for simple color patterns.
117
95
  */
118
96
  declare function parseColor(val: string, ignoreError?: boolean): ParsedColor;
119
- declare function strToRgb(color: string, _ignoreAlpha?: boolean): string | null | undefined;
120
- /**
121
- * Extract RGB values from an rgb()/rgba() string.
122
- * Supports all modern CSS syntax variations:
123
- * - Comma-separated: rgb(255, 128, 0)
124
- * - Space-separated: rgb(255 128 0)
125
- * - Fractional: rgb(128.5, 64.3, 32.1)
126
- * - Percentages: rgb(50%, 25%, 75%)
127
- * - Slash alpha notation: rgb(255 128 0 / 0.5)
128
- *
129
- * Returns array of RGB values (0-255 range), converting percentages as needed.
130
- */
131
- declare function getRgbValuesFromRgbaString(str: string): number[];
132
- declare function hexToRgb(hex: string): string | null;
133
97
  declare function filterMods(mods: string[], allowedMods: string[]): string[];
134
- declare function extendStyles(defaultStyles?: Record<string, unknown> | null, newStyles?: Record<string, unknown> | null): Record<string, unknown>;
135
- /**
136
- * Split properties into style and non-style properties.
137
- * @param props - Component prop map.
138
- * @param [styleList] - List of all style properties.
139
- * @param [defaultStyles] - Default style map of the component.
140
- * @param [propMap] - Props to style alias map.
141
- * @param [ignoreList] - A list of properties to ignore.
142
- */
143
- declare function extractStyles(props: Record<string, unknown>, styleList?: readonly string[], defaultStyles?: Styles, propMap?: Record<string, string>, ignoreList?: readonly string[]): Styles;
144
- /**
145
- * Check if a token is an advanced state (starts with @)
146
- */
147
- declare function isAdvancedStateToken(token: string): boolean;
148
- declare const STATE_OPERATORS: {
149
- NOT: string;
150
- AND: string;
151
- OR: string;
152
- XOR: string;
153
- };
154
- declare const STATE_OPERATOR_LIST: string[];
155
- declare const parseStateNotation: (firstArg: string, secondArg?: string | number | boolean | StyleValueStateMap<string> | StyleStateData | null | undefined) => StyleStateData;
156
- /**
157
- * Build an AtRuleContext from parsed advanced states
158
- */
159
- declare function buildAtRuleContext(advancedStates: ParsedAdvancedState[], negatedStates: Set<string>): AtRuleContext | undefined;
160
- /**
161
- * Parse state notation and return tokens, modifiers and compute model.
162
- * Enhanced to detect and extract advanced states.
163
- */
164
- declare function styleStateMapToStyleStateDataList(styleStateMap: StyleStateMap | StyleValue | StyleValueStateMap, parserContext?: StateParserContext): {
165
- states: StyleStateDataList;
166
- mods: string[];
167
- hasAdvancedStates: boolean;
168
- };
169
- declare const COMPUTE_FUNC_MAP: Record<string, (a: unknown, b?: unknown) => unknown>;
170
- /**
171
- * Compute a result based on a model and incoming map.
172
- */
173
- declare function computeState(computeModel: ComputeModel, valueMap: (number | boolean)[] | Record<string, boolean> | ((...args: unknown[]) => unknown)): unknown;
174
98
  declare function stringifyStyles(styles: unknown): string;
175
99
  //#endregion
176
- export { COMPUTE_FUNC_MAP, CSSMap, CUSTOM_UNITS, ComputeModel, DIRECTIONS, ParsedColor, RawStyleHandler, STATE_OPERATORS, STATE_OPERATOR_LIST, StyleHandler, StyleHandlerDefinition, StyleHandlerResult, StyleMap, StylePropValue, StyleStateData, StyleStateDataList, StyleStateDataListMap, StyleStateMap, StyleValue, StyleValueStateMap, buildAtRuleContext, computeState, customFunc, extendStyles, extractStyles, filterMods, getGlobalFuncs, getGlobalParser, getGlobalPredefinedTokens, getRgbValuesFromRgbaString, hexToRgb, isAdvancedStateToken, normalizeColorTokenValue, parseColor, parseStateNotation, parseStyle, resetGlobalPredefinedTokens, setGlobalPredefinedTokens, strToRgb, stringifyStyles, styleStateMapToStyleStateDataList };
100
+ export { CSSMap, CUSTOM_UNITS, DIRECTIONS, ParsedColor, RawStyleHandler, StyleHandler, StyleHandlerDefinition, StyleHandlerResult, StyleMap, StylePropValue, StyleValue, StyleValueStateMap, customFunc, filterMods, getGlobalFuncs, getGlobalParser, getGlobalPredefinedTokens, normalizeColorTokenValue, parseColor, parseStyle, resetGlobalPredefinedTokens, setGlobalPredefinedTokens, stringifyStyles };
177
101
  //# sourceMappingURL=styles.d.ts.map