@tenphi/tasty 0.0.0-snapshot.d656d18 → 0.0.0-snapshot.d7129ca
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.
- package/README.md +6 -6
- package/dist/{babel-_RVkw0iE.d.ts → babel-DD7kdEFT.d.ts} +2 -2
- package/dist/chunks/async-storage-CG5HnUT5.js +20 -0
- package/dist/chunks/{async-storage-DKK-wTD4.js.map → async-storage-CG5HnUT5.js.map} +1 -1
- package/dist/chunks/build-config-CUQVwdWF.js +42 -0
- package/dist/chunks/build-config-CUQVwdWF.js.map +1 -0
- package/dist/chunks/{collector-DBGcmUEq.js → collector-B0LTHw6Z.js} +6 -124
- package/dist/chunks/collector-B0LTHw6Z.js.map +1 -0
- package/dist/chunks/config-engine-C3pF9EK9.js +267 -0
- package/dist/chunks/config-engine-C3pF9EK9.js.map +1 -0
- package/dist/chunks/css-definitions-D_it4XZH.js +875 -0
- package/dist/chunks/css-definitions-D_it4XZH.js.map +1 -0
- package/dist/chunks/{css-resources-Cyl_axbI.js → css-resources-BN8apgxt.js} +1 -8
- package/dist/chunks/{css-resources-Cyl_axbI.js.map → css-resources-BN8apgxt.js.map} +1 -1
- package/dist/chunks/{debug-BUwqo6vC.js → debug-CiiHDgmR.js} +69 -150
- package/dist/chunks/debug-CiiHDgmR.js.map +1 -0
- package/dist/chunks/{dsl-CXvoaLnj.js → dsl-C5yuAn41.js} +62 -786
- package/dist/chunks/dsl-C5yuAn41.js.map +1 -0
- package/dist/chunks/hydration-TRcz5vnk.js +41 -0
- package/dist/chunks/hydration-TRcz5vnk.js.map +1 -0
- package/dist/chunks/react-runtime-sH6r6Ajr.js +557 -0
- package/dist/chunks/react-runtime-sH6r6Ajr.js.map +1 -0
- package/dist/chunks/runtime-engine-BrRcOZwD.js +2438 -0
- package/dist/chunks/runtime-engine-BrRcOZwD.js.map +1 -0
- package/dist/chunks/runtime-state-BTDqSYBk.js +127 -0
- package/dist/chunks/runtime-state-BTDqSYBk.js.map +1 -0
- package/dist/chunks/{shared-utils-OIg0N_dp.js → shared-utils-DWA4LjIa.js} +24 -62
- package/dist/chunks/shared-utils-DWA4LjIa.js.map +1 -0
- package/dist/chunks/{style-engine-CqSmIlud.js → style-engine-C1ECBZxR.js} +671 -2736
- package/dist/chunks/style-engine-C1ECBZxR.js.map +1 -0
- package/dist/chunks/{css-writer-PFzrSPeu.js → zero-engine-B6EnYcXY.js} +3 -120
- package/dist/chunks/zero-engine-B6EnYcXY.js.map +1 -0
- package/dist/{collector-CVdVIy7s.d.ts → collector-YpsMjV7T.d.ts} +6 -4
- package/dist/{config-BI0y21JV.d.ts → config-BnZqyYG4.d.ts} +16 -25
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +9 -7
- package/dist/{index-CrT0bsiI.d.ts → index-BLJLo9cl.d.ts} +17 -50
- package/dist/index.d.ts +5 -5
- package/dist/index.js +10 -7
- package/dist/{merge-styles-BFktNP8J.d.ts → merge-styles-CTDLIrO5.d.ts} +2 -2
- package/dist/ssr/astro-client.js +1 -14
- package/dist/ssr/astro-client.js.map +1 -1
- package/dist/ssr/astro-middleware-static.js +0 -11
- package/dist/ssr/astro-middleware-static.js.map +1 -1
- package/dist/ssr/astro-middleware.js +0 -12
- package/dist/ssr/astro-middleware.js.map +1 -1
- package/dist/ssr/astro.js +5 -85
- package/dist/ssr/astro.js.map +1 -1
- package/dist/ssr/index.d.ts +6 -6
- package/dist/ssr/index.js +4 -4
- package/dist/ssr/next-config.d.ts +1 -1
- package/dist/ssr/next-config.js +29 -20
- package/dist/ssr/next-config.js.map +1 -1
- package/dist/ssr/next.d.ts +1 -1
- package/dist/ssr/next.js +5 -36
- package/dist/ssr/next.js.map +1 -1
- package/dist/static/index.d.ts +2 -2
- package/dist/static/index.js +1 -19
- package/dist/static/index.js.map +1 -1
- package/dist/{index-BzAC3p06.d.ts → types-vfRQhzRd.d.ts} +811 -811
- package/dist/zero/babel.d.ts +1 -1
- package/dist/zero/babel.js +25 -95
- package/dist/zero/babel.js.map +1 -1
- package/dist/zero/index.d.ts +1 -1
- package/dist/zero/index.js +1 -1
- package/dist/zero/next.d.ts +1 -1
- package/dist/zero/next.js +0 -31
- package/dist/zero/next.js.map +1 -1
- package/docs/ai-agents.md +5 -1
- package/docs/dsl.md +2 -2
- package/docs/getting-started.md +12 -11
- package/docs/methodology.md +2 -2
- package/docs/pipeline.md +3 -0
- package/docs/plugins.md +1 -1
- package/docs/runtime-benchmarks.md +105 -68
- package/docs/ssr.md +1 -1
- package/docs/styles.md +5 -5
- package/docs/tasty-static.md +1 -1
- package/package.json +29 -10
- package/dist/chunks/async-storage-DKK-wTD4.js +0 -44
- package/dist/chunks/collector-DBGcmUEq.js.map +0 -1
- package/dist/chunks/css-writer-PFzrSPeu.js.map +0 -1
- package/dist/chunks/debug-BUwqo6vC.js.map +0 -1
- package/dist/chunks/dsl-CXvoaLnj.js.map +0 -1
- package/dist/chunks/hydrate-6YoHZP6A.js +0 -37
- package/dist/chunks/hydrate-6YoHZP6A.js.map +0 -1
- package/dist/chunks/react-runtime-B3CmvDEQ.js +0 -1525
- package/dist/chunks/react-runtime-B3CmvDEQ.js.map +0 -1
- package/dist/chunks/runtime-engine-Y00VWjrS.js +0 -4719
- package/dist/chunks/runtime-engine-Y00VWjrS.js.map +0 -1
- package/dist/chunks/shared-utils-OIg0N_dp.js.map +0 -1
- package/dist/chunks/style-engine-CqSmIlud.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as warnOnceDev, o as isDevEnv } from "./shared-utils-
|
|
1
|
+
import { a as warnOnceDev, o as isDevEnv } from "./shared-utils-DWA4LjIa.js";
|
|
2
2
|
//#region src/parser/const.ts
|
|
3
3
|
const VALUE_KEYWORDS = new Set([
|
|
4
4
|
"auto",
|
|
@@ -19,11 +19,6 @@ const CSS_WIDE_KEYWORDS = new Set([
|
|
|
19
19
|
"unset",
|
|
20
20
|
"revert-layer"
|
|
21
21
|
]);
|
|
22
|
-
/**
|
|
23
|
-
* Color functions that *derive* a color from other colors. They take no alpha
|
|
24
|
-
* channel, so opacity has to wrap the whole call in `color-mix()` instead of
|
|
25
|
-
* being appended after a slash.
|
|
26
|
-
*/
|
|
27
22
|
const DERIVED_COLOR_FUNCS_LIST = [
|
|
28
23
|
"color-mix",
|
|
29
24
|
"color-contrast",
|
|
@@ -31,11 +26,6 @@ const DERIVED_COLOR_FUNCS_LIST = [
|
|
|
31
26
|
"light-dark"
|
|
32
27
|
];
|
|
33
28
|
const DERIVED_COLOR_FUNCS = new Set(DERIVED_COLOR_FUNCS_LIST);
|
|
34
|
-
/**
|
|
35
|
-
* Every color function the parser recognizes. The ones outside
|
|
36
|
-
* `DERIVED_COLOR_FUNCS` take channels as arguments, optionally followed by
|
|
37
|
-
* `/ <alpha>` — which is where an opacity suffix writes.
|
|
38
|
-
*/
|
|
39
29
|
const COLOR_FUNCS = new Set([
|
|
40
30
|
"rgb",
|
|
41
31
|
"rgba",
|
|
@@ -51,7 +41,6 @@ const COLOR_FUNCS = new Set([
|
|
|
51
41
|
"gray",
|
|
52
42
|
...DERIVED_COLOR_FUNCS_LIST
|
|
53
43
|
]);
|
|
54
|
-
/** A value that is a single `name(args)` call: captures the name and the args. */
|
|
55
44
|
const RE_FUNC_CALL = /^([a-z][a-z0-9-]*)\((.+)\)$/i;
|
|
56
45
|
const RE_UNIT_NUM = /^[+-]?(?:\d*\.\d+|\d+)([a-z][a-z0-9]*)$/;
|
|
57
46
|
const RE_NUMBER = /^[+-]?(?:\d*\.\d+|\d+)$/;
|
|
@@ -78,41 +67,13 @@ function canonicalFuncName(lowered) {
|
|
|
78
67
|
function toSnakeCase(str) {
|
|
79
68
|
return str.replace(/[A-Z]/g, (s) => `-${s.toLowerCase()}`);
|
|
80
69
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Normalize a DSL identifier to the CSS custom-property name it emits.
|
|
83
|
-
*
|
|
84
|
-
* CSS custom-property names are case-sensitive, so `$myVar` has to keep its
|
|
85
|
-
* inner case to reference `--myVar`. A leading capital is the one exception:
|
|
86
|
-
* `$Foo` is not a supported way to name a property, so the first character is
|
|
87
|
-
* folded rather than kebab-cased (`--foo`, not `---foo`) and every later
|
|
88
|
-
* character is left alone.
|
|
89
|
-
*
|
|
90
|
-
* Every place that turns a `$name` / `#name` identifier into a CSS name goes
|
|
91
|
-
* through this, so authoring a token and referencing it always agree.
|
|
92
|
-
*/
|
|
93
70
|
function normalizeDslName(name) {
|
|
94
71
|
if (!name) return name;
|
|
95
72
|
const first = name[0];
|
|
96
73
|
const lower = first.toLowerCase();
|
|
97
74
|
return lower === first ? name : lower + name.slice(1);
|
|
98
75
|
}
|
|
99
|
-
/** A DSL identifier: `$name`, `$$name`, `#name` or `##name`. */
|
|
100
76
|
const RE_DSL_IDENTIFIER = /(\$\$?|##?)([a-zA-Z_][a-zA-Z0-9_-]*)/g;
|
|
101
|
-
/**
|
|
102
|
-
* Case-fold a DSL string for parsing, preserving the case of custom-property
|
|
103
|
-
* names.
|
|
104
|
-
*
|
|
105
|
-
* Everything the parser matches on — keywords, units, modifiers, function names,
|
|
106
|
-
* color-token names — is compared lowercase, so the whole string used to be
|
|
107
|
-
* lowercased up front. That also folded custom-property names, which are
|
|
108
|
-
* case-sensitive in CSS: `$myVar` referenced `var(--myvar)` while the token
|
|
109
|
-
* definition emitted `--myVar`, so the two could never meet.
|
|
110
|
-
*
|
|
111
|
-
* Identifier bodies now keep their case (their first character still folds, see
|
|
112
|
-
* {@link normalizeDslName}); everything else is lowercased exactly as before.
|
|
113
|
-
* Hex literals are excluded — `#FF0000` is a color, not a name, and must fold to
|
|
114
|
-
* match {@link RE_HEX}.
|
|
115
|
-
*/
|
|
116
77
|
function foldDslCase(src) {
|
|
117
78
|
const folded = src.toLowerCase();
|
|
118
79
|
if (folded === src || !src.includes("$") && !src.includes("#")) return folded;
|
|
@@ -130,22 +91,10 @@ function foldDslCase(src) {
|
|
|
130
91
|
}
|
|
131
92
|
//#endregion
|
|
132
93
|
//#region src/utils/color-math.ts
|
|
133
|
-
const
|
|
134
|
-
[
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
.2158037573099136
|
|
138
|
-
],
|
|
139
|
-
[
|
|
140
|
-
1,
|
|
141
|
-
-.1055613458156586,
|
|
142
|
-
-.0638541728258133
|
|
143
|
-
],
|
|
144
|
-
[
|
|
145
|
-
1,
|
|
146
|
-
-.0894841775298119,
|
|
147
|
-
-1.2914855480194092
|
|
148
|
-
]
|
|
94
|
+
const OKLab_to_LMS_ab = [
|
|
95
|
+
[.3963377773761749, .2158037573099136],
|
|
96
|
+
[-.1055613458156586, -.0638541728258133],
|
|
97
|
+
[-.0894841775298119, -1.2914855480194092]
|
|
149
98
|
];
|
|
150
99
|
const LMS_to_linear_sRGB_M = [
|
|
151
100
|
[
|
|
@@ -187,7 +136,8 @@ const OKLab_to_linear_sRGB_coefficients = [
|
|
|
187
136
|
.00692167
|
|
188
137
|
]]
|
|
189
138
|
];
|
|
190
|
-
const dotXY = (
|
|
139
|
+
const dotXY = (vector, x, y) => vector[0] * x + vector[1] * y;
|
|
140
|
+
const dotXYZ = (matrix, x, y, z) => matrix[0] * x + matrix[1] * y + matrix[2] * z;
|
|
191
141
|
const INV_GAMMA = 1 / 2.4;
|
|
192
142
|
function srgbLinearToGamma(val) {
|
|
193
143
|
const sign = val < 0 ? -1 : 1;
|
|
@@ -232,18 +182,12 @@ const oklabToLinearSrgb = (lab) => {
|
|
|
232
182
|
const computeMaxSaturationOKLC = (a, b) => {
|
|
233
183
|
const okCoeff = OKLab_to_linear_sRGB_coefficients;
|
|
234
184
|
const lmsToRgb = LMS_to_linear_sRGB_M;
|
|
235
|
-
const tmp2 = [a, b];
|
|
236
|
-
const tmp3 = [
|
|
237
|
-
0,
|
|
238
|
-
a,
|
|
239
|
-
b
|
|
240
|
-
];
|
|
241
185
|
let chnlCoeff;
|
|
242
186
|
let chnlLMS;
|
|
243
|
-
if (dotXY(okCoeff[0][0],
|
|
187
|
+
if (dotXY(okCoeff[0][0], a, b) > 1) {
|
|
244
188
|
chnlCoeff = okCoeff[0][1];
|
|
245
189
|
chnlLMS = lmsToRgb[0];
|
|
246
|
-
} else if (dotXY(okCoeff[1][0],
|
|
190
|
+
} else if (dotXY(okCoeff[1][0], a, b) > 1) {
|
|
247
191
|
chnlCoeff = okCoeff[1][1];
|
|
248
192
|
chnlLMS = lmsToRgb[1];
|
|
249
193
|
} else {
|
|
@@ -253,10 +197,9 @@ const computeMaxSaturationOKLC = (a, b) => {
|
|
|
253
197
|
const [k0, k1, k2, k3, k4] = chnlCoeff;
|
|
254
198
|
const [wl, wm, ws] = chnlLMS;
|
|
255
199
|
let sat = k0 + k1 * a + k2 * b + k3 * (a * a) + k4 * a * b;
|
|
256
|
-
const
|
|
257
|
-
const
|
|
258
|
-
const
|
|
259
|
-
const ks = dotYZ(OKLab_to_LMS_M[2], tmp3);
|
|
200
|
+
const kl = dotXY(OKLab_to_LMS_ab[0], a, b);
|
|
201
|
+
const km = dotXY(OKLab_to_LMS_ab[1], a, b);
|
|
202
|
+
const ks = dotXY(OKLab_to_LMS_ab[2], a, b);
|
|
260
203
|
const l_ = 1 + sat * kl;
|
|
261
204
|
const m_ = 1 + sat * km;
|
|
262
205
|
const s_ = 1 + sat * ks;
|
|
@@ -287,15 +230,7 @@ const findCuspOKLCH = (a, b) => {
|
|
|
287
230
|
};
|
|
288
231
|
const findGamutIntersectionOKLCH = (a, b, l1, c1, l0, cusp) => {
|
|
289
232
|
const lmsToRgb = LMS_to_linear_sRGB_M;
|
|
290
|
-
const tmp3 = [
|
|
291
|
-
0,
|
|
292
|
-
a,
|
|
293
|
-
b
|
|
294
|
-
];
|
|
295
|
-
const floatMax = Number.MAX_VALUE;
|
|
296
233
|
let t;
|
|
297
|
-
const dotYZ = (mat, vec) => mat[1] * vec[1] + mat[2] * vec[2];
|
|
298
|
-
const dotXYZ = (vec, x, y, z) => vec[0] * x + vec[1] * y + vec[2] * z;
|
|
299
234
|
if ((l1 - l0) * cusp[1] - (cusp[0] - l0) * c1 <= 0) {
|
|
300
235
|
const denom = c1 * cusp[0] + cusp[1] * (l0 - l1);
|
|
301
236
|
t = denom === 0 ? 0 : cusp[1] * l0 / denom;
|
|
@@ -304,9 +239,9 @@ const findGamutIntersectionOKLCH = (a, b, l1, c1, l0, cusp) => {
|
|
|
304
239
|
t = denom === 0 ? 0 : cusp[1] * (l0 - 1) / denom;
|
|
305
240
|
const dl = l1 - l0;
|
|
306
241
|
const dc = c1;
|
|
307
|
-
const kl =
|
|
308
|
-
const km =
|
|
309
|
-
const ks =
|
|
242
|
+
const kl = dotXY(OKLab_to_LMS_ab[0], a, b);
|
|
243
|
+
const km = dotXY(OKLab_to_LMS_ab[1], a, b);
|
|
244
|
+
const ks = dotXY(OKLab_to_LMS_ab[2], a, b);
|
|
310
245
|
const ldt_ = dl + dc * kl;
|
|
311
246
|
const mdt_ = dl + dc * km;
|
|
312
247
|
const sdt_ = dl + dc * ks;
|
|
@@ -324,25 +259,15 @@ const findGamutIntersectionOKLCH = (a, b, l1, c1, l0, cusp) => {
|
|
|
324
259
|
const ldt2 = 6 * ldt_ * ldt_ * l_;
|
|
325
260
|
const mdt2 = 6 * mdt_ * mdt_ * m_;
|
|
326
261
|
const sdt2 = 6 * sdt_ * sdt_ * s_;
|
|
327
|
-
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
let tg = -g_ * ug;
|
|
337
|
-
const b_ = dotXYZ(lmsToRgb[2], l, m, s) - 1;
|
|
338
|
-
const b1 = dotXYZ(lmsToRgb[2], ldt, mdt, sdt);
|
|
339
|
-
const b2 = dotXYZ(lmsToRgb[2], ldt2, mdt2, sdt2);
|
|
340
|
-
const ub = b1 / (b1 * b1 - .5 * b_ * b2);
|
|
341
|
-
let tb = -b_ * ub;
|
|
342
|
-
tr = ur >= 0 ? tr : floatMax;
|
|
343
|
-
tg = ug >= 0 ? tg : floatMax;
|
|
344
|
-
tb = ub >= 0 ? tb : floatMax;
|
|
345
|
-
t += Math.min(tr, Math.min(tg, tb));
|
|
262
|
+
let correction = Number.MAX_VALUE;
|
|
263
|
+
for (const matrix of lmsToRgb) {
|
|
264
|
+
const value = dotXYZ(matrix, l, m, s) - 1;
|
|
265
|
+
const slope = dotXYZ(matrix, ldt, mdt, sdt);
|
|
266
|
+
const slope2 = dotXYZ(matrix, ldt2, mdt2, sdt2);
|
|
267
|
+
const u = slope / (slope * slope - .5 * value * slope2);
|
|
268
|
+
if (u >= 0) correction = Math.min(correction, -value * u);
|
|
269
|
+
}
|
|
270
|
+
t += correction;
|
|
346
271
|
}
|
|
347
272
|
return t;
|
|
348
273
|
};
|
|
@@ -400,15 +325,6 @@ const okhslToOklab = (hsl) => {
|
|
|
400
325
|
b
|
|
401
326
|
];
|
|
402
327
|
};
|
|
403
|
-
/**
|
|
404
|
-
* HSL to RGB.
|
|
405
|
-
* Algorithm from CSS Color 4 spec.
|
|
406
|
-
*
|
|
407
|
-
* @param h - Hue in degrees (0-360)
|
|
408
|
-
* @param s - Saturation (0-1)
|
|
409
|
-
* @param l - Lightness (0-1)
|
|
410
|
-
* @returns RGB values in 0-255 range (may have fractional values)
|
|
411
|
-
*/
|
|
412
328
|
function hslToRgbValues(h, s, l) {
|
|
413
329
|
const a = s * Math.min(l, 1 - l);
|
|
414
330
|
const f = (n) => {
|
|
@@ -421,13 +337,6 @@ function hslToRgbValues(h, s, l) {
|
|
|
421
337
|
f(4) * 255
|
|
422
338
|
];
|
|
423
339
|
}
|
|
424
|
-
/**
|
|
425
|
-
* OKHSL to sRGB (0-1 range).
|
|
426
|
-
* @param h - Hue in degrees (0-360)
|
|
427
|
-
* @param s - Saturation (0-1)
|
|
428
|
-
* @param l - Lightness (0-1)
|
|
429
|
-
* @returns sRGB values in 0-1 range, clamped to gamut
|
|
430
|
-
*/
|
|
431
340
|
function okhslToSrgb(h, s, l) {
|
|
432
341
|
const linearRGB = oklabToLinearSrgb(okhslToOklab([
|
|
433
342
|
h,
|
|
@@ -440,23 +349,9 @@ function okhslToSrgb(h, s, l) {
|
|
|
440
349
|
clamp$1(srgbLinearToGamma(linearRGB[2]), 0, 1)
|
|
441
350
|
];
|
|
442
351
|
}
|
|
443
|
-
/**
|
|
444
|
-
* OKHST to sRGB (0-1 range).
|
|
445
|
-
* @param h - Hue in degrees (0-360)
|
|
446
|
-
* @param s - Saturation (0-1)
|
|
447
|
-
* @param t - Tone (0-1)
|
|
448
|
-
* @returns sRGB values in 0-1 range, clamped to gamut
|
|
449
|
-
*/
|
|
450
352
|
function okhstToSrgb(h, s, t) {
|
|
451
353
|
return okhslToSrgb(h, clamp$1(s, 0, 1), clamp$1(fromTone(t * 100), 0, 1));
|
|
452
354
|
}
|
|
453
|
-
/**
|
|
454
|
-
* OKLCH to sRGB (0-255 range).
|
|
455
|
-
* @param L - Lightness (0-1)
|
|
456
|
-
* @param C - Chroma (typically 0-0.4)
|
|
457
|
-
* @param H - Hue in degrees (0-360)
|
|
458
|
-
* @returns RGB values in 0-255 range, clamped to gamut
|
|
459
|
-
*/
|
|
460
355
|
function oklchToRgbValues(L, C, H) {
|
|
461
356
|
const hRad = H * Math.PI / 180;
|
|
462
357
|
const linear = oklabToLinearSrgb([
|
|
@@ -473,162 +368,12 @@ function oklchToRgbValues(L, C, H) {
|
|
|
473
368
|
let _namedColorHex = null;
|
|
474
369
|
function getNamedColorHex() {
|
|
475
370
|
if (_namedColorHex) return _namedColorHex;
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
["azure", "#f0ffff"],
|
|
482
|
-
["beige", "#f5f5dc"],
|
|
483
|
-
["bisque", "#ffe4c4"],
|
|
484
|
-
["black", "#000000"],
|
|
485
|
-
["blanchedalmond", "#ffebcd"],
|
|
486
|
-
["blue", "#0000ff"],
|
|
487
|
-
["blueviolet", "#8a2be2"],
|
|
488
|
-
["brown", "#a52a2a"],
|
|
489
|
-
["burlywood", "#deb887"],
|
|
490
|
-
["cadetblue", "#5f9ea0"],
|
|
491
|
-
["chartreuse", "#7fff00"],
|
|
492
|
-
["chocolate", "#d2691e"],
|
|
493
|
-
["coral", "#ff7f50"],
|
|
494
|
-
["cornflowerblue", "#6495ed"],
|
|
495
|
-
["cornsilk", "#fff8dc"],
|
|
496
|
-
["crimson", "#dc143c"],
|
|
497
|
-
["cyan", "#00ffff"],
|
|
498
|
-
["darkblue", "#00008b"],
|
|
499
|
-
["darkcyan", "#008b8b"],
|
|
500
|
-
["darkgoldenrod", "#b8860b"],
|
|
501
|
-
["darkgray", "#a9a9a9"],
|
|
502
|
-
["darkgreen", "#006400"],
|
|
503
|
-
["darkgrey", "#a9a9a9"],
|
|
504
|
-
["darkkhaki", "#bdb76b"],
|
|
505
|
-
["darkmagenta", "#8b008b"],
|
|
506
|
-
["darkolivegreen", "#556b2f"],
|
|
507
|
-
["darkorange", "#ff8c00"],
|
|
508
|
-
["darkorchid", "#9932cc"],
|
|
509
|
-
["darkred", "#8b0000"],
|
|
510
|
-
["darksalmon", "#e9967a"],
|
|
511
|
-
["darkseagreen", "#8fbc8f"],
|
|
512
|
-
["darkslateblue", "#483d8b"],
|
|
513
|
-
["darkslategray", "#2f4f4f"],
|
|
514
|
-
["darkslategrey", "#2f4f4f"],
|
|
515
|
-
["darkturquoise", "#00ced1"],
|
|
516
|
-
["darkviolet", "#9400d3"],
|
|
517
|
-
["deeppink", "#ff1493"],
|
|
518
|
-
["deepskyblue", "#00bfff"],
|
|
519
|
-
["dimgray", "#696969"],
|
|
520
|
-
["dimgrey", "#696969"],
|
|
521
|
-
["dodgerblue", "#1e90ff"],
|
|
522
|
-
["firebrick", "#b22222"],
|
|
523
|
-
["floralwhite", "#fffaf0"],
|
|
524
|
-
["forestgreen", "#228b22"],
|
|
525
|
-
["fuchsia", "#ff00ff"],
|
|
526
|
-
["gainsboro", "#dcdcdc"],
|
|
527
|
-
["ghostwhite", "#f8f8ff"],
|
|
528
|
-
["gold", "#ffd700"],
|
|
529
|
-
["goldenrod", "#daa520"],
|
|
530
|
-
["gray", "#808080"],
|
|
531
|
-
["green", "#008000"],
|
|
532
|
-
["greenyellow", "#adff2f"],
|
|
533
|
-
["grey", "#808080"],
|
|
534
|
-
["honeydew", "#f0fff0"],
|
|
535
|
-
["hotpink", "#ff69b4"],
|
|
536
|
-
["indianred", "#cd5c5c"],
|
|
537
|
-
["indigo", "#4b0082"],
|
|
538
|
-
["ivory", "#fffff0"],
|
|
539
|
-
["khaki", "#f0e68c"],
|
|
540
|
-
["lavender", "#e6e6fa"],
|
|
541
|
-
["lavenderblush", "#fff0f5"],
|
|
542
|
-
["lawngreen", "#7cfc00"],
|
|
543
|
-
["lemonchiffon", "#fffacd"],
|
|
544
|
-
["lightblue", "#add8e6"],
|
|
545
|
-
["lightcoral", "#f08080"],
|
|
546
|
-
["lightcyan", "#e0ffff"],
|
|
547
|
-
["lightgoldenrodyellow", "#fafad2"],
|
|
548
|
-
["lightgray", "#d3d3d3"],
|
|
549
|
-
["lightgreen", "#90ee90"],
|
|
550
|
-
["lightgrey", "#d3d3d3"],
|
|
551
|
-
["lightpink", "#ffb6c1"],
|
|
552
|
-
["lightsalmon", "#ffa07a"],
|
|
553
|
-
["lightseagreen", "#20b2aa"],
|
|
554
|
-
["lightskyblue", "#87cefa"],
|
|
555
|
-
["lightslategray", "#778899"],
|
|
556
|
-
["lightslategrey", "#778899"],
|
|
557
|
-
["lightsteelblue", "#b0c4de"],
|
|
558
|
-
["lightyellow", "#ffffe0"],
|
|
559
|
-
["lime", "#00ff00"],
|
|
560
|
-
["limegreen", "#32cd32"],
|
|
561
|
-
["linen", "#faf0e6"],
|
|
562
|
-
["magenta", "#ff00ff"],
|
|
563
|
-
["maroon", "#800000"],
|
|
564
|
-
["mediumaquamarine", "#66cdaa"],
|
|
565
|
-
["mediumblue", "#0000cd"],
|
|
566
|
-
["mediumorchid", "#ba55d3"],
|
|
567
|
-
["mediumpurple", "#9370db"],
|
|
568
|
-
["mediumseagreen", "#3cb371"],
|
|
569
|
-
["mediumslateblue", "#7b68ee"],
|
|
570
|
-
["mediumspringgreen", "#00fa9a"],
|
|
571
|
-
["mediumturquoise", "#48d1cc"],
|
|
572
|
-
["mediumvioletred", "#c71585"],
|
|
573
|
-
["midnightblue", "#191970"],
|
|
574
|
-
["mintcream", "#f5fffa"],
|
|
575
|
-
["mistyrose", "#ffe4e1"],
|
|
576
|
-
["moccasin", "#ffe4b5"],
|
|
577
|
-
["navajowhite", "#ffdead"],
|
|
578
|
-
["navy", "#000080"],
|
|
579
|
-
["oldlace", "#fdf5e6"],
|
|
580
|
-
["olive", "#808000"],
|
|
581
|
-
["olivedrab", "#6b8e23"],
|
|
582
|
-
["orange", "#ffa500"],
|
|
583
|
-
["orangered", "#ff4500"],
|
|
584
|
-
["orchid", "#da70d6"],
|
|
585
|
-
["palegoldenrod", "#eee8aa"],
|
|
586
|
-
["palegreen", "#98fb98"],
|
|
587
|
-
["paleturquoise", "#afeeee"],
|
|
588
|
-
["palevioletred", "#db7093"],
|
|
589
|
-
["papayawhip", "#ffefd5"],
|
|
590
|
-
["peachpuff", "#ffdab9"],
|
|
591
|
-
["peru", "#cd853f"],
|
|
592
|
-
["pink", "#ffc0cb"],
|
|
593
|
-
["plum", "#dda0dd"],
|
|
594
|
-
["powderblue", "#b0e0e6"],
|
|
595
|
-
["purple", "#800080"],
|
|
596
|
-
["rebeccapurple", "#663399"],
|
|
597
|
-
["red", "#ff0000"],
|
|
598
|
-
["rosybrown", "#bc8f8f"],
|
|
599
|
-
["royalblue", "#4169e1"],
|
|
600
|
-
["saddlebrown", "#8b4513"],
|
|
601
|
-
["salmon", "#fa8072"],
|
|
602
|
-
["sandybrown", "#f4a460"],
|
|
603
|
-
["seagreen", "#2e8b57"],
|
|
604
|
-
["seashell", "#fff5ee"],
|
|
605
|
-
["sienna", "#a0522d"],
|
|
606
|
-
["silver", "#c0c0c0"],
|
|
607
|
-
["skyblue", "#87ceeb"],
|
|
608
|
-
["slateblue", "#6a5acd"],
|
|
609
|
-
["slategray", "#708090"],
|
|
610
|
-
["slategrey", "#708090"],
|
|
611
|
-
["snow", "#fffafa"],
|
|
612
|
-
["springgreen", "#00ff7f"],
|
|
613
|
-
["steelblue", "#4682b4"],
|
|
614
|
-
["tan", "#d2b48c"],
|
|
615
|
-
["teal", "#008080"],
|
|
616
|
-
["thistle", "#d8bfd8"],
|
|
617
|
-
["tomato", "#ff6347"],
|
|
618
|
-
["turquoise", "#40e0d0"],
|
|
619
|
-
["violet", "#ee82ee"],
|
|
620
|
-
["wheat", "#f5deb3"],
|
|
621
|
-
["white", "#ffffff"],
|
|
622
|
-
["whitesmoke", "#f5f5f5"],
|
|
623
|
-
["yellow", "#ffff00"],
|
|
624
|
-
["yellowgreen", "#9acd32"]
|
|
625
|
-
]);
|
|
626
|
-
return _namedColorHex;
|
|
371
|
+
const names = "aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple rebeccapurple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen".split(" ");
|
|
372
|
+
const hex = "f0f8fffaebd700ffff7fffd4f0fffff5f5dcffe4c4000000ffebcd0000ff8a2be2a52a2adeb8875f9ea07fff00d2691eff7f506495edfff8dcdc143c00ffff00008b008b8bb8860ba9a9a9006400a9a9a9bdb76b8b008b556b2fff8c009932cc8b0000e9967a8fbc8f483d8b2f4f4f2f4f4f00ced19400d3ff149300bfff6969696969691e90ffb22222fffaf0228b22ff00ffdcdcdcf8f8ffffd700daa520808080008000adff2f808080f0fff0ff69b4cd5c5c4b0082fffff0f0e68ce6e6fafff0f57cfc00fffacdadd8e6f08080e0fffffafad2d3d3d390ee90d3d3d3ffb6c1ffa07a20b2aa87cefa778899778899b0c4deffffe000ff0032cd32faf0e6ff00ff80000066cdaa0000cdba55d39370db3cb3717b68ee00fa9a48d1ccc71585191970f5fffaffe4e1ffe4b5ffdead000080fdf5e68080006b8e23ffa500ff4500da70d6eee8aa98fb98afeeeedb7093ffefd5ffdab9cd853fffc0cbdda0ddb0e0e6800080663399ff0000bc8f8f4169e18b4513fa8072f4a4602e8b57fff5eea0522dc0c0c087ceeb6a5acd708090708090fffafa00ff7f4682b4d2b48c008080d8bfd8ff634740e0d0ee82eef5deb3fffffff5f5f5ffff009acd32";
|
|
373
|
+
const colors = /* @__PURE__ */ new Map();
|
|
374
|
+
for (let i = 0; i < names.length; i++) colors.set(names[i], `#${hex.slice(i * 6, i * 6 + 6)}`);
|
|
375
|
+
return _namedColorHex = colors;
|
|
627
376
|
}
|
|
628
|
-
/**
|
|
629
|
-
* Convert hex color string to `rgb()` CSS string.
|
|
630
|
-
* Supports 3, 4, 6, and 8 character hex values (with or without `#`).
|
|
631
|
-
*/
|
|
632
377
|
function hexToRgb(hex) {
|
|
633
378
|
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);
|
|
634
379
|
if (!matched) return null;
|
|
@@ -637,13 +382,6 @@ function hexToRgb(hex) {
|
|
|
637
382
|
if (rgba.length >= 3) return `rgb(${rgba.slice(0, 3).join(" ")}${rgba.length > 3 ? ` / ${rgba[3]}` : ""})`;
|
|
638
383
|
return null;
|
|
639
384
|
}
|
|
640
|
-
/**
|
|
641
|
-
* Extract RGB values from an `rgb()`/`rgba()` string.
|
|
642
|
-
* Supports comma-separated, space-separated, fractional, percentage,
|
|
643
|
-
* and slash alpha notation.
|
|
644
|
-
*
|
|
645
|
-
* @returns Array of RGB values (0-255 range), converting percentages as needed.
|
|
646
|
-
*/
|
|
647
385
|
function getRgbValuesFromRgbaString(str) {
|
|
648
386
|
const match = str.match(/rgba?\(([^)]+)\)/i);
|
|
649
387
|
if (!match) return [];
|
|
@@ -654,11 +392,6 @@ function getRgbValuesFromRgbaString(str) {
|
|
|
654
392
|
return parseFloat(part);
|
|
655
393
|
});
|
|
656
394
|
}
|
|
657
|
-
/**
|
|
658
|
-
* Convert any recognized color string to an `rgb()` CSS string.
|
|
659
|
-
* Handles hex, `okhsl()`, `okhst()`, `hsl()`/`hsla()`, named CSS colors,
|
|
660
|
-
* and `rgb()`/`rgba()` pass-through.
|
|
661
|
-
*/
|
|
662
395
|
function strToRgb(color, _ignoreAlpha = false) {
|
|
663
396
|
if (!color) return void 0;
|
|
664
397
|
if (color.startsWith("rgb")) return color;
|
|
@@ -669,11 +402,6 @@ function strToRgb(color, _ignoreAlpha = false) {
|
|
|
669
402
|
if (namedHex) return hexToRgb(namedHex);
|
|
670
403
|
return null;
|
|
671
404
|
}
|
|
672
|
-
/**
|
|
673
|
-
* Convert an HSL/HSLA color string to an `rgb()`/`rgba()` CSS string.
|
|
674
|
-
* Supports modern space-separated and legacy comma-separated syntax,
|
|
675
|
-
* deg/turn/rad hue units, and slash alpha notation.
|
|
676
|
-
*/
|
|
677
405
|
function hslStringToRgb(hslStr) {
|
|
678
406
|
const match = hslStr.match(/hsla?\(([^)]+)\)/i);
|
|
679
407
|
if (!match) return null;
|
|
@@ -699,10 +427,6 @@ function hslStringToRgb(hslStr) {
|
|
|
699
427
|
}
|
|
700
428
|
return `rgb(${Math.round(r)} ${Math.round(g)} ${Math.round(b)})`;
|
|
701
429
|
}
|
|
702
|
-
/**
|
|
703
|
-
* Convert an `oklch()` color string to an `rgb()`/`rgba()` CSS string.
|
|
704
|
-
* Supports deg/turn/rad hue units and percentage lightness.
|
|
705
|
-
*/
|
|
706
430
|
function oklchStringToRgb(oklchStr) {
|
|
707
431
|
const match = oklchStr.match(/oklch\(([^)]+)\)/i);
|
|
708
432
|
if (!match) return null;
|
|
@@ -729,62 +453,13 @@ function oklchStringToRgb(oklchStr) {
|
|
|
729
453
|
}
|
|
730
454
|
//#endregion
|
|
731
455
|
//#region src/utils/color-space.ts
|
|
732
|
-
/**
|
|
733
|
-
* Set the alpha of a whole color, replacing any it already carries.
|
|
734
|
-
*
|
|
735
|
-
* CSS relative color syntax is how opacity is applied to every color Tasty
|
|
736
|
-
* emits. `oklch(from <color> l c h / <alpha>)` copies the channels over and
|
|
737
|
-
* writes the alpha slot, which needs nothing from the color except that it *is*
|
|
738
|
-
* a color: a `color-mix()`, a `light-dark()`, a `currentcolor`, a
|
|
739
|
-
* `--name-color` written by hand-authored CSS that Tasty never defined — all of
|
|
740
|
-
* them work, where writing into a channel slot directly would require channels
|
|
741
|
-
* the engine has no way to compute.
|
|
742
|
-
*
|
|
743
|
-
* Alpha is *replaced*, not composed. A token holding `rgb(255 0 0 / .8)` faded
|
|
744
|
-
* to `.5` is alpha `.5`. `color-mix()` against `transparent` cannot do this —
|
|
745
|
-
* it would multiply the two to `.4`.
|
|
746
|
-
*
|
|
747
|
-
* The alpha slot takes a `<number>` or a `<percentage>`, so an opacity custom
|
|
748
|
-
* property passes straight through in whichever form the author declared it.
|
|
749
|
-
*
|
|
750
|
-
* The space is always `oklch`, regardless of the configured {@link ColorSpace}:
|
|
751
|
-
* it is unbounded, so a wide-gamut color survives the round trip that a
|
|
752
|
-
* gamut-limited space would clamp, and it is the space the computed value used
|
|
753
|
-
* to be reported in. Channels are copied rather than interpolated, so the polar
|
|
754
|
-
* form costs nothing even for an achromatic color, whose hue is carried through
|
|
755
|
-
* untouched.
|
|
756
|
-
*/
|
|
757
456
|
function overrideColorAlpha(color, alpha) {
|
|
758
457
|
return `oklch(from ${color} l c h / ${alpha})`;
|
|
759
458
|
}
|
|
760
|
-
/**
|
|
761
|
-
* Compose an alpha onto a color, multiplying with any it already carries.
|
|
762
|
-
*
|
|
763
|
-
* This is the counterpart to {@link overrideColorAlpha}, and the difference is
|
|
764
|
-
* the point. A design token names a color, so fading it *sets* its alpha. But
|
|
765
|
-
* `currentcolor` is the color an element **inherits**, which an ancestor may
|
|
766
|
-
* already have faded — `#current.4` there means "40% of what reaches me", and a
|
|
767
|
-
* nested `#current.18` under it composes to `.072`. Design systems build ramps
|
|
768
|
-
* out of exactly that, so `#current` composes and a token replaces.
|
|
769
|
-
*
|
|
770
|
-
* `color-mix()` against `transparent` is what composes: mixing premultiplied
|
|
771
|
-
* leaves the channels alone and multiplies the alphas. Its percentage slot takes
|
|
772
|
-
* no `<number>`, so a `$prop` alpha has to be scaled — which is why an opacity
|
|
773
|
-
* property used as `#current.$prop` has to hold a unitless number, where a token
|
|
774
|
-
* accepts either form.
|
|
775
|
-
*/
|
|
776
459
|
function mixColorAlpha(color, percentage) {
|
|
777
460
|
return `color-mix(in oklab, ${color} ${percentage}, transparent)`;
|
|
778
461
|
}
|
|
779
|
-
/**
|
|
780
|
-
* Matches what {@link overrideColorAlpha} builds. The first group is greedy so a
|
|
781
|
-
* nested override splits on its outermost layer.
|
|
782
|
-
*/
|
|
783
462
|
const RE_ALPHA_OVERRIDE = /^oklch\(from (.+) l c h \/ (.+)\)$/;
|
|
784
|
-
/**
|
|
785
|
-
* Split what {@link overrideColorAlpha} builds back into the color it faded and
|
|
786
|
-
* the alpha, or `null` when the value is not one of those.
|
|
787
|
-
*/
|
|
788
463
|
function parseAlphaOverride(value) {
|
|
789
464
|
const match = value.match(RE_ALPHA_OVERRIDE);
|
|
790
465
|
return match ? {
|
|
@@ -810,49 +485,16 @@ const makeEmptyDetails = () => ({
|
|
|
810
485
|
all: [],
|
|
811
486
|
parts: []
|
|
812
487
|
});
|
|
813
|
-
const finalizePart = (p) => {
|
|
814
|
-
p.output = p.all.join(" ");
|
|
815
|
-
return p;
|
|
816
|
-
};
|
|
817
|
-
/**
|
|
818
|
-
* Aggregate parts into a StyleDetails group.
|
|
819
|
-
* Combines all parts' arrays into group-level arrays for backward compatibility.
|
|
820
|
-
*/
|
|
821
|
-
const finalizeGroup = (d, parts) => {
|
|
822
|
-
d.parts = parts;
|
|
823
|
-
for (const part of parts) {
|
|
824
|
-
d.mods.push(...part.mods);
|
|
825
|
-
d.values.push(...part.values);
|
|
826
|
-
d.colors.push(...part.colors);
|
|
827
|
-
d.all.push(...part.all);
|
|
828
|
-
}
|
|
829
|
-
d.output = parts.map((p) => p.output).join(" / ");
|
|
830
|
-
return d;
|
|
831
|
-
};
|
|
832
488
|
//#endregion
|
|
833
489
|
//#region src/parser/classify.ts
|
|
834
|
-
/**
|
|
835
|
-
* Convert an opacity suffix to the alpha value it denotes.
|
|
836
|
-
*
|
|
837
|
-
* The authored digits are kept verbatim — `.07` stays `.07` rather than being
|
|
838
|
-
* multiplied into `7.000000000000001%` — and a `$prop` suffix passes the
|
|
839
|
-
* reference straight through, so it works whether the property holds a
|
|
840
|
-
* `<number>` or a `<percentage>`. Both are what the alpha slot accepts.
|
|
841
|
-
*/
|
|
842
490
|
function alphaSuffixToAlpha(rawAlpha) {
|
|
843
491
|
if (rawAlpha.startsWith("$")) return `var(--${rawAlpha.slice(1)})`;
|
|
844
492
|
if (rawAlpha === "0") return "0";
|
|
845
493
|
return `.${rawAlpha}`;
|
|
846
494
|
}
|
|
847
|
-
/** Apply an opacity suffix to a color, replacing any alpha it already carries. */
|
|
848
495
|
function fadeColor(color, rawAlpha) {
|
|
849
496
|
return overrideColorAlpha(color, alphaSuffixToAlpha(rawAlpha));
|
|
850
497
|
}
|
|
851
|
-
/**
|
|
852
|
-
* Convert an opacity suffix to the percentage `color-mix()` needs, by shifting
|
|
853
|
-
* the decimal point rather than multiplying: `.07` is `7%`, not the
|
|
854
|
-
* `7.000000000000001%` that `parseFloat('.07') * 100` produces.
|
|
855
|
-
*/
|
|
856
498
|
function alphaSuffixToPercentage(rawAlpha) {
|
|
857
499
|
if (rawAlpha.startsWith("$")) return `calc(var(--${rawAlpha.slice(1)}) * 100%)`;
|
|
858
500
|
if (rawAlpha === "0") return "0%";
|
|
@@ -861,28 +503,13 @@ function alphaSuffixToPercentage(rawAlpha) {
|
|
|
861
503
|
const fraction = digits.slice(2);
|
|
862
504
|
return `${fraction ? `${whole}.${fraction}` : whole}%`;
|
|
863
505
|
}
|
|
864
|
-
/**
|
|
865
|
-
* Apply an opacity suffix to `currentcolor`, composing with any alpha an
|
|
866
|
-
* ancestor already applied. See {@link mixColorAlpha} for why this differs from
|
|
867
|
-
* how a token is faded.
|
|
868
|
-
*/
|
|
869
506
|
function fadeCurrentColor(rawAlpha) {
|
|
870
507
|
return mixColorAlpha("currentcolor", alphaSuffixToPercentage(rawAlpha));
|
|
871
508
|
}
|
|
872
|
-
/**
|
|
873
|
-
* Whether parsed function arguments hold a color. Colors reach either the color
|
|
874
|
-
* bucket (`#token`, a nested color function, `transparent`) or — for the CSS
|
|
875
|
-
* named colors, which the parser has no token syntax for — the modifier bucket.
|
|
876
|
-
*/
|
|
877
509
|
function hasColorArgs(parsed) {
|
|
878
510
|
const namedColors = getNamedColorHex();
|
|
879
511
|
return parsed.groups.some((group) => group.colors.length > 0 || group.mods.some((mod) => namedColors.has(mod)));
|
|
880
512
|
}
|
|
881
|
-
/**
|
|
882
|
-
* Re-parses a value through the parser until it stabilizes (no changes)
|
|
883
|
-
* or max iterations reached. This allows units to reference other units.
|
|
884
|
-
* Example: { x: '8px', y: '2x' } -> '1y' resolves to '16px'
|
|
885
|
-
*/
|
|
886
513
|
function resolveUntilStable(value, opts, recurse, maxIterations = 10) {
|
|
887
514
|
let current = value;
|
|
888
515
|
for (let i = 0; i < maxIterations; i++) {
|
|
@@ -902,7 +529,7 @@ function classify(raw, opts, recurse) {
|
|
|
902
529
|
bucket: 2,
|
|
903
530
|
processed: ""
|
|
904
531
|
};
|
|
905
|
-
{
|
|
532
|
+
if (token.includes("(")) {
|
|
906
533
|
let depth = 0;
|
|
907
534
|
let inQuote = 0;
|
|
908
535
|
for (let i = 0; i < token.length; i++) {
|
|
@@ -916,7 +543,7 @@ function classify(raw, opts, recurse) {
|
|
|
916
543
|
continue;
|
|
917
544
|
}
|
|
918
545
|
if (ch === "(") depth++;
|
|
919
|
-
else if (ch === ")"
|
|
546
|
+
else if (ch === ")" && depth) depth--;
|
|
920
547
|
}
|
|
921
548
|
if (depth !== 0) {
|
|
922
549
|
console.warn("[Tasty] skipped invalid function token with unmatched parentheses:", token);
|
|
@@ -1212,15 +839,6 @@ function classify(raw, opts, recurse) {
|
|
|
1212
839
|
}
|
|
1213
840
|
//#endregion
|
|
1214
841
|
//#region src/parser/lru.ts
|
|
1215
|
-
/**
|
|
1216
|
-
* Doubly-linked-list LRU.
|
|
1217
|
-
*
|
|
1218
|
-
* The list holds direct node references rather than keys, so rewiring on a
|
|
1219
|
-
* `get()` of a non-MRU entry is pure pointer work. Storing keys instead cost
|
|
1220
|
-
* three extra `Map.get()` lookups per read (prev, next and the current head),
|
|
1221
|
-
* which is measurable on these read-mostly caches: they are hit on every
|
|
1222
|
-
* render once the style pipeline is warm.
|
|
1223
|
-
*/
|
|
1224
842
|
var Lru = class {
|
|
1225
843
|
limit;
|
|
1226
844
|
map = /* @__PURE__ */ new Map();
|
|
@@ -1305,7 +923,6 @@ var Lru = class {
|
|
|
1305
923
|
const isWhitespace = (ch) => ch === " " || ch === "\n" || ch === " " || ch === "\r" || ch === "\f";
|
|
1306
924
|
function scan(src, cb) {
|
|
1307
925
|
let depth = 0;
|
|
1308
|
-
let inUrl = false;
|
|
1309
926
|
let inQuote = 0;
|
|
1310
927
|
let start = 0;
|
|
1311
928
|
let i = 0;
|
|
@@ -1313,11 +930,9 @@ function scan(src, cb) {
|
|
|
1313
930
|
const flush = (isComma, isSlash) => {
|
|
1314
931
|
const actualSlash = isSlash || pendingSlash;
|
|
1315
932
|
pendingSlash = false;
|
|
1316
|
-
if (start < i)
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
} else if (isComma) cb("", true, false, null);
|
|
1320
|
-
else if (actualSlash) cb("", false, true, null);
|
|
933
|
+
if (start < i) cb(src.slice(start, i), isComma, actualSlash);
|
|
934
|
+
else if (isComma) cb("", true, false);
|
|
935
|
+
else if (actualSlash) cb("", false, true);
|
|
1321
936
|
start = i + 1;
|
|
1322
937
|
};
|
|
1323
938
|
for (; i < src.length; i++) {
|
|
@@ -1331,18 +946,13 @@ function scan(src, cb) {
|
|
|
1331
946
|
continue;
|
|
1332
947
|
}
|
|
1333
948
|
if (ch === "(") {
|
|
1334
|
-
if (!depth) {
|
|
1335
|
-
if (src.slice(Math.max(0, i - 3), i + 1) === "url(") inUrl = true;
|
|
1336
|
-
}
|
|
1337
949
|
depth++;
|
|
1338
950
|
continue;
|
|
1339
951
|
}
|
|
1340
952
|
if (ch === ")") {
|
|
1341
|
-
|
|
1342
|
-
if (inUrl && depth === 0) inUrl = false;
|
|
953
|
+
if (depth) depth--;
|
|
1343
954
|
continue;
|
|
1344
955
|
}
|
|
1345
|
-
if (inUrl) continue;
|
|
1346
956
|
if (!depth) {
|
|
1347
957
|
if (ch === ",") {
|
|
1348
958
|
flush(true, false);
|
|
@@ -1386,14 +996,9 @@ var StyleParser = class {
|
|
|
1386
996
|
let parts = [];
|
|
1387
997
|
const pushToken = (bucket, processed) => {
|
|
1388
998
|
if (!processed) return;
|
|
1389
|
-
const mergeIntoPrevUrl = () => {
|
|
1390
|
-
const lastIdx = currentPart.values.length - 1;
|
|
1391
|
-
currentPart.values[lastIdx] += ` ${processed}`;
|
|
1392
|
-
const lastAllIdx = currentPart.all.length - 1;
|
|
1393
|
-
currentPart.all[lastAllIdx] += ` ${processed}`;
|
|
1394
|
-
};
|
|
1395
999
|
if (currentPart.values.length > 0 && currentPart.values[currentPart.values.length - 1].startsWith("url(")) {
|
|
1396
|
-
|
|
1000
|
+
currentPart.values[currentPart.values.length - 1] += ` ${processed}`;
|
|
1001
|
+
currentPart.all[currentPart.all.length - 1] += ` ${processed}`;
|
|
1397
1002
|
return;
|
|
1398
1003
|
}
|
|
1399
1004
|
switch (bucket) {
|
|
@@ -1413,26 +1018,31 @@ var StyleParser = class {
|
|
|
1413
1018
|
}
|
|
1414
1019
|
currentPart.all.push(processed);
|
|
1415
1020
|
};
|
|
1416
|
-
const endPart = () => {
|
|
1021
|
+
const endPart = (reset = true) => {
|
|
1417
1022
|
if (currentPart.all.length > 0) {
|
|
1418
|
-
|
|
1023
|
+
currentPart.output = currentPart.all.join(" ");
|
|
1419
1024
|
parts.push(currentPart);
|
|
1420
1025
|
}
|
|
1421
|
-
currentPart = makeEmptyPart();
|
|
1026
|
+
if (reset) currentPart = makeEmptyPart();
|
|
1422
1027
|
};
|
|
1423
|
-
const endGroup = () => {
|
|
1424
|
-
endPart();
|
|
1425
|
-
if (parts.length === 0)
|
|
1426
|
-
|
|
1427
|
-
|
|
1028
|
+
const endGroup = (reset = true) => {
|
|
1029
|
+
endPart(reset);
|
|
1030
|
+
if (parts.length === 0) parts.push(makeEmptyPart());
|
|
1031
|
+
currentGroup.parts = parts;
|
|
1032
|
+
for (const part of parts) {
|
|
1033
|
+
currentGroup.mods.push(...part.mods);
|
|
1034
|
+
currentGroup.values.push(...part.values);
|
|
1035
|
+
currentGroup.colors.push(...part.colors);
|
|
1036
|
+
currentGroup.all.push(...part.all);
|
|
1428
1037
|
}
|
|
1429
|
-
|
|
1038
|
+
currentGroup.output = parts.length === 1 ? parts[0].output : parts.map((part) => part.output).join(" / ");
|
|
1430
1039
|
groups.push(currentGroup);
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1040
|
+
if (reset) {
|
|
1041
|
+
currentGroup = makeEmptyDetails();
|
|
1042
|
+
parts = [];
|
|
1043
|
+
}
|
|
1434
1044
|
};
|
|
1435
|
-
scan(stripped, (tok, isComma, isSlash
|
|
1045
|
+
scan(stripped, (tok, isComma, isSlash) => {
|
|
1436
1046
|
if (tok) {
|
|
1437
1047
|
if (currentGroup.input) currentGroup.input += ` ${tok}`;
|
|
1438
1048
|
else currentGroup.input = tok;
|
|
@@ -1442,9 +1052,9 @@ var StyleParser = class {
|
|
|
1442
1052
|
if (isSlash) endPart();
|
|
1443
1053
|
if (isComma) endGroup();
|
|
1444
1054
|
});
|
|
1445
|
-
if (currentPart.all.length || parts.length || !groups.length) endGroup();
|
|
1055
|
+
if (currentPart.all.length || parts.length || !groups.length) endGroup(false);
|
|
1446
1056
|
const result = {
|
|
1447
|
-
output: groups.map((
|
|
1057
|
+
output: groups.length === 1 ? groups[0].output : groups.map((group) => group.output).join(", "),
|
|
1448
1058
|
groups
|
|
1449
1059
|
};
|
|
1450
1060
|
Object.freeze(result);
|
|
@@ -1464,17 +1074,9 @@ var StyleParser = class {
|
|
|
1464
1074
|
if (patch.cacheSize) this.cache = new Lru(patch.cacheSize);
|
|
1465
1075
|
else this.cache.clear();
|
|
1466
1076
|
}
|
|
1467
|
-
/**
|
|
1468
|
-
* Clear the parser cache.
|
|
1469
|
-
* Call this when external state that affects parsing results has changed
|
|
1470
|
-
* (e.g., predefined tokens).
|
|
1471
|
-
*/
|
|
1472
1077
|
clearCache() {
|
|
1473
1078
|
this.cache.clear();
|
|
1474
1079
|
}
|
|
1475
|
-
/**
|
|
1476
|
-
* Get the current units configuration.
|
|
1477
|
-
*/
|
|
1478
1080
|
getUnits() {
|
|
1479
1081
|
return this.opts.units;
|
|
1480
1082
|
}
|
|
@@ -1482,10 +1084,6 @@ var StyleParser = class {
|
|
|
1482
1084
|
//#endregion
|
|
1483
1085
|
//#region src/plugins/color-func.ts
|
|
1484
1086
|
const clamp = (value, min, max) => Math.max(Math.min(value, max), min);
|
|
1485
|
-
/**
|
|
1486
|
-
* Parse an angle value with optional unit.
|
|
1487
|
-
* Supports: deg, turn, rad, or unitless (treated as degrees).
|
|
1488
|
-
*/
|
|
1489
1087
|
const parseAngle = (value) => {
|
|
1490
1088
|
const match = value.match(/^([+-]?\d*\.?\d+)(deg|turn|rad)?$/);
|
|
1491
1089
|
if (!match) return 0;
|
|
@@ -1496,31 +1094,12 @@ const parseAngle = (value) => {
|
|
|
1496
1094
|
default: return num;
|
|
1497
1095
|
}
|
|
1498
1096
|
};
|
|
1499
|
-
/**
|
|
1500
|
-
* Parse a percentage value (e.g., "50%") to a 0-1 range. A unitless number is
|
|
1501
|
-
* read as the factor it already looks like, so `okhsl(280 .8 .52)` and
|
|
1502
|
-
* `okhsl(280 80% 52%)` are the same color.
|
|
1503
|
-
*/
|
|
1504
1097
|
const parsePercentage = (value) => {
|
|
1505
1098
|
const match = value.match(/^([+-]?\d*\.?\d+)%?$/);
|
|
1506
1099
|
if (!match) return 0;
|
|
1507
1100
|
const num = parseFloat(match[1]);
|
|
1508
1101
|
return value.includes("%") ? num / 100 : num;
|
|
1509
1102
|
};
|
|
1510
|
-
/**
|
|
1511
|
-
* Creates a color function handler for the tasty parser.
|
|
1512
|
-
*
|
|
1513
|
-
* A color function is a custom `functions` entry that converts its arguments
|
|
1514
|
-
* to an `rgb(...)` string (an already-supported color), so it needs no special
|
|
1515
|
-
* core integration — registering it as a parse function is enough.
|
|
1516
|
-
*
|
|
1517
|
-
* @param name The name of the color function (e.g., 'okhsl', 'okhst')
|
|
1518
|
-
* @param convert Converts the parsed first three channel values (after angle/
|
|
1519
|
-
* percent normalization) to sRGB `[r, g, b]` in the 0-1 range
|
|
1520
|
-
* @param label Optional diagnostic label shown in dev warnings when the wrong
|
|
1521
|
-
* number of arguments is supplied (e.g., 'H S L'). Has no effect on parsing
|
|
1522
|
-
* or output.
|
|
1523
|
-
*/
|
|
1524
1103
|
function createColorFunc(name, convert, label) {
|
|
1525
1104
|
const conversionCache = new Lru(500);
|
|
1526
1105
|
const expected = label ? ` (${label})` : "";
|
|
@@ -1552,124 +1131,26 @@ function createColorFunc(name, convert, label) {
|
|
|
1552
1131
|
}
|
|
1553
1132
|
//#endregion
|
|
1554
1133
|
//#region src/plugins/okhsl-plugin.ts
|
|
1555
|
-
/**
|
|
1556
|
-
* OKHSL Plugin for Tasty
|
|
1557
|
-
*
|
|
1558
|
-
* Converts OKHSL color syntax to RGB notation.
|
|
1559
|
-
* Supports angle units: deg, turn, rad, or unitless (degrees).
|
|
1560
|
-
*
|
|
1561
|
-
* Examples:
|
|
1562
|
-
* okhsl(240.5 50% 50%)
|
|
1563
|
-
* okhsl(240.5deg 50% 50%)
|
|
1564
|
-
* okhsl(0.25turn 50% 50%)
|
|
1565
|
-
* okhsl(1.57rad 50% 50%)
|
|
1566
|
-
*/
|
|
1567
|
-
/**
|
|
1568
|
-
* The okhsl function handler for tasty parser.
|
|
1569
|
-
* Receives parsed style groups and returns an RGB color string.
|
|
1570
|
-
*/
|
|
1571
1134
|
const okhslFunction = createColorFunc("okhsl", okhslToSrgb, "H S L");
|
|
1572
|
-
/**
|
|
1573
|
-
* OKHSL Plugin for Tasty.
|
|
1574
|
-
*
|
|
1575
|
-
* Adds support for the `okhsl()` color function in tasty styles.
|
|
1576
|
-
*
|
|
1577
|
-
* @example
|
|
1578
|
-
* ```ts
|
|
1579
|
-
* import { configure } from '@tenphi/tasty';
|
|
1580
|
-
* import { okhslPlugin } from '@tenphi/tasty';
|
|
1581
|
-
*
|
|
1582
|
-
* configure({
|
|
1583
|
-
* plugins: [okhslPlugin()],
|
|
1584
|
-
* });
|
|
1585
|
-
*
|
|
1586
|
-
* // Now you can use okhsl in styles:
|
|
1587
|
-
* const Box = tasty({
|
|
1588
|
-
* styles: {
|
|
1589
|
-
* fill: 'okhsl(240 50% 50%)',
|
|
1590
|
-
* },
|
|
1591
|
-
* });
|
|
1592
|
-
* ```
|
|
1593
|
-
*/
|
|
1594
1135
|
const okhslPlugin = () => ({
|
|
1595
1136
|
name: "okhsl",
|
|
1596
1137
|
functions: { okhsl: okhslFunction }
|
|
1597
1138
|
});
|
|
1598
1139
|
//#endregion
|
|
1599
1140
|
//#region src/plugins/okhst-plugin.ts
|
|
1600
|
-
/**
|
|
1601
|
-
* OKHST Plugin for Tasty
|
|
1602
|
-
*
|
|
1603
|
-
* Converts OKHST color syntax to RGB notation.
|
|
1604
|
-
* OKHST is OKHSL with the lightness axis replaced by a contrast-uniform tone axis.
|
|
1605
|
-
* Supports angle units: deg, turn, rad, or unitless (degrees).
|
|
1606
|
-
*
|
|
1607
|
-
* Examples:
|
|
1608
|
-
* okhst(240.5 50% 50%)
|
|
1609
|
-
* okhst(240.5deg 50% 50%)
|
|
1610
|
-
* okhst(0.25turn 50% 50%)
|
|
1611
|
-
* okhst(1.57rad 50% 50%)
|
|
1612
|
-
*/
|
|
1613
|
-
/**
|
|
1614
|
-
* The okhst function handler for tasty parser.
|
|
1615
|
-
* Receives parsed style groups and returns an RGB color string.
|
|
1616
|
-
*/
|
|
1617
1141
|
const okhstFunction = createColorFunc("okhst", okhstToSrgb, "H S T");
|
|
1618
|
-
/**
|
|
1619
|
-
* OKHST Plugin for Tasty.
|
|
1620
|
-
*
|
|
1621
|
-
* Adds support for the `okhst()` color function in tasty styles.
|
|
1622
|
-
*
|
|
1623
|
-
* @example
|
|
1624
|
-
* ```ts
|
|
1625
|
-
* import { configure } from '@tenphi/tasty';
|
|
1626
|
-
* import { okhstPlugin } from '@tenphi/tasty';
|
|
1627
|
-
*
|
|
1628
|
-
* configure({
|
|
1629
|
-
* plugins: [okhstPlugin()],
|
|
1630
|
-
* });
|
|
1631
|
-
*
|
|
1632
|
-
* // Now you can use okhst in styles:
|
|
1633
|
-
* const Box = tasty({
|
|
1634
|
-
* styles: {
|
|
1635
|
-
* fill: 'okhst(240 50% 50%)',
|
|
1636
|
-
* },
|
|
1637
|
-
* });
|
|
1638
|
-
* ```
|
|
1639
|
-
*/
|
|
1640
1142
|
const okhstPlugin = () => ({
|
|
1641
1143
|
name: "okhst",
|
|
1642
1144
|
functions: { okhst: okhstFunction }
|
|
1643
1145
|
});
|
|
1644
1146
|
//#endregion
|
|
1645
1147
|
//#region src/plugins/defaults.ts
|
|
1646
|
-
/**
|
|
1647
|
-
* Register the default color functions (okhsl, okhst) with the global parser.
|
|
1648
|
-
*
|
|
1649
|
-
* They are ordinary `functions` entries — the same mechanism any third-party
|
|
1650
|
-
* color plugin uses — so they need no special-casing in core.
|
|
1651
|
-
*
|
|
1652
|
-
* Idempotent and safe to call from the lazy parser initializer so that
|
|
1653
|
-
* zero-config usage keeps working. `resetGlobalParseFunctions()` re-invokes it
|
|
1654
|
-
* after clearing user-registered functions so the defaults survive a config reset.
|
|
1655
|
-
*
|
|
1656
|
-
* @internal
|
|
1657
|
-
*/
|
|
1658
1148
|
function registerDefaultFunctions() {
|
|
1659
1149
|
customFunction("okhsl", okhslFunction);
|
|
1660
1150
|
customFunction("okhst", okhstFunction);
|
|
1661
1151
|
}
|
|
1662
1152
|
//#endregion
|
|
1663
1153
|
//#region src/utils/styles.ts
|
|
1664
|
-
/**
|
|
1665
|
-
* Normalize a color token value.
|
|
1666
|
-
* - Boolean `true` is converted to `'transparent'`
|
|
1667
|
-
* - Boolean `false` returns `null` (signals the token should be skipped)
|
|
1668
|
-
* - Other values are returned as-is
|
|
1669
|
-
*
|
|
1670
|
-
* @param value - The raw token value
|
|
1671
|
-
* @returns Normalized value or null if the token should be skipped
|
|
1672
|
-
*/
|
|
1673
1154
|
function normalizeColorTokenValue(value) {
|
|
1674
1155
|
if (value === true) return "transparent";
|
|
1675
1156
|
if (value === false) return null;
|
|
@@ -1734,60 +1215,22 @@ function getOrCreateParser() {
|
|
|
1734
1215
|
return __tastyParser;
|
|
1735
1216
|
}
|
|
1736
1217
|
const __tastyParseFunctions = {};
|
|
1737
|
-
/**
|
|
1738
|
-
* Register a parse-time function.
|
|
1739
|
-
*
|
|
1740
|
-
* @internal Use `configure({ functions })`. This bypasses the configuration lock
|
|
1741
|
-
* and is kept only for the lazy default-function bootstrap and the `@function`
|
|
1742
|
-
* polyfill, both of which must register after `configure()` has run.
|
|
1743
|
-
*/
|
|
1744
1218
|
function customFunction(name, fn) {
|
|
1745
1219
|
__tastyParseFunctions[name] = fn;
|
|
1746
1220
|
getOrCreateParser().setFunctions(__tastyParseFunctions);
|
|
1747
1221
|
}
|
|
1748
|
-
/**
|
|
1749
|
-
* Reset parse functions back to the built-in set (okhsl/okhst).
|
|
1750
|
-
*
|
|
1751
|
-
* @internal Called by `resetConfig()`.
|
|
1752
|
-
*/
|
|
1753
1222
|
function resetGlobalParseFunctions() {
|
|
1754
1223
|
for (const key of Object.keys(__tastyParseFunctions)) delete __tastyParseFunctions[key];
|
|
1755
1224
|
registerDefaultFunctions();
|
|
1756
1225
|
getOrCreateParser().setFunctions(__tastyParseFunctions);
|
|
1757
1226
|
}
|
|
1758
|
-
/**
|
|
1759
|
-
* Get the global StyleParser instance.
|
|
1760
|
-
* Used by configure() to apply parser configuration.
|
|
1761
|
-
*/
|
|
1762
1227
|
function getGlobalParser() {
|
|
1763
1228
|
return getOrCreateParser();
|
|
1764
1229
|
}
|
|
1765
|
-
/**
|
|
1766
|
-
* Get the current custom functions registry.
|
|
1767
|
-
* Used by configure() to merge with new functions.
|
|
1768
|
-
*/
|
|
1769
|
-
/**
|
|
1770
|
-
* The live parse-function registry.
|
|
1771
|
-
*
|
|
1772
|
-
* @internal Returns the mutable internal map; writing to it bypasses the
|
|
1773
|
-
* parser's cache invalidation, so the write silently does not take effect.
|
|
1774
|
-
* Read-only, internal use.
|
|
1775
|
-
*/
|
|
1776
1230
|
function getGlobalParseFunctions() {
|
|
1777
1231
|
return __tastyParseFunctions;
|
|
1778
1232
|
}
|
|
1779
|
-
/**
|
|
1780
|
-
* Storage for predefined tokens that are replaced during style parsing.
|
|
1781
|
-
* Keys are token names (with $ or # prefix), values are pre-processed CSS values.
|
|
1782
|
-
*/
|
|
1783
1233
|
let __globalPredefinedTokens = null;
|
|
1784
|
-
/**
|
|
1785
|
-
* Set global predefined tokens.
|
|
1786
|
-
* Called from configure() after processing token values.
|
|
1787
|
-
* Merges with existing tokens (new tokens override existing ones with same key).
|
|
1788
|
-
* Keys are normalized to lowercase (parser lowercases input before classification).
|
|
1789
|
-
* @internal
|
|
1790
|
-
*/
|
|
1791
1234
|
function setGlobalPredefinedTokens(tokens) {
|
|
1792
1235
|
const normalizedTokens = {};
|
|
1793
1236
|
for (const [key, value] of Object.entries(tokens)) {
|
|
@@ -1805,28 +1248,13 @@ function setGlobalPredefinedTokens(tokens) {
|
|
|
1805
1248
|
} : normalizedTokens;
|
|
1806
1249
|
getOrCreateParser().clearCache();
|
|
1807
1250
|
}
|
|
1808
|
-
/**
|
|
1809
|
-
* Get the current global predefined tokens.
|
|
1810
|
-
* Returns null if no tokens are configured.
|
|
1811
|
-
*/
|
|
1812
1251
|
function getGlobalPredefinedTokens() {
|
|
1813
1252
|
return __globalPredefinedTokens;
|
|
1814
1253
|
}
|
|
1815
|
-
/**
|
|
1816
|
-
* Reset global predefined tokens.
|
|
1817
|
-
* Used for testing.
|
|
1818
|
-
* @internal
|
|
1819
|
-
*/
|
|
1820
1254
|
function resetGlobalPredefinedTokens() {
|
|
1821
1255
|
__globalPredefinedTokens = null;
|
|
1822
1256
|
getOrCreateParser().clearCache();
|
|
1823
1257
|
}
|
|
1824
|
-
/**
|
|
1825
|
-
*
|
|
1826
|
-
* @param {String} value
|
|
1827
|
-
* @param {Number} mode
|
|
1828
|
-
* @returns {Object<String,String|Array>}
|
|
1829
|
-
*/
|
|
1830
1258
|
function parseStyle(value) {
|
|
1831
1259
|
let str;
|
|
1832
1260
|
if (typeof value === "string") str = value;
|
|
@@ -1834,32 +1262,11 @@ function parseStyle(value) {
|
|
|
1834
1262
|
else str = "";
|
|
1835
1263
|
return getOrCreateParser().process(str);
|
|
1836
1264
|
}
|
|
1837
|
-
/** A `$`-prefixed custom-property reference — the only DSL syntax that starts with `$`. */
|
|
1838
1265
|
const RE_CUSTOM_PROPERTY_REF = /\$[a-zA-Z_$]/;
|
|
1839
|
-
/**
|
|
1840
|
-
* Substitute custom-property references (`$ident` → `var(--ident)`) inside a
|
|
1841
|
-
* value a handler would otherwise emit to CSS verbatim.
|
|
1842
|
-
*
|
|
1843
|
-
* Handlers for keyword-valued properties (`display`, `align`, `text-transform`,
|
|
1844
|
-
* `overflow`, …) pass their input straight through, since there are no units or
|
|
1845
|
-
* color tokens to resolve. That leaked the raw DSL into the stylesheet:
|
|
1846
|
-
* `display: '$my-display'` emitted `display: $my-display`, which the browser
|
|
1847
|
-
* drops as invalid. The same applies to color props whose value the parser could
|
|
1848
|
-
* not classify as a color — `$ident` is a color only when the name ends with
|
|
1849
|
-
* `-color`, so `fill: '$my-fill'` fell back to the unparsed input.
|
|
1850
|
-
*
|
|
1851
|
-
* Values without a `$` skip the parser entirely, so pass-through behaviour (and
|
|
1852
|
-
* the parser's case folding) is unchanged for every value that was already
|
|
1853
|
-
* valid CSS.
|
|
1854
|
-
*/
|
|
1855
1266
|
function resolveCustomProperties(value) {
|
|
1856
1267
|
if (!RE_CUSTOM_PROPERTY_REF.test(value)) return value;
|
|
1857
1268
|
return parseStyle(value).output || value;
|
|
1858
1269
|
}
|
|
1859
|
-
/**
|
|
1860
|
-
* Parse color. Find it value, name and opacity.
|
|
1861
|
-
* Optimized to avoid heavy parseStyle calls for simple color patterns.
|
|
1862
|
-
*/
|
|
1863
1270
|
function parseColor(val, ignoreError = false) {
|
|
1864
1271
|
if (typeof val !== "string") val = String(val ?? "");
|
|
1865
1272
|
val = val.trim();
|
|
@@ -1901,7 +1308,9 @@ function parseColor(val, ignoreError = false) {
|
|
|
1901
1308
|
};
|
|
1902
1309
|
}
|
|
1903
1310
|
function filterMods(mods, allowedMods) {
|
|
1904
|
-
|
|
1311
|
+
const filtered = [];
|
|
1312
|
+
for (const mod of mods) if (allowedMods.includes(mod)) filtered.push(mod);
|
|
1313
|
+
return filtered;
|
|
1905
1314
|
}
|
|
1906
1315
|
const _innerCache = /* @__PURE__ */ new WeakMap();
|
|
1907
1316
|
const _topLevelCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -1942,20 +1351,6 @@ function stringifyStyles(styles) {
|
|
|
1942
1351
|
//#region src/utils/function-color.ts
|
|
1943
1352
|
const RE_FUNC_NAME = /^([a-z][a-z0-9-]*)\s*\(/i;
|
|
1944
1353
|
const RE_COLOR_OUT = /^(?:rgb|hsl|hwb|lab|lch|oklab|oklch|color)\(|^#|^var\(--/i;
|
|
1945
|
-
/**
|
|
1946
|
-
* Resolve a `name(...)` value produced by a registered custom parse function
|
|
1947
|
-
* into its concrete color output.
|
|
1948
|
-
*
|
|
1949
|
-
* A color function is just a `functions` entry whose output is an already
|
|
1950
|
-
* supported color (`rgb`, `hsl`, `#…`, `oklch`, …). This helper delegates the
|
|
1951
|
-
* value to the global parser (which already runs the registered parse function)
|
|
1952
|
-
* and returns the result only when it looks like a color. Returns `null` when
|
|
1953
|
-
* `str` is not a registered custom function or its output is not a color.
|
|
1954
|
-
*
|
|
1955
|
-
* This is the generic replacement for the previously hardcoded okhsl/okhst
|
|
1956
|
-
* conversion branches scattered across `strToRgb`, `resolveToRgbaValues`, and
|
|
1957
|
-
* the `#token.alpha` injection path.
|
|
1958
|
-
*/
|
|
1959
1354
|
function resolveFunctionColor(str) {
|
|
1960
1355
|
const m = RE_FUNC_NAME.exec(str);
|
|
1961
1356
|
if (!m) return null;
|
|
@@ -1973,125 +1368,6 @@ function color(name, opacity = 1) {
|
|
|
1973
1368
|
return `var(--${name}-color)`;
|
|
1974
1369
|
}
|
|
1975
1370
|
//#endregion
|
|
1976
|
-
|
|
1977
|
-
const dotize = {
|
|
1978
|
-
valTypes: {
|
|
1979
|
-
none: "NONE",
|
|
1980
|
-
primitive: "PRIM",
|
|
1981
|
-
object: "OBJECT",
|
|
1982
|
-
array: "ARRAY"
|
|
1983
|
-
},
|
|
1984
|
-
getValType: function(val) {
|
|
1985
|
-
if (!val || typeof val != "object" || Array.isArray(val)) return dotize.valTypes.primitive;
|
|
1986
|
-
if (typeof val == "object") return dotize.valTypes.object;
|
|
1987
|
-
},
|
|
1988
|
-
getPathType: function(arrPath) {
|
|
1989
|
-
const arrPathTypes = [];
|
|
1990
|
-
for (const path in arrPath) {
|
|
1991
|
-
const pathVal = arrPath[path];
|
|
1992
|
-
if (!pathVal) arrPathTypes.push(dotize.valTypes.none);
|
|
1993
|
-
else if (dotize.isNumber(pathVal)) arrPathTypes.push(dotize.valTypes.array);
|
|
1994
|
-
else arrPathTypes.push(dotize.valTypes.object);
|
|
1995
|
-
}
|
|
1996
|
-
return arrPathTypes;
|
|
1997
|
-
},
|
|
1998
|
-
isUndefined: function(obj) {
|
|
1999
|
-
return typeof obj == "undefined";
|
|
2000
|
-
},
|
|
2001
|
-
isNumber: function(f) {
|
|
2002
|
-
return !isNaN(parseInt(f));
|
|
2003
|
-
},
|
|
2004
|
-
isEmptyObj: function(obj) {
|
|
2005
|
-
for (const prop in obj) if (Object.hasOwnProperty.call(obj, prop)) return false;
|
|
2006
|
-
return JSON.stringify(obj) === JSON.stringify({});
|
|
2007
|
-
},
|
|
2008
|
-
isPlainObject: function(obj) {
|
|
2009
|
-
if (typeof obj !== "object" || obj === null) return false;
|
|
2010
|
-
return Object.getPrototypeOf(obj) === Object.prototype;
|
|
2011
|
-
},
|
|
2012
|
-
isNotObject: function(obj) {
|
|
2013
|
-
return !obj || !this.isPlainObject(obj);
|
|
2014
|
-
},
|
|
2015
|
-
isEmptyArray: function(arr) {
|
|
2016
|
-
return Array.isArray(arr) && arr.length == 0;
|
|
2017
|
-
},
|
|
2018
|
-
isNotArray: function(arr) {
|
|
2019
|
-
return Array.isArray(arr) == false;
|
|
2020
|
-
},
|
|
2021
|
-
removeEmptyArrayItem: function(arr) {
|
|
2022
|
-
return arr.filter(function(el) {
|
|
2023
|
-
return el != null && el != "";
|
|
2024
|
-
});
|
|
2025
|
-
},
|
|
2026
|
-
getFieldName: function(field, prefix, isRoot, isArrayItem, isArray) {
|
|
2027
|
-
if (isArray) return (prefix ? prefix : "") + (dotize.isNumber(field) ? "[" + field + "]" : (isRoot && !prefix ? "" : ".") + field);
|
|
2028
|
-
else if (isArrayItem) return (prefix ? prefix : "") + "[" + field + "]";
|
|
2029
|
-
else return (prefix ? prefix + "." : "") + field;
|
|
2030
|
-
},
|
|
2031
|
-
startsWith: function(val, valToSearch) {
|
|
2032
|
-
return val.indexOf(valToSearch) == 0;
|
|
2033
|
-
},
|
|
2034
|
-
convert: function(obj, prefix = "") {
|
|
2035
|
-
let newObj = {};
|
|
2036
|
-
if (dotize.isNotObject(obj)) if (prefix) {
|
|
2037
|
-
newObj[prefix] = obj;
|
|
2038
|
-
return newObj;
|
|
2039
|
-
} else return obj;
|
|
2040
|
-
return (function recurse(o, p, isRoot) {
|
|
2041
|
-
const isArrayItem = Array.isArray(o);
|
|
2042
|
-
for (const f in o) {
|
|
2043
|
-
const currentProp = o[f];
|
|
2044
|
-
if (currentProp && typeof currentProp === "object" && !Array.isArray(currentProp) && dotize.isPlainObject(currentProp)) {
|
|
2045
|
-
if (isArrayItem && dotize.isEmptyObj(currentProp) == false) newObj = recurse(currentProp, dotize.getFieldName(f, p, isRoot, true));
|
|
2046
|
-
else if (dotize.isEmptyObj(currentProp) == false) newObj = recurse(currentProp, dotize.getFieldName(f, p, isRoot));
|
|
2047
|
-
else if (dotize.isEmptyObj(currentProp)) newObj[dotize.getFieldName(f, p, isRoot, isArrayItem)] = currentProp;
|
|
2048
|
-
} else if (isArrayItem || dotize.isNumber(f)) newObj[dotize.getFieldName(f, p, isRoot, true)] = currentProp;
|
|
2049
|
-
else newObj[dotize.getFieldName(f, p, isRoot)] = currentProp;
|
|
2050
|
-
}
|
|
2051
|
-
return newObj;
|
|
2052
|
-
})(obj, prefix, true);
|
|
2053
|
-
},
|
|
2054
|
-
backward: function(obj, prefix) {
|
|
2055
|
-
let newObj = {};
|
|
2056
|
-
const arStartRegex = /\[(\d+)\]/g;
|
|
2057
|
-
if (dotize.isNotObject(obj) && dotize.isNotArray(obj)) if (prefix) return obj[prefix];
|
|
2058
|
-
else return obj;
|
|
2059
|
-
for (let tProp in obj) {
|
|
2060
|
-
const tPropVal = obj[tProp];
|
|
2061
|
-
if (prefix) {
|
|
2062
|
-
const prefixRegex = new RegExp("^" + prefix);
|
|
2063
|
-
tProp = tProp.replace(prefixRegex, "");
|
|
2064
|
-
}
|
|
2065
|
-
tProp = tProp.replace(arStartRegex, ".$1");
|
|
2066
|
-
if (dotize.startsWith(tProp, ".")) tProp = tProp.replace(/^\./, "");
|
|
2067
|
-
const arrPath = tProp.split(".");
|
|
2068
|
-
const arrPathTypes = dotize.getPathType(arrPath);
|
|
2069
|
-
if (!dotize.isUndefined(arrPathTypes) && arrPathTypes[0] == dotize.valTypes.array && Array.isArray(newObj) == false) newObj = [];
|
|
2070
|
-
(function recurse(rPropVal, rObj, rPropValPrev, rObjPrev) {
|
|
2071
|
-
let currentPath = arrPath.shift();
|
|
2072
|
-
const currentPathType = arrPathTypes.shift();
|
|
2073
|
-
if (typeof currentPath == "undefined" || currentPath == "") {
|
|
2074
|
-
newObj = rPropVal;
|
|
2075
|
-
return;
|
|
2076
|
-
}
|
|
2077
|
-
const isArray = currentPathType == dotize.valTypes.array;
|
|
2078
|
-
if (dotize.isNumber(currentPath)) currentPath = parseInt(currentPath);
|
|
2079
|
-
if (arrPath.length > 0) {
|
|
2080
|
-
if (typeof rObj[currentPath] == "undefined") if (isArray) rObj[currentPath] = [];
|
|
2081
|
-
else rObj[currentPath] = {};
|
|
2082
|
-
recurse(rPropVal, rObj[currentPath], currentPath, rObj);
|
|
2083
|
-
return;
|
|
2084
|
-
}
|
|
2085
|
-
if (currentPathType == dotize.valTypes.array && rPropValPrev && rObjPrev) {
|
|
2086
|
-
if (Array.isArray(rObjPrev[rPropValPrev]) == false) rObjPrev[rPropValPrev] = [];
|
|
2087
|
-
rObjPrev[rPropValPrev].push(rPropVal);
|
|
2088
|
-
} else rObj[currentPath] = rPropVal;
|
|
2089
|
-
})(tPropVal, newObj);
|
|
2090
|
-
}
|
|
2091
|
-
return newObj;
|
|
2092
|
-
}
|
|
2093
|
-
};
|
|
2094
|
-
//#endregion
|
|
2095
|
-
export { hslToRgbValues as A, createColorFunc as C, getNamedColorHex as D, makeEmptyDetails as E, RE_NUMBER as F, RE_RAW_UNIT as I, normalizeDslName as M, toSnakeCase as N, getRgbValuesFromRgbaString as O, CSS_WIDE_KEYWORDS as P, okhslPlugin as S, Lru as T, setGlobalPredefinedTokens as _, DIRECTIONS as a, okhstPlugin as b, getGlobalParseFunctions as c, normalizeColorTokenValue as d, parseColor as f, resolveCustomProperties as g, resetGlobalPredefinedTokens as h, CUSTOM_UNITS as i, strToRgb as j, hexToRgb as k, getGlobalParser as l, resetGlobalParseFunctions as m, color as n, customFunction as o, parseStyle as p, resolveFunctionColor as r, filterMods as s, dotize as t, getGlobalPredefinedTokens as u, stringifyStyles as v, StyleParser as w, okhslFunction as x, okhstFunction as y };
|
|
1371
|
+
export { strToRgb as A, StyleParser as C, getRgbValuesFromRgbaString as D, getNamedColorHex as E, RE_RAW_UNIT as F, toSnakeCase as M, CSS_WIDE_KEYWORDS as N, hexToRgb as O, RE_NUMBER as P, createColorFunc as S, makeEmptyDetails as T, stringifyStyles as _, customFunction as a, okhslFunction as b, getGlobalParser as c, parseColor as d, parseStyle as f, setGlobalPredefinedTokens as g, resolveCustomProperties as h, DIRECTIONS as i, normalizeDslName as j, hslToRgbValues as k, getGlobalPredefinedTokens as l, resetGlobalPredefinedTokens as m, resolveFunctionColor as n, filterMods as o, resetGlobalParseFunctions as p, CUSTOM_UNITS as r, getGlobalParseFunctions as s, color as t, normalizeColorTokenValue as u, okhstFunction as v, Lru as w, okhslPlugin as x, okhstPlugin as y };
|
|
2096
1372
|
|
|
2097
|
-
//# sourceMappingURL=dsl-
|
|
1373
|
+
//# sourceMappingURL=dsl-C5yuAn41.js.map
|