@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,10 +1,6 @@
1
+ import { getNamedColorHex, getRgbValuesFromRgbaString, hexToRgb, strToRgb } from "./color-math.js";
1
2
  import { StyleParser } from "../parser/parser.js";
2
3
  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
4
 
9
5
  //#region src/utils/styles.ts
10
6
  /**
@@ -22,19 +18,23 @@ function normalizeColorTokenValue(value) {
22
18
  return value;
23
19
  }
24
20
  const COLOR_VAR_PATTERN = /var\(--([a-z0-9-]+)-color/;
25
- const COLOR_VAR_RGB_PATTERN = /var\(--([a-z0-9-]+)-color-rgb/;
21
+ const COLOR_VAR_COMPONENTS_PATTERN = /var\(--([a-z0-9-]+)-color-(?:rgb|hsl|oklch)/;
26
22
  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
- ];
23
+ const RE_HEX_COLOR = /^#[0-9a-fA-F]{3,8}$/;
24
+ const RE_VAR_COLOR = /^var\(--[a-z0-9-]+-color/;
25
+ function isSimpleColorFast(val) {
26
+ switch (val.charCodeAt(0)) {
27
+ case 35: return RE_HEX_COLOR.test(val);
28
+ case 114: return val.charCodeAt(1) === 103 && val.charCodeAt(2) === 98;
29
+ case 104: return val.charCodeAt(1) === 115 && val.charCodeAt(2) === 108;
30
+ case 108: return val.charCodeAt(1) === 99 && val.charCodeAt(2) === 104;
31
+ case 111: return val.startsWith("oklch(") || val.startsWith("okhsl(");
32
+ case 118: return RE_VAR_COLOR.test(val);
33
+ case 99: return val === "currentColor" || val === "currentcolor";
34
+ case 116: return val === "transparent";
35
+ default: return getNamedColorHex().has(val.toLowerCase());
36
+ }
37
+ }
38
38
  let colorWarningCount = 0;
39
39
  const MAX_COLOR_WARNINGS = 10;
40
40
  const CUSTOM_UNITS = {
@@ -148,23 +148,23 @@ function parseColor(val, ignoreError = false) {
148
148
  if (typeof val !== "string") val = String(val ?? "");
149
149
  val = val.trim();
150
150
  if (!val) return {};
151
- const isSimpleColor = SIMPLE_COLOR_PATTERNS.some((pattern) => pattern.test(val));
151
+ const isSimpleColor = isSimpleColorFast(val);
152
152
  let firstColor;
153
153
  if (isSimpleColor) firstColor = val;
154
154
  else {
155
155
  const extractedColor = parseStyle(val).groups.find((g) => g.colors.length)?.colors[0];
156
156
  if (!extractedColor) {
157
157
  if (!ignoreError && colorWarningCount < MAX_COLOR_WARNINGS) {
158
- console.warn("CubeUIKit: unable to parse color:", val);
158
+ console.warn("Tasty: unable to parse color:", val);
159
159
  colorWarningCount++;
160
- if (colorWarningCount === MAX_COLOR_WARNINGS) console.warn("CubeUIKit: color parsing warnings will be suppressed from now on");
160
+ if (colorWarningCount === MAX_COLOR_WARNINGS) console.warn("Tasty: color parsing warnings will be suppressed from now on");
161
161
  }
162
162
  return {};
163
163
  }
164
164
  firstColor = extractedColor;
165
165
  }
166
166
  let nameMatch = firstColor.match(COLOR_VAR_PATTERN);
167
- if (!nameMatch) nameMatch = firstColor.match(COLOR_VAR_RGB_PATTERN);
167
+ if (!nameMatch) nameMatch = firstColor.match(COLOR_VAR_COMPONENTS_PATTERN);
168
168
  let opacity;
169
169
  if (firstColor.startsWith("rgb") || firstColor.startsWith("hsl") || firstColor.startsWith("lch") || firstColor.startsWith("oklch") || firstColor.startsWith("okhsl")) {
170
170
  const alphaMatch = firstColor.match(RGB_ALPHA_PATTERN);
@@ -179,524 +179,15 @@ function parseColor(val, ignoreError = false) {
179
179
  opacity
180
180
  };
181
181
  }
182
- /**
183
- * CSS named color keywords → hex values.
184
- * Lazy-initialized on first use to avoid up-front cost.
185
- */
186
- let _namedColorHex = null;
187
- function getNamedColorHex() {
188
- if (_namedColorHex) return _namedColorHex;
189
- _namedColorHex = new Map([
190
- ["aliceblue", "#f0f8ff"],
191
- ["antiquewhite", "#faebd7"],
192
- ["aqua", "#00ffff"],
193
- ["aquamarine", "#7fffd4"],
194
- ["azure", "#f0ffff"],
195
- ["beige", "#f5f5dc"],
196
- ["bisque", "#ffe4c4"],
197
- ["black", "#000000"],
198
- ["blanchedalmond", "#ffebcd"],
199
- ["blue", "#0000ff"],
200
- ["blueviolet", "#8a2be2"],
201
- ["brown", "#a52a2a"],
202
- ["burlywood", "#deb887"],
203
- ["cadetblue", "#5f9ea0"],
204
- ["chartreuse", "#7fff00"],
205
- ["chocolate", "#d2691e"],
206
- ["coral", "#ff7f50"],
207
- ["cornflowerblue", "#6495ed"],
208
- ["cornsilk", "#fff8dc"],
209
- ["crimson", "#dc143c"],
210
- ["cyan", "#00ffff"],
211
- ["darkblue", "#00008b"],
212
- ["darkcyan", "#008b8b"],
213
- ["darkgoldenrod", "#b8860b"],
214
- ["darkgray", "#a9a9a9"],
215
- ["darkgreen", "#006400"],
216
- ["darkgrey", "#a9a9a9"],
217
- ["darkkhaki", "#bdb76b"],
218
- ["darkmagenta", "#8b008b"],
219
- ["darkolivegreen", "#556b2f"],
220
- ["darkorange", "#ff8c00"],
221
- ["darkorchid", "#9932cc"],
222
- ["darkred", "#8b0000"],
223
- ["darksalmon", "#e9967a"],
224
- ["darkseagreen", "#8fbc8f"],
225
- ["darkslateblue", "#483d8b"],
226
- ["darkslategray", "#2f4f4f"],
227
- ["darkslategrey", "#2f4f4f"],
228
- ["darkturquoise", "#00ced1"],
229
- ["darkviolet", "#9400d3"],
230
- ["deeppink", "#ff1493"],
231
- ["deepskyblue", "#00bfff"],
232
- ["dimgray", "#696969"],
233
- ["dimgrey", "#696969"],
234
- ["dodgerblue", "#1e90ff"],
235
- ["firebrick", "#b22222"],
236
- ["floralwhite", "#fffaf0"],
237
- ["forestgreen", "#228b22"],
238
- ["fuchsia", "#ff00ff"],
239
- ["gainsboro", "#dcdcdc"],
240
- ["ghostwhite", "#f8f8ff"],
241
- ["gold", "#ffd700"],
242
- ["goldenrod", "#daa520"],
243
- ["gray", "#808080"],
244
- ["green", "#008000"],
245
- ["greenyellow", "#adff2f"],
246
- ["grey", "#808080"],
247
- ["honeydew", "#f0fff0"],
248
- ["hotpink", "#ff69b4"],
249
- ["indianred", "#cd5c5c"],
250
- ["indigo", "#4b0082"],
251
- ["ivory", "#fffff0"],
252
- ["khaki", "#f0e68c"],
253
- ["lavender", "#e6e6fa"],
254
- ["lavenderblush", "#fff0f5"],
255
- ["lawngreen", "#7cfc00"],
256
- ["lemonchiffon", "#fffacd"],
257
- ["lightblue", "#add8e6"],
258
- ["lightcoral", "#f08080"],
259
- ["lightcyan", "#e0ffff"],
260
- ["lightgoldenrodyellow", "#fafad2"],
261
- ["lightgray", "#d3d3d3"],
262
- ["lightgreen", "#90ee90"],
263
- ["lightgrey", "#d3d3d3"],
264
- ["lightpink", "#ffb6c1"],
265
- ["lightsalmon", "#ffa07a"],
266
- ["lightseagreen", "#20b2aa"],
267
- ["lightskyblue", "#87cefa"],
268
- ["lightslategray", "#778899"],
269
- ["lightslategrey", "#778899"],
270
- ["lightsteelblue", "#b0c4de"],
271
- ["lightyellow", "#ffffe0"],
272
- ["lime", "#00ff00"],
273
- ["limegreen", "#32cd32"],
274
- ["linen", "#faf0e6"],
275
- ["magenta", "#ff00ff"],
276
- ["maroon", "#800000"],
277
- ["mediumaquamarine", "#66cdaa"],
278
- ["mediumblue", "#0000cd"],
279
- ["mediumorchid", "#ba55d3"],
280
- ["mediumpurple", "#9370db"],
281
- ["mediumseagreen", "#3cb371"],
282
- ["mediumslateblue", "#7b68ee"],
283
- ["mediumspringgreen", "#00fa9a"],
284
- ["mediumturquoise", "#48d1cc"],
285
- ["mediumvioletred", "#c71585"],
286
- ["midnightblue", "#191970"],
287
- ["mintcream", "#f5fffa"],
288
- ["mistyrose", "#ffe4e1"],
289
- ["moccasin", "#ffe4b5"],
290
- ["navajowhite", "#ffdead"],
291
- ["navy", "#000080"],
292
- ["oldlace", "#fdf5e6"],
293
- ["olive", "#808000"],
294
- ["olivedrab", "#6b8e23"],
295
- ["orange", "#ffa500"],
296
- ["orangered", "#ff4500"],
297
- ["orchid", "#da70d6"],
298
- ["palegoldenrod", "#eee8aa"],
299
- ["palegreen", "#98fb98"],
300
- ["paleturquoise", "#afeeee"],
301
- ["palevioletred", "#db7093"],
302
- ["papayawhip", "#ffefd5"],
303
- ["peachpuff", "#ffdab9"],
304
- ["peru", "#cd853f"],
305
- ["pink", "#ffc0cb"],
306
- ["plum", "#dda0dd"],
307
- ["powderblue", "#b0e0e6"],
308
- ["purple", "#800080"],
309
- ["rebeccapurple", "#663399"],
310
- ["red", "#ff0000"],
311
- ["rosybrown", "#bc8f8f"],
312
- ["royalblue", "#4169e1"],
313
- ["saddlebrown", "#8b4513"],
314
- ["salmon", "#fa8072"],
315
- ["sandybrown", "#f4a460"],
316
- ["seagreen", "#2e8b57"],
317
- ["seashell", "#fff5ee"],
318
- ["sienna", "#a0522d"],
319
- ["silver", "#c0c0c0"],
320
- ["skyblue", "#87ceeb"],
321
- ["slateblue", "#6a5acd"],
322
- ["slategray", "#708090"],
323
- ["slategrey", "#708090"],
324
- ["snow", "#fffafa"],
325
- ["springgreen", "#00ff7f"],
326
- ["steelblue", "#4682b4"],
327
- ["tan", "#d2b48c"],
328
- ["teal", "#008080"],
329
- ["thistle", "#d8bfd8"],
330
- ["tomato", "#ff6347"],
331
- ["turquoise", "#40e0d0"],
332
- ["violet", "#ee82ee"],
333
- ["wheat", "#f5deb3"],
334
- ["white", "#ffffff"],
335
- ["whitesmoke", "#f5f5f5"],
336
- ["yellow", "#ffff00"],
337
- ["yellowgreen", "#9acd32"]
338
- ]);
339
- return _namedColorHex;
340
- }
341
- function strToRgb(color, _ignoreAlpha = false) {
342
- if (!color) return void 0;
343
- if (color.startsWith("rgb")) return color;
344
- if (color.startsWith("#")) return hexToRgb(color);
345
- if (color.startsWith("okhsl(")) return okhslToRgb(color);
346
- if (color.startsWith("hsl")) return hslToRgb(color);
347
- const namedHex = getNamedColorHex().get(color.toLowerCase());
348
- if (namedHex) return hexToRgb(namedHex);
349
- return null;
350
- }
351
- /**
352
- * Extract RGB values from an rgb()/rgba() string.
353
- * Supports all modern CSS syntax variations:
354
- * - Comma-separated: rgb(255, 128, 0)
355
- * - Space-separated: rgb(255 128 0)
356
- * - Fractional: rgb(128.5, 64.3, 32.1)
357
- * - Percentages: rgb(50%, 25%, 75%)
358
- * - Slash alpha notation: rgb(255 128 0 / 0.5)
359
- *
360
- * Returns array of RGB values (0-255 range), converting percentages as needed.
361
- */
362
- function getRgbValuesFromRgbaString(str) {
363
- const match = str.match(/rgba?\(([^)]+)\)/i);
364
- if (!match) return [];
365
- const [colorPart] = match[1].trim().split("/");
366
- return colorPart.trim().split(/[,\s]+/).filter(Boolean).slice(0, 3).map((part) => {
367
- part = part.trim();
368
- if (part.endsWith("%")) return parseFloat(part) / 100 * 255;
369
- return parseFloat(part);
370
- });
371
- }
372
- function hexToRgb(hex) {
373
- 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);
374
- if (!matched) return null;
375
- const rgba = matched.map((x, i) => parseInt(x, 16) * (i === 3 ? 1 / 255 : 1));
376
- if (rgba.some((v) => Number.isNaN(v))) return null;
377
- if (rgba.length >= 3) return `rgb(${rgba.slice(0, 3).join(" ")}${rgba.length > 3 ? ` / ${rgba[3]}` : ""})`;
378
- return null;
379
- }
380
182
  function filterMods(mods, allowedMods) {
381
183
  return mods.filter((mod) => allowedMods.includes(mod));
382
184
  }
383
- function extendStyles(defaultStyles, newStyles) {
384
- let styles = {};
385
- if (!defaultStyles) {
386
- if (!newStyles) return styles;
387
- } else styles = Object.assign({}, defaultStyles);
388
- if (newStyles) Object.keys(newStyles).forEach((key) => {
389
- if (newStyles[key] != null) styles[key] = newStyles[key];
390
- });
391
- return styles;
392
- }
393
- /**
394
- * Split properties into style and non-style properties.
395
- * @param props - Component prop map.
396
- * @param [styleList] - List of all style properties.
397
- * @param [defaultStyles] - Default style map of the component.
398
- * @param [propMap] - Props to style alias map.
399
- * @param [ignoreList] - A list of properties to ignore.
400
- */
401
- function extractStyles(props, styleList = [], defaultStyles, propMap, ignoreList = []) {
402
- const styles = {
403
- ...defaultStyles,
404
- ...ignoreList.includes("styles") ? void 0 : props.styles && typeof props.styles === "object" ? props.styles : void 0
405
- };
406
- Object.keys(props).forEach((prop) => {
407
- const propName = propMap ? propMap[prop] || prop : prop;
408
- const value = props[prop];
409
- if (ignoreList && ignoreList.includes(prop)) {} else if (styleList.includes(propName)) styles[propName] = value;
410
- }, {});
411
- return styles;
412
- }
413
- 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;
414
- /**
415
- * Check if a token is an advanced state (starts with @)
416
- */
417
- function isAdvancedStateToken(token) {
418
- return token.startsWith("@") || token.startsWith("!@");
419
- }
420
- const STATE_OPERATORS = {
421
- NOT: "!",
422
- AND: "&",
423
- OR: "|",
424
- XOR: "^"
425
- };
426
- const STATE_OPERATOR_LIST = [
427
- "!",
428
- "&",
429
- "|",
430
- "^"
431
- ];
432
- /**
433
- * Convert state notation tokens to a compute model (string, or nested [op, lhs, rhs]).
434
- */
435
- function convertTokensToComputeUnits(tokens) {
436
- if (tokens.length === 1) return tokens[0];
437
- const hasLength = (x) => typeof x === "string" || Array.isArray(x);
438
- STATE_OPERATOR_LIST.forEach((operator) => {
439
- let i;
440
- while ((i = tokens.indexOf(operator)) !== -1) {
441
- const token = tokens[i];
442
- if (token === "!") {
443
- const next = tokens[i + 1];
444
- if (next !== void 0 && hasLength(next) && next.length !== 1) tokens.splice(i, 2, ["!", next]);
445
- else tokens.splice(i, 1);
446
- } else {
447
- const prev = tokens[i - 1];
448
- const next = tokens[i + 1];
449
- if (prev !== void 0 && next !== void 0 && hasLength(prev) && hasLength(next) && prev.length !== 1 && next.length !== 1) tokens.splice(i - 1, 3, [
450
- token,
451
- prev,
452
- next
453
- ]);
454
- else tokens.splice(i, 1);
455
- }
456
- }
457
- });
458
- return tokens.length === 1 ? tokens[0] : tokens;
459
- }
460
- /**
461
- * Replace commas with | only outside of parentheses.
462
- * This preserves commas in advanced states like @(card, w < 600px)
463
- */
464
- function replaceCommasOutsideParens(str) {
465
- let result = "";
466
- let depth = 0;
467
- for (const char of str) if (char === "(") {
468
- depth++;
469
- result += char;
470
- } else if (char === ")") {
471
- depth--;
472
- result += char;
473
- } else if (char === "," && depth === 0) result += "|";
474
- else result += char;
475
- return result;
476
- }
477
- /**
478
- * Parse state notation and return tokens, modifiers and compute model.
479
- */
480
- function parseStateNotationInner(notation, value) {
481
- const tokens = replaceCommasOutsideParens(notation).match(STATES_REGEXP);
482
- if (!tokens || !tokens.length) return {
483
- model: void 0,
484
- mods: [],
485
- notMods: [],
486
- tokens: [],
487
- value
488
- };
489
- else if (tokens.length === 1) return {
490
- model: tokens[0],
491
- mods: tokens.slice(0),
492
- notMods: [],
493
- tokens,
494
- value
495
- };
496
- const mods = [];
497
- const operations = [[]];
498
- let list = operations[0];
499
- let position = 0;
500
- let operation;
501
- tokens.forEach((token) => {
502
- switch (token) {
503
- case "(":
504
- operation = [];
505
- position++;
506
- list = operations[position] = operation;
507
- break;
508
- case ")":
509
- position--;
510
- operations[position].push(convertTokensToComputeUnits(list));
511
- list = operations[position];
512
- break;
513
- default:
514
- if (token.length > 1) {
515
- if (!mods.includes(token)) mods.push(token);
516
- }
517
- list.push(token);
518
- }
519
- });
520
- while (position) {
521
- position--;
522
- operations[position].push(convertTokensToComputeUnits(list));
523
- list = operations[position];
524
- }
525
- return {
526
- tokens,
527
- mods,
528
- notMods: [],
529
- model: convertTokensToComputeUnits(operations[0]),
530
- value
531
- };
532
- }
533
- const parseStateNotation = cacheWrapper(parseStateNotationInner);
534
- /**
535
- * Build an AtRuleContext from parsed advanced states
536
- */
537
- function buildAtRuleContext(advancedStates, negatedStates) {
538
- if (advancedStates.length === 0) return void 0;
539
- const ctx = {};
540
- for (const state of advancedStates) {
541
- const isNegated = negatedStates.has(state.raw);
542
- switch (state.type) {
543
- case "media": {
544
- if (!ctx.media) ctx.media = [];
545
- let mediaCondition = "";
546
- if (state.mediaType) mediaCondition = state.mediaType;
547
- else if (state.condition) mediaCondition = `(${state.condition})`;
548
- if (mediaCondition) if (isNegated) ctx.media.push(`not ${mediaCondition}`);
549
- else ctx.media.push(mediaCondition);
550
- break;
551
- }
552
- case "container": {
553
- if (!ctx.container) ctx.container = [];
554
- let condition = state.condition;
555
- if (isNegated) condition = `not (${condition})`;
556
- ctx.container.push({
557
- name: state.containerName,
558
- condition
559
- });
560
- break;
561
- }
562
- case "root": {
563
- if (!ctx.rootStates) ctx.rootStates = [];
564
- const rootSelector = buildRootSelector(state.condition, isNegated);
565
- ctx.rootStates.push(rootSelector);
566
- break;
567
- }
568
- case "starting":
569
- if (!isNegated) ctx.startingStyle = true;
570
- break;
571
- }
572
- }
573
- if (!ctx.media?.length && !ctx.container?.length && !ctx.rootStates?.length && !ctx.startingStyle) return;
574
- return ctx;
575
- }
576
- /**
577
- * Build a root state selector from a condition
578
- */
579
- function buildRootSelector(condition, isNegated) {
580
- let selector;
581
- if (condition.startsWith(".")) selector = condition;
582
- else if (condition.startsWith("[")) selector = condition;
583
- else if (condition.includes("=")) {
584
- const [key, value] = condition.split("=");
585
- selector = `[data-${camelToKebab(key.trim())}="${value.trim()}"]`;
586
- } else selector = `[data-${camelToKebab(condition)}]`;
587
- if (isNegated) return `:not(${selector})`;
588
- return selector;
589
- }
590
- /**
591
- * Parse state notation and return tokens, modifiers and compute model.
592
- * Enhanced to detect and extract advanced states.
593
- */
594
- function styleStateMapToStyleStateDataList(styleStateMap, parserContext) {
595
- if (typeof styleStateMap !== "object" || !styleStateMap) return {
596
- states: [{
597
- model: void 0,
598
- mods: [],
599
- notMods: [],
600
- value: styleStateMap
601
- }],
602
- mods: [],
603
- hasAdvancedStates: false
604
- };
605
- const stateDataList = [];
606
- let hasAdvancedStates = false;
607
- Object.keys(styleStateMap).forEach((stateNotation) => {
608
- const state = parseStateNotation(stateNotation, styleStateMap[stateNotation]);
609
- const advancedStates = [];
610
- const negatedAdvancedStates = /* @__PURE__ */ new Set();
611
- const regularMods = [];
612
- const ownMods = [];
613
- const negatedOwnMods = [];
614
- if (state.tokens) {
615
- let isNegated = false;
616
- for (const token of state.tokens) {
617
- if (token === "!") {
618
- isNegated = true;
619
- continue;
620
- }
621
- if (isAdvancedStateToken(token)) {
622
- hasAdvancedStates = true;
623
- const parsed = parseAdvancedState(token, parserContext || createStateParserContext(void 0));
624
- advancedStates.push(parsed);
625
- if (parsed.type === "own" && parsed.condition) if (isNegated) negatedOwnMods.push(parsed.condition);
626
- else ownMods.push(parsed.condition);
627
- else if (isNegated) negatedAdvancedStates.add(token);
628
- isNegated = false;
629
- } else if (token.length > 1 && ![
630
- "&",
631
- "|",
632
- "^",
633
- "(",
634
- ")"
635
- ].includes(token)) {
636
- regularMods.push(token);
637
- isNegated = false;
638
- } else isNegated = false;
639
- }
640
- }
641
- if (advancedStates.length > 0) {
642
- state.advancedStates = advancedStates;
643
- state.atRuleContext = buildAtRuleContext(advancedStates, negatedAdvancedStates);
644
- state.mods = regularMods;
645
- }
646
- if (ownMods.length > 0) state.ownMods = ownMods;
647
- if (negatedOwnMods.length > 0) state.negatedOwnMods = negatedOwnMods;
648
- stateDataList.push(state);
649
- });
650
- stateDataList.reverse();
651
- let initialState;
652
- const allMods = stateDataList.reduce((all, state) => {
653
- if (!state.mods.length && !state.advancedStates?.length) initialState = state;
654
- else state.mods.forEach((mod) => {
655
- if (!all.includes(mod)) all.push(mod);
656
- });
657
- return all;
658
- }, []);
659
- if (!initialState) stateDataList.push({
660
- mods: [],
661
- notMods: allMods,
662
- value: true
663
- });
664
- return {
665
- states: stateDataList,
666
- mods: allMods,
667
- hasAdvancedStates
668
- };
669
- }
670
- const COMPUTE_FUNC_MAP = {
671
- "!": (a) => !a,
672
- "^": (a, b) => a && !b || !a && b,
673
- "|": (a, b) => a || b,
674
- "&": (a, b) => a && b
675
- };
676
- /**
677
- * Compute a result based on a model and incoming map.
678
- */
679
- function computeState(computeModel, valueMap) {
680
- if (!computeModel) return true;
681
- const map = valueMap;
682
- if (!Array.isArray(computeModel)) if (typeof valueMap === "function") return !!valueMap(computeModel);
683
- else return !!map[computeModel];
684
- const func = COMPUTE_FUNC_MAP[computeModel[0]];
685
- if (!func) console.warn("CubeUIKit: unexpected compute method in the model", computeModel);
686
- let a = computeModel[1];
687
- if (typeof a === "object") a = !!computeState(a, valueMap);
688
- else if (typeof valueMap === "function") a = !!valueMap(a);
689
- else a = !!map[a];
690
- if (computeModel.length === 2) return func(a);
691
- let b = computeModel[2];
692
- if (typeof b === "object") b = !!computeState(b, valueMap);
693
- else if (typeof valueMap === "function") b = !!valueMap(b);
694
- else b = !!map[b];
695
- return !!func(a, b);
696
- }
697
185
  const _innerCache = /* @__PURE__ */ new WeakMap();
186
+ const _topLevelCache = /* @__PURE__ */ new WeakMap();
698
187
  function stringifyStyles(styles) {
699
188
  if (styles == null || typeof styles !== "object") return "";
189
+ const cached = _topLevelCache.get(styles);
190
+ if (cached !== void 0) return cached;
700
191
  const obj = styles;
701
192
  const keys = Object.keys(obj).sort();
702
193
  const parts = [];
@@ -722,9 +213,11 @@ function stringifyStyles(styles) {
722
213
  } else sv = JSON.stringify(v);
723
214
  parts.push(JSON.stringify(k) + ":" + sv);
724
215
  }
725
- return "{" + parts.join(",") + "}";
216
+ const result = "{" + parts.join(",") + "}";
217
+ _topLevelCache.set(styles, result);
218
+ return result;
726
219
  }
727
220
 
728
221
  //#endregion
729
- export { COMPUTE_FUNC_MAP, CUSTOM_UNITS, DIRECTIONS, STATE_OPERATORS, STATE_OPERATOR_LIST, buildAtRuleContext, computeState, customFunc, extendStyles, extractStyles, filterMods, getGlobalFuncs, getGlobalParser, getGlobalPredefinedTokens, getRgbValuesFromRgbaString, hexToRgb, isAdvancedStateToken, normalizeColorTokenValue, parseColor, parseStateNotation, parseStyle, resetGlobalPredefinedTokens, setGlobalPredefinedTokens, strToRgb, stringifyStyles, styleStateMapToStyleStateDataList };
222
+ export { CUSTOM_UNITS, DIRECTIONS, customFunc, filterMods, getGlobalFuncs, getGlobalParser, getGlobalPredefinedTokens, normalizeColorTokenValue, parseColor, parseStyle, resetGlobalPredefinedTokens, setGlobalPredefinedTokens, stringifyStyles };
730
223
  //# sourceMappingURL=styles.js.map