@tenphi/tasty 0.0.0-snapshot.09c74e2

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 (243) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +539 -0
  3. package/dist/_virtual/_rolldown/runtime.js +8 -0
  4. package/dist/chunks/cacheKey.js +70 -0
  5. package/dist/chunks/cacheKey.js.map +1 -0
  6. package/dist/chunks/definitions.d.ts +37 -0
  7. package/dist/chunks/definitions.js +260 -0
  8. package/dist/chunks/definitions.js.map +1 -0
  9. package/dist/chunks/renderChunk.js +61 -0
  10. package/dist/chunks/renderChunk.js.map +1 -0
  11. package/dist/config.d.ts +280 -0
  12. package/dist/config.js +403 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/core/index.d.ts +33 -0
  15. package/dist/core/index.js +26 -0
  16. package/dist/debug.d.ts +204 -0
  17. package/dist/debug.js +733 -0
  18. package/dist/debug.js.map +1 -0
  19. package/dist/hooks/useGlobalStyles.d.ts +27 -0
  20. package/dist/hooks/useGlobalStyles.js +56 -0
  21. package/dist/hooks/useGlobalStyles.js.map +1 -0
  22. package/dist/hooks/useKeyframes.d.ts +56 -0
  23. package/dist/hooks/useKeyframes.js +54 -0
  24. package/dist/hooks/useKeyframes.js.map +1 -0
  25. package/dist/hooks/useProperty.d.ts +79 -0
  26. package/dist/hooks/useProperty.js +91 -0
  27. package/dist/hooks/useProperty.js.map +1 -0
  28. package/dist/hooks/useRawCSS.d.ts +53 -0
  29. package/dist/hooks/useRawCSS.js +28 -0
  30. package/dist/hooks/useRawCSS.js.map +1 -0
  31. package/dist/hooks/useStyles.d.ts +40 -0
  32. package/dist/hooks/useStyles.js +169 -0
  33. package/dist/hooks/useStyles.js.map +1 -0
  34. package/dist/index.d.ts +48 -0
  35. package/dist/index.js +33 -0
  36. package/dist/injector/index.d.ts +157 -0
  37. package/dist/injector/index.js +154 -0
  38. package/dist/injector/index.js.map +1 -0
  39. package/dist/injector/injector.d.ts +139 -0
  40. package/dist/injector/injector.js +404 -0
  41. package/dist/injector/injector.js.map +1 -0
  42. package/dist/injector/sheet-manager.d.ts +127 -0
  43. package/dist/injector/sheet-manager.js +714 -0
  44. package/dist/injector/sheet-manager.js.map +1 -0
  45. package/dist/injector/types.d.ts +135 -0
  46. package/dist/keyframes/index.js +206 -0
  47. package/dist/keyframes/index.js.map +1 -0
  48. package/dist/parser/classify.js +319 -0
  49. package/dist/parser/classify.js.map +1 -0
  50. package/dist/parser/const.js +33 -0
  51. package/dist/parser/const.js.map +1 -0
  52. package/dist/parser/lru.js +109 -0
  53. package/dist/parser/lru.js.map +1 -0
  54. package/dist/parser/parser.d.ts +25 -0
  55. package/dist/parser/parser.js +116 -0
  56. package/dist/parser/parser.js.map +1 -0
  57. package/dist/parser/tokenizer.js +69 -0
  58. package/dist/parser/tokenizer.js.map +1 -0
  59. package/dist/parser/types.d.ts +51 -0
  60. package/dist/parser/types.js +46 -0
  61. package/dist/parser/types.js.map +1 -0
  62. package/dist/pipeline/conditions.d.ts +134 -0
  63. package/dist/pipeline/conditions.js +406 -0
  64. package/dist/pipeline/conditions.js.map +1 -0
  65. package/dist/pipeline/exclusive.js +231 -0
  66. package/dist/pipeline/exclusive.js.map +1 -0
  67. package/dist/pipeline/index.d.ts +53 -0
  68. package/dist/pipeline/index.js +660 -0
  69. package/dist/pipeline/index.js.map +1 -0
  70. package/dist/pipeline/materialize.js +844 -0
  71. package/dist/pipeline/materialize.js.map +1 -0
  72. package/dist/pipeline/parseStateKey.d.ts +15 -0
  73. package/dist/pipeline/parseStateKey.js +438 -0
  74. package/dist/pipeline/parseStateKey.js.map +1 -0
  75. package/dist/pipeline/simplify.js +516 -0
  76. package/dist/pipeline/simplify.js.map +1 -0
  77. package/dist/pipeline/warnings.js +18 -0
  78. package/dist/pipeline/warnings.js.map +1 -0
  79. package/dist/plugins/okhsl-plugin.d.ts +35 -0
  80. package/dist/plugins/okhsl-plugin.js +371 -0
  81. package/dist/plugins/okhsl-plugin.js.map +1 -0
  82. package/dist/plugins/types.d.ts +69 -0
  83. package/dist/properties/index.js +158 -0
  84. package/dist/properties/index.js.map +1 -0
  85. package/dist/states/index.d.ts +49 -0
  86. package/dist/states/index.js +416 -0
  87. package/dist/states/index.js.map +1 -0
  88. package/dist/static/index.d.ts +5 -0
  89. package/dist/static/index.js +5 -0
  90. package/dist/static/tastyStatic.d.ts +46 -0
  91. package/dist/static/tastyStatic.js +31 -0
  92. package/dist/static/tastyStatic.js.map +1 -0
  93. package/dist/static/types.d.ts +49 -0
  94. package/dist/static/types.js +24 -0
  95. package/dist/static/types.js.map +1 -0
  96. package/dist/styles/align.d.ts +15 -0
  97. package/dist/styles/align.js +14 -0
  98. package/dist/styles/align.js.map +1 -0
  99. package/dist/styles/border.d.ts +25 -0
  100. package/dist/styles/border.js +114 -0
  101. package/dist/styles/border.js.map +1 -0
  102. package/dist/styles/color.d.ts +14 -0
  103. package/dist/styles/color.js +23 -0
  104. package/dist/styles/color.js.map +1 -0
  105. package/dist/styles/createStyle.js +77 -0
  106. package/dist/styles/createStyle.js.map +1 -0
  107. package/dist/styles/dimension.js +97 -0
  108. package/dist/styles/dimension.js.map +1 -0
  109. package/dist/styles/display.d.ts +37 -0
  110. package/dist/styles/display.js +67 -0
  111. package/dist/styles/display.js.map +1 -0
  112. package/dist/styles/fade.d.ts +15 -0
  113. package/dist/styles/fade.js +58 -0
  114. package/dist/styles/fade.js.map +1 -0
  115. package/dist/styles/fill.d.ts +42 -0
  116. package/dist/styles/fill.js +52 -0
  117. package/dist/styles/fill.js.map +1 -0
  118. package/dist/styles/flow.d.ts +16 -0
  119. package/dist/styles/flow.js +12 -0
  120. package/dist/styles/flow.js.map +1 -0
  121. package/dist/styles/gap.d.ts +31 -0
  122. package/dist/styles/gap.js +37 -0
  123. package/dist/styles/gap.js.map +1 -0
  124. package/dist/styles/height.d.ts +17 -0
  125. package/dist/styles/height.js +20 -0
  126. package/dist/styles/height.js.map +1 -0
  127. package/dist/styles/index.d.ts +2 -0
  128. package/dist/styles/index.js +9 -0
  129. package/dist/styles/index.js.map +1 -0
  130. package/dist/styles/inset.d.ts +52 -0
  131. package/dist/styles/inset.js +150 -0
  132. package/dist/styles/inset.js.map +1 -0
  133. package/dist/styles/justify.d.ts +15 -0
  134. package/dist/styles/justify.js +14 -0
  135. package/dist/styles/justify.js.map +1 -0
  136. package/dist/styles/list.d.ts +16 -0
  137. package/dist/styles/list.js +98 -0
  138. package/dist/styles/list.js.map +1 -0
  139. package/dist/styles/margin.d.ts +24 -0
  140. package/dist/styles/margin.js +104 -0
  141. package/dist/styles/margin.js.map +1 -0
  142. package/dist/styles/outline.d.ts +29 -0
  143. package/dist/styles/outline.js +65 -0
  144. package/dist/styles/outline.js.map +1 -0
  145. package/dist/styles/padding.d.ts +24 -0
  146. package/dist/styles/padding.js +104 -0
  147. package/dist/styles/padding.js.map +1 -0
  148. package/dist/styles/predefined.d.ts +73 -0
  149. package/dist/styles/predefined.js +241 -0
  150. package/dist/styles/predefined.js.map +1 -0
  151. package/dist/styles/preset.d.ts +47 -0
  152. package/dist/styles/preset.js +126 -0
  153. package/dist/styles/preset.js.map +1 -0
  154. package/dist/styles/radius.d.ts +14 -0
  155. package/dist/styles/radius.js +51 -0
  156. package/dist/styles/radius.js.map +1 -0
  157. package/dist/styles/scrollbar.d.ts +21 -0
  158. package/dist/styles/scrollbar.js +112 -0
  159. package/dist/styles/scrollbar.js.map +1 -0
  160. package/dist/styles/shadow.d.ts +14 -0
  161. package/dist/styles/shadow.js +24 -0
  162. package/dist/styles/shadow.js.map +1 -0
  163. package/dist/styles/styledScrollbar.d.ts +47 -0
  164. package/dist/styles/styledScrollbar.js +38 -0
  165. package/dist/styles/styledScrollbar.js.map +1 -0
  166. package/dist/styles/transition.d.ts +14 -0
  167. package/dist/styles/transition.js +158 -0
  168. package/dist/styles/transition.js.map +1 -0
  169. package/dist/styles/types.d.ts +498 -0
  170. package/dist/styles/width.d.ts +17 -0
  171. package/dist/styles/width.js +20 -0
  172. package/dist/styles/width.js.map +1 -0
  173. package/dist/tasty.d.ts +982 -0
  174. package/dist/tasty.js +206 -0
  175. package/dist/tasty.js.map +1 -0
  176. package/dist/tokens/typography.d.ts +19 -0
  177. package/dist/tokens/typography.js +237 -0
  178. package/dist/tokens/typography.js.map +1 -0
  179. package/dist/types.d.ts +184 -0
  180. package/dist/utils/cache-wrapper.js +26 -0
  181. package/dist/utils/cache-wrapper.js.map +1 -0
  182. package/dist/utils/case-converter.js +8 -0
  183. package/dist/utils/case-converter.js.map +1 -0
  184. package/dist/utils/colors.d.ts +5 -0
  185. package/dist/utils/colors.js +9 -0
  186. package/dist/utils/colors.js.map +1 -0
  187. package/dist/utils/css-types.d.ts +7 -0
  188. package/dist/utils/dotize.d.ts +26 -0
  189. package/dist/utils/dotize.js +122 -0
  190. package/dist/utils/dotize.js.map +1 -0
  191. package/dist/utils/filter-base-props.d.ts +15 -0
  192. package/dist/utils/filter-base-props.js +45 -0
  193. package/dist/utils/filter-base-props.js.map +1 -0
  194. package/dist/utils/get-display-name.d.ts +7 -0
  195. package/dist/utils/get-display-name.js +10 -0
  196. package/dist/utils/get-display-name.js.map +1 -0
  197. package/dist/utils/hsl-to-rgb.js +38 -0
  198. package/dist/utils/hsl-to-rgb.js.map +1 -0
  199. package/dist/utils/is-dev-env.js +19 -0
  200. package/dist/utils/is-dev-env.js.map +1 -0
  201. package/dist/utils/is-valid-element-type.js +15 -0
  202. package/dist/utils/is-valid-element-type.js.map +1 -0
  203. package/dist/utils/merge-styles.d.ts +7 -0
  204. package/dist/utils/merge-styles.js +146 -0
  205. package/dist/utils/merge-styles.js.map +1 -0
  206. package/dist/utils/mod-attrs.d.ts +8 -0
  207. package/dist/utils/mod-attrs.js +21 -0
  208. package/dist/utils/mod-attrs.js.map +1 -0
  209. package/dist/utils/okhsl-to-rgb.js +296 -0
  210. package/dist/utils/okhsl-to-rgb.js.map +1 -0
  211. package/dist/utils/process-tokens.d.ts +31 -0
  212. package/dist/utils/process-tokens.js +171 -0
  213. package/dist/utils/process-tokens.js.map +1 -0
  214. package/dist/utils/resolve-recipes.d.ts +17 -0
  215. package/dist/utils/resolve-recipes.js +147 -0
  216. package/dist/utils/resolve-recipes.js.map +1 -0
  217. package/dist/utils/string.js +8 -0
  218. package/dist/utils/string.js.map +1 -0
  219. package/dist/utils/styles.d.ts +178 -0
  220. package/dist/utils/styles.js +590 -0
  221. package/dist/utils/styles.js.map +1 -0
  222. package/dist/utils/typography.d.ts +36 -0
  223. package/dist/utils/typography.js +53 -0
  224. package/dist/utils/typography.js.map +1 -0
  225. package/dist/utils/warnings.d.ts +16 -0
  226. package/dist/utils/warnings.js +16 -0
  227. package/dist/utils/warnings.js.map +1 -0
  228. package/dist/zero/babel.d.ts +108 -0
  229. package/dist/zero/babel.js +282 -0
  230. package/dist/zero/babel.js.map +1 -0
  231. package/dist/zero/css-writer.d.ts +45 -0
  232. package/dist/zero/css-writer.js +74 -0
  233. package/dist/zero/css-writer.js.map +1 -0
  234. package/dist/zero/extractor.d.ts +24 -0
  235. package/dist/zero/extractor.js +150 -0
  236. package/dist/zero/extractor.js.map +1 -0
  237. package/dist/zero/index.d.ts +3 -0
  238. package/dist/zero/index.js +4 -0
  239. package/dist/zero/next.d.ts +60 -0
  240. package/dist/zero/next.js +78 -0
  241. package/dist/zero/next.js.map +1 -0
  242. package/package.json +189 -0
  243. package/tasty.config.ts +14 -0
@@ -0,0 +1,590 @@
1
+ import { StyleParser } from "../parser/parser.js";
2
+ import { okhslFunc } from "../plugins/okhsl-plugin.js";
3
+ import { createStateParserContext, parseAdvancedState } from "../states/index.js";
4
+ import { cacheWrapper } from "./cache-wrapper.js";
5
+ import { camelToKebab } from "./case-converter.js";
6
+ import { okhslToRgb } from "./okhsl-to-rgb.js";
7
+ import { hslToRgb } from "./hsl-to-rgb.js";
8
+
9
+ //#region src/utils/styles.ts
10
+ /**
11
+ * Normalize a color token value.
12
+ * - Boolean `true` is converted to `'transparent'`
13
+ * - Boolean `false` returns `null` (signals the token should be skipped)
14
+ * - Other values are returned as-is
15
+ *
16
+ * @param value - The raw token value
17
+ * @returns Normalized value or null if the token should be skipped
18
+ */
19
+ function normalizeColorTokenValue(value) {
20
+ if (value === true) return "transparent";
21
+ if (value === false) return null;
22
+ return value;
23
+ }
24
+ const COLOR_VAR_PATTERN = /var\(--([a-z0-9-]+)-color/;
25
+ const COLOR_VAR_RGB_PATTERN = /var\(--([a-z0-9-]+)-color-rgb/;
26
+ const RGB_ALPHA_PATTERN = /\/\s*([0-9.]+)\)/;
27
+ const SIMPLE_COLOR_PATTERNS = [
28
+ /^#[0-9a-fA-F]{3,8}$/,
29
+ /^rgb\(/,
30
+ /^hsl\(/,
31
+ /^lch\(/,
32
+ /^oklch\(/,
33
+ /^okhsl\(/,
34
+ /^var\(--[a-z0-9-]+-color/,
35
+ /^currentColor$/,
36
+ /^transparent$/
37
+ ];
38
+ let colorWarningCount = 0;
39
+ const MAX_COLOR_WARNINGS = 10;
40
+ const CUSTOM_UNITS = {
41
+ r: "6px",
42
+ cr: "10px",
43
+ bw: "1px",
44
+ ow: "3px",
45
+ x: "8px",
46
+ fs: "var(--font-size)",
47
+ lh: "var(--line-height)",
48
+ sf: function sf(num) {
49
+ return `minmax(0, ${num}fr)`;
50
+ }
51
+ };
52
+ const DIRECTIONS = [
53
+ "top",
54
+ "right",
55
+ "bottom",
56
+ "left"
57
+ ];
58
+ const MOD_NAME_CACHE = /* @__PURE__ */ new Map();
59
+ function getModSelector(modName) {
60
+ if (!MOD_NAME_CACHE.has(modName)) {
61
+ let selector;
62
+ const valueModMatch = modName.match(/^([a-z][a-z0-9-]*)(\^=|\$=|\*=|=)(.+)$/i);
63
+ if (valueModMatch) {
64
+ const key = valueModMatch[1];
65
+ const operator = valueModMatch[2];
66
+ let value = valueModMatch[3];
67
+ if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
68
+ selector = `[data-${camelToKebab(key)}${operator}"${value}"]`;
69
+ } else if (modName.match(/^[a-z]/)) selector = `[data-${camelToKebab(modName)}]`;
70
+ else if (modName.includes(":has(")) selector = modName.replace(/:has\(([^)]+)\)/g, (match, content) => {
71
+ if (/[A-Z][a-z]*[>+~]|[>+~][A-Z][a-z]*/.test(content)) console.error(`[Tasty] Invalid :has() selector syntax: "${modName}"\nCombinators (>, +, ~) must have spaces around them when used with element names.\nExample: Use ":has(Body > Row)" instead of ":has(Body>Row)"\nThis is a design choice: the parser uses simple whitespace splitting for performance.`);
72
+ return `:has(${content.split(/\s+/).map((token) => /^[A-Z]/.test(token) ? `[data-element="${token}"]` : token).join(" ")})`;
73
+ });
74
+ else selector = modName;
75
+ MOD_NAME_CACHE.set(modName, selector);
76
+ }
77
+ return MOD_NAME_CACHE.get(modName);
78
+ }
79
+ let __tastyParser = null;
80
+ function getOrCreateParser() {
81
+ if (!__tastyParser) {
82
+ __tastyParser = new StyleParser({ units: CUSTOM_UNITS });
83
+ __tastyParser.setFuncs(__tastyFuncs);
84
+ }
85
+ return __tastyParser;
86
+ }
87
+ const __tastyFuncs = { okhsl: okhslFunc };
88
+ function customFunc(name, fn) {
89
+ __tastyFuncs[name] = fn;
90
+ getOrCreateParser().setFuncs(__tastyFuncs);
91
+ }
92
+ /**
93
+ * Get the global StyleParser instance.
94
+ * Used by configure() to apply parser configuration.
95
+ */
96
+ function getGlobalParser() {
97
+ return getOrCreateParser();
98
+ }
99
+ /**
100
+ * Get the current custom functions registry.
101
+ * Used by configure() to merge with new functions.
102
+ */
103
+ function getGlobalFuncs() {
104
+ return __tastyFuncs;
105
+ }
106
+ /**
107
+ * Storage for predefined tokens that are replaced during style parsing.
108
+ * Keys are token names (with $ or # prefix), values are pre-processed CSS values.
109
+ */
110
+ let __globalPredefinedTokens = null;
111
+ /**
112
+ * Set global predefined tokens.
113
+ * Called from configure() after processing token values.
114
+ * Merges with existing tokens (new tokens override existing ones with same key).
115
+ * Keys are normalized to lowercase (parser lowercases input before classification).
116
+ * @internal
117
+ */
118
+ function setGlobalPredefinedTokens(tokens) {
119
+ const normalizedTokens = {};
120
+ for (const [key, value] of Object.entries(tokens)) {
121
+ const lowerKey = key.toLowerCase();
122
+ const lowerValue = value.toLowerCase();
123
+ if (lowerKey.startsWith("#") && lowerValue === "#current") {
124
+ console.warn(`Tasty: Using #current to define color token "${key}" is not supported. The #current token represents currentcolor which cannot be used as a base for other tokens.`);
125
+ continue;
126
+ }
127
+ normalizedTokens[lowerKey] = value;
128
+ }
129
+ __globalPredefinedTokens = __globalPredefinedTokens ? {
130
+ ...__globalPredefinedTokens,
131
+ ...normalizedTokens
132
+ } : normalizedTokens;
133
+ getOrCreateParser().clearCache();
134
+ }
135
+ /**
136
+ * Get the current global predefined tokens.
137
+ * Returns null if no tokens are configured.
138
+ */
139
+ function getGlobalPredefinedTokens() {
140
+ return __globalPredefinedTokens;
141
+ }
142
+ /**
143
+ * Reset global predefined tokens.
144
+ * Used for testing.
145
+ * @internal
146
+ */
147
+ function resetGlobalPredefinedTokens() {
148
+ __globalPredefinedTokens = null;
149
+ getOrCreateParser().clearCache();
150
+ }
151
+ /**
152
+ *
153
+ * @param {String} value
154
+ * @param {Number} mode
155
+ * @returns {Object<String,String|Array>}
156
+ */
157
+ function parseStyle(value) {
158
+ let str;
159
+ if (typeof value === "string") str = value;
160
+ else if (typeof value === "number") str = String(value);
161
+ else str = "";
162
+ return getOrCreateParser().process(str);
163
+ }
164
+ /**
165
+ * Parse color. Find it value, name and opacity.
166
+ * Optimized to avoid heavy parseStyle calls for simple color patterns.
167
+ */
168
+ function parseColor(val, ignoreError = false) {
169
+ if (typeof val !== "string") val = String(val ?? "");
170
+ val = val.trim();
171
+ if (!val) return {};
172
+ const isSimpleColor = SIMPLE_COLOR_PATTERNS.some((pattern) => pattern.test(val));
173
+ let firstColor;
174
+ if (isSimpleColor) firstColor = val;
175
+ else {
176
+ const extractedColor = parseStyle(val).groups.find((g) => g.colors.length)?.colors[0];
177
+ if (!extractedColor) {
178
+ if (!ignoreError && colorWarningCount < MAX_COLOR_WARNINGS) {
179
+ console.warn("CubeUIKit: unable to parse color:", val);
180
+ colorWarningCount++;
181
+ if (colorWarningCount === MAX_COLOR_WARNINGS) console.warn("CubeUIKit: color parsing warnings will be suppressed from now on");
182
+ }
183
+ return {};
184
+ }
185
+ firstColor = extractedColor;
186
+ }
187
+ let nameMatch = firstColor.match(COLOR_VAR_PATTERN);
188
+ if (!nameMatch) nameMatch = firstColor.match(COLOR_VAR_RGB_PATTERN);
189
+ let opacity;
190
+ if (firstColor.startsWith("rgb") || firstColor.startsWith("hsl") || firstColor.startsWith("lch") || firstColor.startsWith("oklch") || firstColor.startsWith("okhsl")) {
191
+ const alphaMatch = firstColor.match(RGB_ALPHA_PATTERN);
192
+ if (alphaMatch) {
193
+ const v = parseFloat(alphaMatch[1]);
194
+ if (!isNaN(v)) opacity = v * 100;
195
+ }
196
+ }
197
+ return {
198
+ color: firstColor,
199
+ name: nameMatch ? nameMatch[1] : void 0,
200
+ opacity
201
+ };
202
+ }
203
+ function strToRgb(color, _ignoreAlpha = false) {
204
+ if (!color) return void 0;
205
+ if (color.startsWith("rgb")) return color;
206
+ if (color.startsWith("#")) return hexToRgb(color);
207
+ if (color.startsWith("okhsl(")) return okhslToRgb(color);
208
+ if (color.startsWith("hsl")) return hslToRgb(color);
209
+ return null;
210
+ }
211
+ /**
212
+ * Extract RGB values from an rgb()/rgba() string.
213
+ * Supports all modern CSS syntax variations:
214
+ * - Comma-separated: rgb(255, 128, 0)
215
+ * - Space-separated: rgb(255 128 0)
216
+ * - Fractional: rgb(128.5, 64.3, 32.1)
217
+ * - Percentages: rgb(50%, 25%, 75%)
218
+ * - Slash alpha notation: rgb(255 128 0 / 0.5)
219
+ *
220
+ * Returns array of RGB values (0-255 range), converting percentages as needed.
221
+ */
222
+ function getRgbValuesFromRgbaString(str) {
223
+ const match = str.match(/rgba?\(([^)]+)\)/i);
224
+ if (!match) return [];
225
+ const [colorPart] = match[1].trim().split("/");
226
+ return colorPart.trim().split(/[,\s]+/).filter(Boolean).slice(0, 3).map((part) => {
227
+ part = part.trim();
228
+ if (part.endsWith("%")) return parseFloat(part) / 100 * 255;
229
+ return parseFloat(part);
230
+ });
231
+ }
232
+ function hexToRgb(hex) {
233
+ const matched = hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (_m, r, g, b) => "#" + r + r + g + g + b + b).substring(1).match(/.{2}/g);
234
+ if (!matched) return null;
235
+ const rgba = matched.map((x, i) => parseInt(x, 16) * (i === 3 ? 1 / 255 : 1));
236
+ if (rgba.some((v) => Number.isNaN(v))) return null;
237
+ if (rgba.length >= 3) return `rgb(${rgba.slice(0, 3).join(" ")}${rgba.length > 3 ? ` / ${rgba[3]}` : ""})`;
238
+ return null;
239
+ }
240
+ function filterMods(mods, allowedMods) {
241
+ return mods.filter((mod) => allowedMods.includes(mod));
242
+ }
243
+ function extendStyles(defaultStyles, newStyles) {
244
+ let styles = {};
245
+ if (!defaultStyles) {
246
+ if (!newStyles) return styles;
247
+ } else styles = Object.assign({}, defaultStyles);
248
+ if (newStyles) Object.keys(newStyles).forEach((key) => {
249
+ if (newStyles[key] != null) styles[key] = newStyles[key];
250
+ });
251
+ return styles;
252
+ }
253
+ /**
254
+ * Split properties into style and non-style properties.
255
+ * @param props - Component prop map.
256
+ * @param [styleList] - List of all style properties.
257
+ * @param [defaultStyles] - Default style map of the component.
258
+ * @param [propMap] - Props to style alias map.
259
+ * @param [ignoreList] - A list of properties to ignore.
260
+ */
261
+ function extractStyles(props, styleList = [], defaultStyles, propMap, ignoreList = []) {
262
+ const styles = {
263
+ ...defaultStyles,
264
+ ...ignoreList.includes("styles") ? void 0 : props.styles && typeof props.styles === "object" ? props.styles : void 0
265
+ };
266
+ Object.keys(props).forEach((prop) => {
267
+ const propName = propMap ? propMap[prop] || prop : prop;
268
+ const value = props[prop];
269
+ if (ignoreList && ignoreList.includes(prop)) {} else if (styleList.includes(propName)) styles[propName] = value;
270
+ }, {});
271
+ return styles;
272
+ }
273
+ const STATES_REGEXP = /([&|!^])|([()])|(@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;
274
+ /**
275
+ * Check if a token is an advanced state (starts with @)
276
+ */
277
+ function isAdvancedStateToken(token) {
278
+ return token.startsWith("@") || token.startsWith("!@");
279
+ }
280
+ const STATE_OPERATORS = {
281
+ NOT: "!",
282
+ AND: "&",
283
+ OR: "|",
284
+ XOR: "^"
285
+ };
286
+ const STATE_OPERATOR_LIST = [
287
+ "!",
288
+ "&",
289
+ "|",
290
+ "^"
291
+ ];
292
+ /**
293
+ * Convert state notation tokens to a compute model (string, or nested [op, lhs, rhs]).
294
+ */
295
+ function convertTokensToComputeUnits(tokens) {
296
+ if (tokens.length === 1) return tokens[0];
297
+ const hasLength = (x) => typeof x === "string" || Array.isArray(x);
298
+ STATE_OPERATOR_LIST.forEach((operator) => {
299
+ let i;
300
+ while ((i = tokens.indexOf(operator)) !== -1) {
301
+ const token = tokens[i];
302
+ if (token === "!") {
303
+ const next = tokens[i + 1];
304
+ if (next !== void 0 && hasLength(next) && next.length !== 1) tokens.splice(i, 2, ["!", next]);
305
+ else tokens.splice(i, 1);
306
+ } else {
307
+ const prev = tokens[i - 1];
308
+ const next = tokens[i + 1];
309
+ if (prev !== void 0 && next !== void 0 && hasLength(prev) && hasLength(next) && prev.length !== 1 && next.length !== 1) tokens.splice(i - 1, 3, [
310
+ token,
311
+ prev,
312
+ next
313
+ ]);
314
+ else tokens.splice(i, 1);
315
+ }
316
+ }
317
+ });
318
+ return tokens.length === 1 ? tokens[0] : tokens;
319
+ }
320
+ /**
321
+ * Replace commas with | only outside of parentheses.
322
+ * This preserves commas in advanced states like @(card, w < 600px)
323
+ */
324
+ function replaceCommasOutsideParens(str) {
325
+ let result = "";
326
+ let depth = 0;
327
+ for (const char of str) if (char === "(") {
328
+ depth++;
329
+ result += char;
330
+ } else if (char === ")") {
331
+ depth--;
332
+ result += char;
333
+ } else if (char === "," && depth === 0) result += "|";
334
+ else result += char;
335
+ return result;
336
+ }
337
+ /**
338
+ * Parse state notation and return tokens, modifiers and compute model.
339
+ */
340
+ function parseStateNotationInner(notation, value) {
341
+ const tokens = replaceCommasOutsideParens(notation).match(STATES_REGEXP);
342
+ if (!tokens || !tokens.length) return {
343
+ model: void 0,
344
+ mods: [],
345
+ notMods: [],
346
+ tokens: [],
347
+ value
348
+ };
349
+ else if (tokens.length === 1) return {
350
+ model: tokens[0],
351
+ mods: tokens.slice(0),
352
+ notMods: [],
353
+ tokens,
354
+ value
355
+ };
356
+ const mods = [];
357
+ const operations = [[]];
358
+ let list = operations[0];
359
+ let position = 0;
360
+ let operation;
361
+ tokens.forEach((token) => {
362
+ switch (token) {
363
+ case "(":
364
+ operation = [];
365
+ position++;
366
+ list = operations[position] = operation;
367
+ break;
368
+ case ")":
369
+ position--;
370
+ operations[position].push(convertTokensToComputeUnits(list));
371
+ list = operations[position];
372
+ break;
373
+ default:
374
+ if (token.length > 1) {
375
+ if (!mods.includes(token)) mods.push(token);
376
+ }
377
+ list.push(token);
378
+ }
379
+ });
380
+ while (position) {
381
+ position--;
382
+ operations[position].push(convertTokensToComputeUnits(list));
383
+ list = operations[position];
384
+ }
385
+ return {
386
+ tokens,
387
+ mods,
388
+ notMods: [],
389
+ model: convertTokensToComputeUnits(operations[0]),
390
+ value
391
+ };
392
+ }
393
+ const parseStateNotation = cacheWrapper(parseStateNotationInner);
394
+ /**
395
+ * Build an AtRuleContext from parsed advanced states
396
+ */
397
+ function buildAtRuleContext(advancedStates, negatedStates) {
398
+ if (advancedStates.length === 0) return void 0;
399
+ const ctx = {};
400
+ for (const state of advancedStates) {
401
+ const isNegated = negatedStates.has(state.raw);
402
+ switch (state.type) {
403
+ case "media": {
404
+ if (!ctx.media) ctx.media = [];
405
+ let mediaCondition = "";
406
+ if (state.mediaType) mediaCondition = state.mediaType;
407
+ else if (state.condition) mediaCondition = `(${state.condition})`;
408
+ if (mediaCondition) if (isNegated) ctx.media.push(`not ${mediaCondition}`);
409
+ else ctx.media.push(mediaCondition);
410
+ break;
411
+ }
412
+ case "container": {
413
+ if (!ctx.container) ctx.container = [];
414
+ let condition = state.condition;
415
+ if (isNegated) condition = `not (${condition})`;
416
+ ctx.container.push({
417
+ name: state.containerName,
418
+ condition
419
+ });
420
+ break;
421
+ }
422
+ case "root": {
423
+ if (!ctx.rootStates) ctx.rootStates = [];
424
+ const rootSelector = buildRootSelector(state.condition, isNegated);
425
+ ctx.rootStates.push(rootSelector);
426
+ break;
427
+ }
428
+ case "starting":
429
+ if (!isNegated) ctx.startingStyle = true;
430
+ break;
431
+ }
432
+ }
433
+ if (!ctx.media?.length && !ctx.container?.length && !ctx.rootStates?.length && !ctx.startingStyle) return;
434
+ return ctx;
435
+ }
436
+ /**
437
+ * Build a root state selector from a condition
438
+ */
439
+ function buildRootSelector(condition, isNegated) {
440
+ let selector;
441
+ if (condition.startsWith(".")) selector = condition;
442
+ else if (condition.startsWith("[")) selector = condition;
443
+ else if (condition.includes("=")) {
444
+ const [key, value] = condition.split("=");
445
+ selector = `[data-${camelToKebab(key.trim())}="${value.trim()}"]`;
446
+ } else selector = `[data-${camelToKebab(condition)}]`;
447
+ if (isNegated) return `:not(${selector})`;
448
+ return selector;
449
+ }
450
+ /**
451
+ * Parse state notation and return tokens, modifiers and compute model.
452
+ * Enhanced to detect and extract advanced states.
453
+ */
454
+ function styleStateMapToStyleStateDataList(styleStateMap, parserContext) {
455
+ if (typeof styleStateMap !== "object" || !styleStateMap) return {
456
+ states: [{
457
+ model: void 0,
458
+ mods: [],
459
+ notMods: [],
460
+ value: styleStateMap
461
+ }],
462
+ mods: [],
463
+ hasAdvancedStates: false
464
+ };
465
+ const stateDataList = [];
466
+ let hasAdvancedStates = false;
467
+ Object.keys(styleStateMap).forEach((stateNotation) => {
468
+ const state = parseStateNotation(stateNotation, styleStateMap[stateNotation]);
469
+ const advancedStates = [];
470
+ const negatedAdvancedStates = /* @__PURE__ */ new Set();
471
+ const regularMods = [];
472
+ const ownMods = [];
473
+ const negatedOwnMods = [];
474
+ if (state.tokens) {
475
+ let isNegated = false;
476
+ for (const token of state.tokens) {
477
+ if (token === "!") {
478
+ isNegated = true;
479
+ continue;
480
+ }
481
+ if (isAdvancedStateToken(token)) {
482
+ hasAdvancedStates = true;
483
+ const parsed = parseAdvancedState(token, parserContext || createStateParserContext(void 0));
484
+ advancedStates.push(parsed);
485
+ if (parsed.type === "own" && parsed.condition) if (isNegated) negatedOwnMods.push(parsed.condition);
486
+ else ownMods.push(parsed.condition);
487
+ else if (isNegated) negatedAdvancedStates.add(token);
488
+ isNegated = false;
489
+ } else if (token.length > 1 && ![
490
+ "&",
491
+ "|",
492
+ "^",
493
+ "(",
494
+ ")"
495
+ ].includes(token)) {
496
+ regularMods.push(token);
497
+ isNegated = false;
498
+ } else isNegated = false;
499
+ }
500
+ }
501
+ if (advancedStates.length > 0) {
502
+ state.advancedStates = advancedStates;
503
+ state.atRuleContext = buildAtRuleContext(advancedStates, negatedAdvancedStates);
504
+ state.mods = regularMods;
505
+ }
506
+ if (ownMods.length > 0) state.ownMods = ownMods;
507
+ if (negatedOwnMods.length > 0) state.negatedOwnMods = negatedOwnMods;
508
+ stateDataList.push(state);
509
+ });
510
+ stateDataList.reverse();
511
+ let initialState;
512
+ const allMods = stateDataList.reduce((all, state) => {
513
+ if (!state.mods.length && !state.advancedStates?.length) initialState = state;
514
+ else state.mods.forEach((mod) => {
515
+ if (!all.includes(mod)) all.push(mod);
516
+ });
517
+ return all;
518
+ }, []);
519
+ if (!initialState) stateDataList.push({
520
+ mods: [],
521
+ notMods: allMods,
522
+ value: true
523
+ });
524
+ return {
525
+ states: stateDataList,
526
+ mods: allMods,
527
+ hasAdvancedStates
528
+ };
529
+ }
530
+ const COMPUTE_FUNC_MAP = {
531
+ "!": (a) => !a,
532
+ "^": (a, b) => a && !b || !a && b,
533
+ "|": (a, b) => a || b,
534
+ "&": (a, b) => a && b
535
+ };
536
+ /**
537
+ * Compute a result based on a model and incoming map.
538
+ */
539
+ function computeState(computeModel, valueMap) {
540
+ if (!computeModel) return true;
541
+ const map = valueMap;
542
+ if (!Array.isArray(computeModel)) if (typeof valueMap === "function") return !!valueMap(computeModel);
543
+ else return !!map[computeModel];
544
+ const func = COMPUTE_FUNC_MAP[computeModel[0]];
545
+ if (!func) console.warn("CubeUIKit: unexpected compute method in the model", computeModel);
546
+ let a = computeModel[1];
547
+ if (typeof a === "object") a = !!computeState(a, valueMap);
548
+ else if (typeof valueMap === "function") a = !!valueMap(a);
549
+ else a = !!map[a];
550
+ if (computeModel.length === 2) return func(a);
551
+ let b = computeModel[2];
552
+ if (typeof b === "object") b = !!computeState(b, valueMap);
553
+ else if (typeof valueMap === "function") b = !!valueMap(b);
554
+ else b = !!map[b];
555
+ return !!func(a, b);
556
+ }
557
+ const _innerCache = /* @__PURE__ */ new WeakMap();
558
+ function stringifyStyles(styles) {
559
+ if (styles == null || typeof styles !== "object") return "";
560
+ const obj = styles;
561
+ const keys = Object.keys(obj).sort();
562
+ const parts = [];
563
+ for (const k of keys) {
564
+ const v = obj[k];
565
+ if (v === void 0 || typeof v === "function" || typeof v === "symbol") continue;
566
+ const c0 = k.charCodeAt(0);
567
+ const needsInnerSort = (c0 >= 65 && c0 <= 90 || c0 === 38) && v && typeof v === "object" && !Array.isArray(v);
568
+ let sv;
569
+ if (needsInnerSort) {
570
+ sv = _innerCache.get(v);
571
+ if (sv === void 0) {
572
+ const innerObj = v;
573
+ const innerKeys = Object.keys(innerObj).sort();
574
+ const innerParts = [];
575
+ for (const ik of innerKeys) {
576
+ const ivs = JSON.stringify(innerObj[ik]);
577
+ if (ivs !== void 0) innerParts.push(JSON.stringify(ik) + ":" + ivs);
578
+ }
579
+ sv = "{" + innerParts.join(",") + "}";
580
+ _innerCache.set(v, sv);
581
+ }
582
+ } else sv = JSON.stringify(v);
583
+ parts.push(JSON.stringify(k) + ":" + sv);
584
+ }
585
+ return "{" + parts.join(",") + "}";
586
+ }
587
+
588
+ //#endregion
589
+ export { COMPUTE_FUNC_MAP, CUSTOM_UNITS, DIRECTIONS, STATE_OPERATORS, STATE_OPERATOR_LIST, buildAtRuleContext, computeState, customFunc, extendStyles, extractStyles, filterMods, getGlobalFuncs, getGlobalParser, getGlobalPredefinedTokens, getModSelector, getRgbValuesFromRgbaString, hexToRgb, isAdvancedStateToken, normalizeColorTokenValue, parseColor, parseStateNotation, parseStyle, resetGlobalPredefinedTokens, setGlobalPredefinedTokens, strToRgb, stringifyStyles, styleStateMapToStyleStateDataList };
590
+ //# sourceMappingURL=styles.js.map