rainbowindex 0.6.0 → 0.7.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.
- package/CHANGELOG.md +543 -0
- package/LICENSE +16 -17
- package/NOTICE.md +106 -0
- package/README.md +219 -65
- package/dist/browser.d.ts +4 -2
- package/dist/browser.mjs +12 -4
- package/dist/chunk-2T7V5XLK.mjs +912 -0
- package/dist/chunk-6OORICWF.mjs +16 -0
- package/dist/{chunk-KSNYSR3C.mjs → chunk-FJOZJIKB.mjs} +2499 -329
- package/dist/chunk-L56IRO7A.mjs +491 -0
- package/dist/chunk-PZDVDEZJ.mjs +196 -0
- package/dist/{chunk-3LWJTLOJ.mjs → chunk-RC6DDE4L.mjs} +23 -15
- package/dist/chunk-TQJYVQPE.mjs +217 -0
- package/dist/chunk-W756NVYI.mjs +33 -0
- package/dist/chunk-WBESS2ZD.mjs +598 -0
- package/dist/{chunk-3HRMFZGE.mjs → chunk-X66Z2YHT.mjs} +2 -1
- package/dist/{chunk-6U4IOFOS.mjs → chunk-XQGSG2HK.mjs} +199 -555
- package/dist/cli.mjs +1077 -123
- package/dist/{index-DSgpB6bS.d.ts → context-DcBtnnan.d.ts} +47 -103
- package/dist/editor.d.ts +71 -433
- package/dist/editor.mjs +51 -368
- package/dist/eslint.d.ts +16 -0
- package/dist/eslint.mjs +32 -0
- package/dist/{index-4Kyaq3IZ.d.ts → imports-C9esHd5Q.d.ts} +78 -84
- package/dist/index-CNqdL5U0.d.ts +56 -0
- package/dist/index-Czx-EUwh.d.ts +138 -0
- package/dist/index-DW8YSxTz.d.ts +104 -0
- package/dist/index.d.ts +46 -5
- package/dist/index.mjs +33 -9
- package/dist/oxlint.d.ts +21 -3
- package/dist/oxlint.mjs +19 -1
- package/dist/recipe.d.ts +111 -0
- package/dist/recipe.mjs +71 -0
- package/dist/safelist-CH3_PywB.d.ts +43 -0
- package/dist/session-CMaskdB7.d.ts +543 -0
- package/dist/tailwind.css +644 -0
- package/dist/theme-CIZiGlce.d.ts +115 -0
- package/dist/vite.d.ts +10 -1
- package/dist/vite.mjs +266 -118
- package/package.json +27 -5
- package/dist/chunk-WK6S4HTC.mjs +0 -1921
- package/dist/chunk-ZR7XJMUN.mjs +0 -251
- package/dist/safelist-CGCtF-Fr.d.ts +0 -96
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
// src/theme/colors.ts
|
|
2
|
+
function isValidColorSuffix(n) {
|
|
3
|
+
return Number.isInteger(n) && n >= 1 && n <= 999;
|
|
4
|
+
}
|
|
5
|
+
var STOP_LO = 50;
|
|
6
|
+
var STOP_STEP = 50;
|
|
7
|
+
var L_PROFILE = [
|
|
8
|
+
0.9668,
|
|
9
|
+
// 50
|
|
10
|
+
0.936756,
|
|
11
|
+
// 100
|
|
12
|
+
0.905984,
|
|
13
|
+
// 150
|
|
14
|
+
0.87442,
|
|
15
|
+
// 200
|
|
16
|
+
0.841988,
|
|
17
|
+
// 250
|
|
18
|
+
0.808602,
|
|
19
|
+
// 300
|
|
20
|
+
0.774158,
|
|
21
|
+
// 350
|
|
22
|
+
0.73853,
|
|
23
|
+
// 400
|
|
24
|
+
0.701568,
|
|
25
|
+
// 450
|
|
26
|
+
0.663082,
|
|
27
|
+
// 500
|
|
28
|
+
0.622832,
|
|
29
|
+
// 550
|
|
30
|
+
0.580504,
|
|
31
|
+
// 600
|
|
32
|
+
0.535677,
|
|
33
|
+
// 650
|
|
34
|
+
0.487755,
|
|
35
|
+
// 700
|
|
36
|
+
0.435847,
|
|
37
|
+
// 750
|
|
38
|
+
0.378506,
|
|
39
|
+
// 800
|
|
40
|
+
0.313034,
|
|
41
|
+
// 850
|
|
42
|
+
0.232988,
|
|
43
|
+
// 900
|
|
44
|
+
0.045
|
|
45
|
+
// 950
|
|
46
|
+
];
|
|
47
|
+
var REF_CHROMA = 0.05;
|
|
48
|
+
var C_REF = [
|
|
49
|
+
0.006863863034589374,
|
|
50
|
+
// 50
|
|
51
|
+
0.01319862716849036,
|
|
52
|
+
// 100
|
|
53
|
+
0.019388384668336325,
|
|
54
|
+
// 150
|
|
55
|
+
0.025429811853816625,
|
|
56
|
+
// 200
|
|
57
|
+
0.03131716290796655,
|
|
58
|
+
// 250
|
|
59
|
+
0.03704281264548738,
|
|
60
|
+
// 300
|
|
61
|
+
0.04259815284255128,
|
|
62
|
+
// 350
|
|
63
|
+
0.04797259847240491,
|
|
64
|
+
// 400
|
|
65
|
+
0.053139652622711774,
|
|
66
|
+
// 450
|
|
67
|
+
0.05807254410984486,
|
|
68
|
+
// 500
|
|
69
|
+
0.057890440330825195,
|
|
70
|
+
// 550
|
|
71
|
+
0.05222950205066024,
|
|
72
|
+
// 600
|
|
73
|
+
0.04663166172903349,
|
|
74
|
+
// 650
|
|
75
|
+
0.04108661482545571,
|
|
76
|
+
// 700
|
|
77
|
+
0.035584106512529856,
|
|
78
|
+
// 750
|
|
79
|
+
0.030108630901677546,
|
|
80
|
+
// 800
|
|
81
|
+
0.02463007273923548,
|
|
82
|
+
// 850
|
|
83
|
+
0.01911062262055484,
|
|
84
|
+
// 900
|
|
85
|
+
0.013470720217073236
|
|
86
|
+
// 950
|
|
87
|
+
];
|
|
88
|
+
var H_DRIFT = [
|
|
89
|
+
-0.93815866691077,
|
|
90
|
+
// 50
|
|
91
|
+
-0.88308454198904,
|
|
92
|
+
// 100
|
|
93
|
+
-0.82986570023714,
|
|
94
|
+
// 150
|
|
95
|
+
-0.77925524218887,
|
|
96
|
+
// 200
|
|
97
|
+
-0.73231968077941,
|
|
98
|
+
// 250
|
|
99
|
+
-0.69055370894147,
|
|
100
|
+
// 300
|
|
101
|
+
-0.65608113228225,
|
|
102
|
+
// 350
|
|
103
|
+
-0.6319804472577,
|
|
104
|
+
// 400
|
|
105
|
+
-0.62282301825498,
|
|
106
|
+
// 450
|
|
107
|
+
-0.63542113918918,
|
|
108
|
+
// 500
|
|
109
|
+
-0.65047025648765,
|
|
110
|
+
// 550
|
|
111
|
+
-0.64293938410323,
|
|
112
|
+
// 600
|
|
113
|
+
-0.63626978185344,
|
|
114
|
+
// 650
|
|
115
|
+
-0.63057786221076,
|
|
116
|
+
// 700
|
|
117
|
+
-0.62611168444876,
|
|
118
|
+
// 750
|
|
119
|
+
-0.62332854799372,
|
|
120
|
+
// 800
|
|
121
|
+
-0.62317507759171,
|
|
122
|
+
// 850
|
|
123
|
+
-0.62789446720379,
|
|
124
|
+
// 900
|
|
125
|
+
-0.64378251527182
|
|
126
|
+
// 950
|
|
127
|
+
];
|
|
128
|
+
function sampleProfile(values, suffix, monotone) {
|
|
129
|
+
const last = values.length - 1;
|
|
130
|
+
const fx = (suffix - STOP_LO) / STOP_STEP;
|
|
131
|
+
if (fx <= 0) return values[0] + (values[1] - values[0]) * fx;
|
|
132
|
+
if (fx >= last) return values[last] + (values[last] - values[last - 1]) * (fx - last);
|
|
133
|
+
const i = Math.floor(fx);
|
|
134
|
+
const t = fx - i;
|
|
135
|
+
if (t === 0) return values[i];
|
|
136
|
+
const seg = values[i + 1] - values[i];
|
|
137
|
+
const tangent = (k) => {
|
|
138
|
+
if (k <= 0) return values[1] - values[0];
|
|
139
|
+
if (k >= last) return values[last] - values[last - 1];
|
|
140
|
+
return (values[k + 1] - values[k - 1]) / 2;
|
|
141
|
+
};
|
|
142
|
+
let m0 = tangent(i);
|
|
143
|
+
let m1 = tangent(i + 1);
|
|
144
|
+
if (monotone) {
|
|
145
|
+
if (seg === 0) {
|
|
146
|
+
m0 = 0;
|
|
147
|
+
m1 = 0;
|
|
148
|
+
} else {
|
|
149
|
+
const a = m0 / seg;
|
|
150
|
+
const b = m1 / seg;
|
|
151
|
+
const s = a * a + b * b;
|
|
152
|
+
if (s > 9) {
|
|
153
|
+
const tau = 3 / Math.sqrt(s);
|
|
154
|
+
m0 = tau * a * seg;
|
|
155
|
+
m1 = tau * b * seg;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const t2 = t * t;
|
|
160
|
+
const t3 = t2 * t;
|
|
161
|
+
return (2 * t3 - 3 * t2 + 1) * values[i] + (t3 - 2 * t2 + t) * m0 + (-2 * t3 + 3 * t2) * values[i + 1] + (t3 - t2) * m1;
|
|
162
|
+
}
|
|
163
|
+
function lightnessFromSuffix(suffix) {
|
|
164
|
+
return Math.min(0.98, Math.max(0.02, sampleProfile(L_PROFILE, suffix, true)));
|
|
165
|
+
}
|
|
166
|
+
var DEFAULT_COLORS = Object.freeze({
|
|
167
|
+
theme: {
|
|
168
|
+
type: "generative",
|
|
169
|
+
chroma: 0,
|
|
170
|
+
hue: 0,
|
|
171
|
+
parabolic: false,
|
|
172
|
+
chromaBoost: false
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
var DEFAULT_DARK_VARIANT = Object.freeze({ kind: "media" });
|
|
176
|
+
var DEFAULT_DARK_CONFIG = {
|
|
177
|
+
mode: "auto",
|
|
178
|
+
// 0 → dark keeps the light stop's chroma exactly (same tone in both modes).
|
|
179
|
+
// Raise it via `@color dark { chroma-boost }` for punchier dark-mode colors.
|
|
180
|
+
chromaBoost: 0,
|
|
181
|
+
hueShift: 0,
|
|
182
|
+
variant: DEFAULT_DARK_VARIANT
|
|
183
|
+
};
|
|
184
|
+
var GAMUT_CLAMP_ITERATIONS = 20;
|
|
185
|
+
function oklchToOklab(l, c, h) {
|
|
186
|
+
const hRad = h * Math.PI / 180;
|
|
187
|
+
return [l, c * Math.cos(hRad), c * Math.sin(hRad)];
|
|
188
|
+
}
|
|
189
|
+
function oklabToLinearSrgb(l, a, b) {
|
|
190
|
+
const l_ = l + 0.3963377774 * a + 0.2158037573 * b;
|
|
191
|
+
const m_ = l - 0.1055613458 * a - 0.0638541728 * b;
|
|
192
|
+
const s_ = l - 0.0894841775 * a - 1.291485548 * b;
|
|
193
|
+
const lc = l_ * l_ * l_;
|
|
194
|
+
const mc = m_ * m_ * m_;
|
|
195
|
+
const sc = s_ * s_ * s_;
|
|
196
|
+
const r = 4.0767416621 * lc - 3.3077115913 * mc + 0.2309699292 * sc;
|
|
197
|
+
const g = -1.2684380046 * lc + 2.6097574011 * mc - 0.3413193965 * sc;
|
|
198
|
+
const bv = -0.0041960863 * lc - 0.7034186147 * mc + 1.707614701 * sc;
|
|
199
|
+
return [r, g, bv];
|
|
200
|
+
}
|
|
201
|
+
function isInSrgbGamut(l, c, h) {
|
|
202
|
+
const [la, a, b] = oklchToOklab(l, c, h);
|
|
203
|
+
const [r, g, bv] = oklabToLinearSrgb(la, a, b);
|
|
204
|
+
const eps = 1e-3;
|
|
205
|
+
return r >= -eps && r <= 1 + eps && g >= -eps && g <= 1 + eps && bv >= -eps && bv <= 1 + eps;
|
|
206
|
+
}
|
|
207
|
+
function gamutSafeChroma(l, requestedChroma, h) {
|
|
208
|
+
if (requestedChroma <= 0) return 0;
|
|
209
|
+
if (isInSrgbGamut(l, requestedChroma, h)) return requestedChroma;
|
|
210
|
+
let lo = 0;
|
|
211
|
+
let hi = requestedChroma;
|
|
212
|
+
for (let i = 0; i < GAMUT_CLAMP_ITERATIONS; i++) {
|
|
213
|
+
const mid = (lo + hi) / 2;
|
|
214
|
+
if (isInSrgbGamut(l, mid, h)) {
|
|
215
|
+
lo = mid;
|
|
216
|
+
} else {
|
|
217
|
+
hi = mid;
|
|
218
|
+
}
|
|
219
|
+
if (hi - lo < 5e-4) break;
|
|
220
|
+
}
|
|
221
|
+
return lo;
|
|
222
|
+
}
|
|
223
|
+
var APCA_MAIN_TRC = 2.4;
|
|
224
|
+
var APCA_NORM_BG = 0.56;
|
|
225
|
+
var APCA_NORM_TXT = 0.57;
|
|
226
|
+
var APCA_REV_TXT = 0.62;
|
|
227
|
+
var APCA_REV_BG = 0.65;
|
|
228
|
+
var APCA_BLK_THRS = 0.022;
|
|
229
|
+
var APCA_BLK_CLMP = Math.SQRT2;
|
|
230
|
+
var APCA_SCALE = 1.14;
|
|
231
|
+
var APCA_LO_BOW_OFFSET = 0.027;
|
|
232
|
+
var APCA_LO_WOB_OFFSET = 0.027;
|
|
233
|
+
var APCA_DELTA_Y_MIN = 5e-4;
|
|
234
|
+
var APCA_LO_CLIP = 0.1;
|
|
235
|
+
function linearToSrgb(c) {
|
|
236
|
+
const x = Math.max(0, Math.min(1, c));
|
|
237
|
+
return x <= 31308e-7 ? 12.92 * x : 1.055 * x ** (1 / 2.4) - 0.055;
|
|
238
|
+
}
|
|
239
|
+
function oklchToApcaY(l, c, h) {
|
|
240
|
+
const [la, a, b] = oklchToOklab(l, c, h);
|
|
241
|
+
const [lr, lg, lb] = oklabToLinearSrgb(la, a, b);
|
|
242
|
+
const r = linearToSrgb(lr);
|
|
243
|
+
const g = linearToSrgb(lg);
|
|
244
|
+
const bv = linearToSrgb(lb);
|
|
245
|
+
return 0.2126 * r ** APCA_MAIN_TRC + 0.7152 * g ** APCA_MAIN_TRC + 0.0722 * bv ** APCA_MAIN_TRC;
|
|
246
|
+
}
|
|
247
|
+
function apcaContrast(yText, yBg) {
|
|
248
|
+
if (yText < 0 || yBg < 0) return 0;
|
|
249
|
+
if (Math.max(yText, yBg) < APCA_BLK_THRS) return 0;
|
|
250
|
+
const txtY = yText < APCA_BLK_THRS ? yText + (APCA_BLK_THRS - yText) ** APCA_BLK_CLMP : yText;
|
|
251
|
+
const bgY = yBg < APCA_BLK_THRS ? yBg + (APCA_BLK_THRS - yBg) ** APCA_BLK_CLMP : yBg;
|
|
252
|
+
if (Math.abs(bgY - txtY) < APCA_DELTA_Y_MIN) return 0;
|
|
253
|
+
if (bgY > txtY) {
|
|
254
|
+
const sapc2 = (bgY ** APCA_NORM_BG - txtY ** APCA_NORM_TXT) * APCA_SCALE;
|
|
255
|
+
return sapc2 < APCA_LO_CLIP ? 0 : (sapc2 - APCA_LO_BOW_OFFSET) * 100;
|
|
256
|
+
}
|
|
257
|
+
const sapc = (bgY ** APCA_REV_BG - txtY ** APCA_REV_TXT) * APCA_SCALE;
|
|
258
|
+
return sapc > -APCA_LO_CLIP ? 0 : (sapc + APCA_LO_WOB_OFFSET) * 100;
|
|
259
|
+
}
|
|
260
|
+
var _stopMemo = /* @__PURE__ */ new WeakMap();
|
|
261
|
+
function generateStop(def, suffix) {
|
|
262
|
+
let bySuffix = _stopMemo.get(def);
|
|
263
|
+
if (!bySuffix) {
|
|
264
|
+
bySuffix = /* @__PURE__ */ new Map();
|
|
265
|
+
_stopMemo.set(def, bySuffix);
|
|
266
|
+
}
|
|
267
|
+
const cached = bySuffix.get(suffix);
|
|
268
|
+
if (cached) return cached;
|
|
269
|
+
const stop = computeStop(def, suffix);
|
|
270
|
+
bySuffix.set(suffix, stop);
|
|
271
|
+
return stop;
|
|
272
|
+
}
|
|
273
|
+
function computeStop(def, suffix) {
|
|
274
|
+
const roundedL = Math.round(lightnessFromSuffix(suffix) * 1e3) / 1e3;
|
|
275
|
+
const h = def.chroma > 0 ? def.hue + sampleProfile(H_DRIFT, suffix, false) : def.hue;
|
|
276
|
+
const roundedH = Math.round(h * 1e3) / 1e3;
|
|
277
|
+
const shapedChroma = def.parabolic === false ? def.chroma : def.chroma * sampleProfile(C_REF, suffix, false) / REF_CHROMA;
|
|
278
|
+
const safeC = gamutSafeChroma(roundedL, shapedChroma, roundedH);
|
|
279
|
+
const roundedC = Math.floor(safeC * 1e4) / 1e4;
|
|
280
|
+
return {
|
|
281
|
+
stop: suffix,
|
|
282
|
+
l: roundedL,
|
|
283
|
+
c: roundedC,
|
|
284
|
+
h: roundedH
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function computeDarkStop(def, suffix, darkConfig, darkOverride) {
|
|
288
|
+
const lightStop = generateStop(def, suffix);
|
|
289
|
+
const darkL = generateStop(def, 1e3 - suffix).l;
|
|
290
|
+
let extraChroma = 0;
|
|
291
|
+
let extraHue = 0;
|
|
292
|
+
if (darkOverride?.strategy === "shift") {
|
|
293
|
+
extraChroma = darkOverride.chromaDelta;
|
|
294
|
+
extraHue = darkOverride.hueDelta;
|
|
295
|
+
}
|
|
296
|
+
const darkH = lightStop.h + darkConfig.hueShift + extraHue;
|
|
297
|
+
const globalChromaBoost = def.chromaBoost !== false ? darkConfig.chromaBoost : 0;
|
|
298
|
+
const requestedChroma = lightStop.c + globalChromaBoost + extraChroma;
|
|
299
|
+
const darkC = Math.floor(gamutSafeChroma(darkL, requestedChroma, darkH) * 1e4) / 1e4;
|
|
300
|
+
return { stop: suffix, l: darkL, c: darkC, h: darkH };
|
|
301
|
+
}
|
|
302
|
+
function formatOklch(l, c, h) {
|
|
303
|
+
return `oklch(${l} ${c} ${h})`;
|
|
304
|
+
}
|
|
305
|
+
function generateColorVariables(name, def, suffixes, darkConfig = DEFAULT_DARK_CONFIG, darkOverride) {
|
|
306
|
+
const vars = [];
|
|
307
|
+
const strategy = darkOverride?.strategy ?? "mirror";
|
|
308
|
+
for (const suffix of suffixes) {
|
|
309
|
+
const lightStop = generateStop(def, suffix);
|
|
310
|
+
const lightValue = formatOklch(lightStop.l, lightStop.c, lightStop.h);
|
|
311
|
+
if (darkConfig.mode === "off" || strategy === "fixed") {
|
|
312
|
+
if (darkConfig.mode === "off") {
|
|
313
|
+
vars.push(`--color-${name}-${suffix}: ${lightValue};`);
|
|
314
|
+
} else {
|
|
315
|
+
vars.push(`--color-${name}-${suffix}: light-dark(${lightValue}, ${lightValue});`);
|
|
316
|
+
}
|
|
317
|
+
} else {
|
|
318
|
+
const darkStop = computeDarkStop(def, suffix, darkConfig, darkOverride);
|
|
319
|
+
const darkValue = formatOklch(darkStop.l, darkStop.c, darkStop.h);
|
|
320
|
+
vars.push(`--color-${name}-${suffix}: light-dark(${lightValue}, ${darkValue});`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return vars;
|
|
324
|
+
}
|
|
325
|
+
var SEMANTIC_COLORS = Object.freeze([
|
|
326
|
+
"--color-paper: light-dark(oklch(1 0 0), oklch(0 0 0));",
|
|
327
|
+
"--color-ink: light-dark(oklch(0 0 0), oklch(1 0 0));"
|
|
328
|
+
]);
|
|
329
|
+
var DEFAULT_PALETTE_CONTRAST_LC = 60;
|
|
330
|
+
function checkPaletteContrast(colors, usedColorStops, options = {}) {
|
|
331
|
+
const minLc = options.minLc ?? DEFAULT_PALETTE_CONTRAST_LC;
|
|
332
|
+
const warnings = [];
|
|
333
|
+
const paperY = oklchToApcaY(1, 0, 0);
|
|
334
|
+
const inkY = oklchToApcaY(0, 0, 0);
|
|
335
|
+
for (const [name, def] of Object.entries(colors)) {
|
|
336
|
+
if (def.type !== "generative") continue;
|
|
337
|
+
const stops = usedColorStops.get(name);
|
|
338
|
+
if (!stops || stops.size === 0) continue;
|
|
339
|
+
const sorted = [...stops].sort((a, b) => a - b);
|
|
340
|
+
for (const suffix of sorted) {
|
|
341
|
+
const stop = generateStop(def, suffix);
|
|
342
|
+
const fgY = oklchToApcaY(stop.l, stop.c, stop.h);
|
|
343
|
+
const lcPaper = Math.abs(apcaContrast(fgY, paperY));
|
|
344
|
+
const lcInk = Math.abs(apcaContrast(fgY, inkY));
|
|
345
|
+
const best = Math.max(lcPaper, lcInk);
|
|
346
|
+
if (best < minLc) {
|
|
347
|
+
warnings.push(
|
|
348
|
+
`[RI-1106] @color "${name}-${suffix}" has low APCA contrast (best |Lc| ${best.toFixed(0)} < ${minLc}; paper ${lcPaper.toFixed(0)}, ink ${lcInk.toFixed(0)}). Stop is unsuitable as text on either --color-paper or --color-ink \u2014 use a darker (lower suffix) or lighter (higher suffix) variant for text roles.`
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return warnings;
|
|
354
|
+
}
|
|
355
|
+
function resolveAliasTarget(colors, source) {
|
|
356
|
+
const visited = /* @__PURE__ */ new Set();
|
|
357
|
+
let current = source;
|
|
358
|
+
while (!visited.has(current)) {
|
|
359
|
+
visited.add(current);
|
|
360
|
+
const def = colors[current];
|
|
361
|
+
if (!def) return null;
|
|
362
|
+
if (def.type !== "alias") return { name: current, def };
|
|
363
|
+
current = def.source;
|
|
364
|
+
}
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
function generateAllColorVariables(colors = DEFAULT_COLORS, darkConfig = DEFAULT_DARK_CONFIG, usedColorStops, usedColorNames) {
|
|
368
|
+
const allVars = [];
|
|
369
|
+
allVars.push(...SEMANTIC_COLORS);
|
|
370
|
+
for (const [name, def] of Object.entries(colors)) {
|
|
371
|
+
switch (def.type) {
|
|
372
|
+
case "generative": {
|
|
373
|
+
const suffixes = usedColorStops?.get(name);
|
|
374
|
+
if (!suffixes || suffixes.size === 0) break;
|
|
375
|
+
const sorted = [...suffixes].sort((a, b) => a - b);
|
|
376
|
+
allVars.push(...generateColorVariables(name, def, sorted, darkConfig, def.dark));
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
case "explicit": {
|
|
380
|
+
if (usedColorNames && !usedColorNames.has(name)) break;
|
|
381
|
+
allVars.push(`--color-${name}: ${def.value};`);
|
|
382
|
+
break;
|
|
383
|
+
}
|
|
384
|
+
case "pair": {
|
|
385
|
+
if (usedColorNames && !usedColorNames.has(name)) break;
|
|
386
|
+
if (darkConfig.mode === "off") {
|
|
387
|
+
allVars.push(`--color-${name}: ${def.light};`);
|
|
388
|
+
} else {
|
|
389
|
+
allVars.push(`--color-${name}: light-dark(${def.light}, ${def.dark});`);
|
|
390
|
+
}
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
case "alias": {
|
|
394
|
+
const target = resolveAliasTarget(colors, def.source);
|
|
395
|
+
if (target === null) break;
|
|
396
|
+
if (target.def.type === "generative") {
|
|
397
|
+
const suffixes = usedColorStops?.get(name);
|
|
398
|
+
if (!suffixes || suffixes.size === 0) break;
|
|
399
|
+
const sorted = [...suffixes].sort((a, b) => a - b);
|
|
400
|
+
for (const suffix of sorted) {
|
|
401
|
+
allVars.push(`--color-${name}-${suffix}: var(--color-${def.source}-${suffix});`);
|
|
402
|
+
}
|
|
403
|
+
} else if (target.def.type === "keyword") {
|
|
404
|
+
if (usedColorNames && !usedColorNames.has(name)) break;
|
|
405
|
+
allVars.push(`--color-${name}: ${target.def.value};`);
|
|
406
|
+
} else {
|
|
407
|
+
if (usedColorNames && !usedColorNames.has(name)) break;
|
|
408
|
+
allVars.push(`--color-${name}: var(--color-${def.source});`);
|
|
409
|
+
}
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return allVars;
|
|
415
|
+
}
|
|
416
|
+
function generateThemeOverrides(colors, usedThemeSuffixes) {
|
|
417
|
+
if (!Object.hasOwn(colors, "theme")) return [];
|
|
418
|
+
if (!usedThemeSuffixes || usedThemeSuffixes.size === 0) return [];
|
|
419
|
+
const sorted = [...usedThemeSuffixes].sort((a, b) => a - b);
|
|
420
|
+
const blocks = [];
|
|
421
|
+
for (const [name, def] of Object.entries(colors)) {
|
|
422
|
+
if (name === "theme") continue;
|
|
423
|
+
if (def.type !== "generative") continue;
|
|
424
|
+
if (!def.inline) continue;
|
|
425
|
+
const vars = [];
|
|
426
|
+
for (const suffix of sorted) {
|
|
427
|
+
vars.push(` --color-theme-${suffix}: var(--color-${name}-${suffix});`);
|
|
428
|
+
}
|
|
429
|
+
const safeName = name.replace(/[\\"'\]]/g, "");
|
|
430
|
+
if (!safeName) continue;
|
|
431
|
+
blocks.push(`[data-theme="${safeName}"] {
|
|
432
|
+
${vars.join("\n")}
|
|
433
|
+
}`);
|
|
434
|
+
}
|
|
435
|
+
return blocks;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// src/theme/index.ts
|
|
439
|
+
var CORNER_SHAPE_KEYWORDS = [
|
|
440
|
+
"round",
|
|
441
|
+
"scoop",
|
|
442
|
+
"bevel",
|
|
443
|
+
"notch",
|
|
444
|
+
"square",
|
|
445
|
+
"squircle"
|
|
446
|
+
];
|
|
447
|
+
var DEFAULT_CORNER_SCALE = {
|
|
448
|
+
round: 1,
|
|
449
|
+
square: 1,
|
|
450
|
+
notch: 1,
|
|
451
|
+
bevel: 0.8,
|
|
452
|
+
scoop: 1.2,
|
|
453
|
+
squircle: 1.6
|
|
454
|
+
};
|
|
455
|
+
var DEFAULT_SUPERELLIPSE_SCALE = 1.6;
|
|
456
|
+
var defaultTheme = Object.freeze({
|
|
457
|
+
spacing: {
|
|
458
|
+
base: "0.25rem"
|
|
459
|
+
},
|
|
460
|
+
colors: DEFAULT_COLORS,
|
|
461
|
+
// Every named scale below ships empty: the tokens come from @text,
|
|
462
|
+
// @breakpoint, @shadow, @weight, @ease, @animate and @blur. @fluid carries
|
|
463
|
+
// no viewport range until one is declared, so fluid utilities stay inert.
|
|
464
|
+
text: {},
|
|
465
|
+
breakpoints: {},
|
|
466
|
+
shadows: {},
|
|
467
|
+
weights: {},
|
|
468
|
+
easing: {},
|
|
469
|
+
fluid: {},
|
|
470
|
+
animations: {},
|
|
471
|
+
blur: {}
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
export {
|
|
475
|
+
isValidColorSuffix,
|
|
476
|
+
DEFAULT_COLORS,
|
|
477
|
+
DEFAULT_DARK_CONFIG,
|
|
478
|
+
oklchToOklab,
|
|
479
|
+
oklabToLinearSrgb,
|
|
480
|
+
linearToSrgb,
|
|
481
|
+
generateStop,
|
|
482
|
+
computeDarkStop,
|
|
483
|
+
formatOklch,
|
|
484
|
+
checkPaletteContrast,
|
|
485
|
+
generateAllColorVariables,
|
|
486
|
+
generateThemeOverrides,
|
|
487
|
+
CORNER_SHAPE_KEYWORDS,
|
|
488
|
+
DEFAULT_CORNER_SCALE,
|
|
489
|
+
DEFAULT_SUPERELLIPSE_SCALE,
|
|
490
|
+
defaultTheme
|
|
491
|
+
};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createClassInspector,
|
|
3
|
+
enumerateClassNames,
|
|
4
|
+
listThemeTokens,
|
|
5
|
+
resolveColorSwatch
|
|
6
|
+
} from "./chunk-WBESS2ZD.mjs";
|
|
7
|
+
import {
|
|
8
|
+
analyzeProjectCSS,
|
|
9
|
+
assembleSections,
|
|
10
|
+
codepointCompare,
|
|
11
|
+
compileCSSFunctions,
|
|
12
|
+
createCompiler,
|
|
13
|
+
createThemeSnapshot,
|
|
14
|
+
diagnosticFromWarning,
|
|
15
|
+
extractClassCandidates,
|
|
16
|
+
hasCSSFunctions,
|
|
17
|
+
inlineDirectiveImports,
|
|
18
|
+
scanCSSForTokenUsage,
|
|
19
|
+
stripRIDirectives
|
|
20
|
+
} from "./chunk-FJOZJIKB.mjs";
|
|
21
|
+
import {
|
|
22
|
+
mergeUncached,
|
|
23
|
+
resolverFor
|
|
24
|
+
} from "./chunk-XQGSG2HK.mjs";
|
|
25
|
+
|
|
26
|
+
// src/merge/analyze.ts
|
|
27
|
+
function analyzeMerge(classes, snapshot) {
|
|
28
|
+
const resolve = resolverFor(snapshot);
|
|
29
|
+
const trace = { claimers: /* @__PURE__ */ new Map(), dropped: [] };
|
|
30
|
+
const output = mergeUncached(classes, resolve, trace);
|
|
31
|
+
trace.dropped.sort((a, b) => a.index - b.index);
|
|
32
|
+
const droppedIndexes = new Set(trace.dropped.map((d) => d.index));
|
|
33
|
+
const kept = [];
|
|
34
|
+
for (let i = 0; i < classes.length; i++) {
|
|
35
|
+
if (!droppedIndexes.has(i)) kept.push(i);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
output,
|
|
39
|
+
kept,
|
|
40
|
+
dropped: trace.dropped.map((d) => ({
|
|
41
|
+
index: d.index,
|
|
42
|
+
className: classes[d.index],
|
|
43
|
+
overriddenBy: d.overriddenBy
|
|
44
|
+
}))
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/editor/render.ts
|
|
49
|
+
function renderStylesheet(theme, classNames, options = {}) {
|
|
50
|
+
const compiler = createCompiler();
|
|
51
|
+
const compilation = compiler.compile([...classNames], theme, options.authoredClassNames);
|
|
52
|
+
const warnings = [];
|
|
53
|
+
let userCSS = options.userCSS ?? "";
|
|
54
|
+
if (userCSS && hasCSSFunctions(userCSS)) {
|
|
55
|
+
userCSS = compileCSSFunctions(userCSS, theme, warnings);
|
|
56
|
+
}
|
|
57
|
+
if (userCSS) scanCSSForTokenUsage(userCSS, compilation);
|
|
58
|
+
const assembled = assembleSections(compilation, theme, compiler.fontOutputCache);
|
|
59
|
+
warnings.push(...assembled.warnings, ...compilation.warnings);
|
|
60
|
+
const sections = assembled.sections;
|
|
61
|
+
return {
|
|
62
|
+
css: userCSS ? [...sections, userCSS].join("\n\n") : sections.join("\n\n"),
|
|
63
|
+
sections,
|
|
64
|
+
userCSS,
|
|
65
|
+
warnings
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/editor/sort.ts
|
|
70
|
+
function sortClassesWithInspector(inspector, classes) {
|
|
71
|
+
const unknown = [];
|
|
72
|
+
const known = [];
|
|
73
|
+
for (const className of classes) {
|
|
74
|
+
const explanation = inspector.explain(className);
|
|
75
|
+
if (explanation === null) {
|
|
76
|
+
unknown.push(className);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
known.push({ className, sortKey: explanation.sortKey, selector: explanation.selector });
|
|
80
|
+
}
|
|
81
|
+
known.sort((a, b) => a.sortKey - b.sortKey || codepointCompare(a.selector, b.selector));
|
|
82
|
+
const out = unknown;
|
|
83
|
+
for (const entry of known) out.push(entry.className);
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
var inspectorMemo = /* @__PURE__ */ new WeakMap();
|
|
87
|
+
function sortClasses(theme, classes) {
|
|
88
|
+
let inspector = inspectorMemo.get(theme);
|
|
89
|
+
if (inspector === void 0) {
|
|
90
|
+
inspector = createClassInspector(theme);
|
|
91
|
+
inspectorMemo.set(theme, inspector);
|
|
92
|
+
}
|
|
93
|
+
return sortClassesWithInspector(inspector, classes);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/editor/session.ts
|
|
97
|
+
function createEditorSession(options = {}) {
|
|
98
|
+
let css = options.css ?? "";
|
|
99
|
+
let analysis = null;
|
|
100
|
+
let inspector = null;
|
|
101
|
+
let enumeration = null;
|
|
102
|
+
let tokens = null;
|
|
103
|
+
let snapshot = null;
|
|
104
|
+
let importedFiles = [];
|
|
105
|
+
let effectiveCss = "";
|
|
106
|
+
const ensureAnalysis = () => {
|
|
107
|
+
if (analysis === null) {
|
|
108
|
+
const resolve = options.resolveImport;
|
|
109
|
+
if (resolve === void 0) {
|
|
110
|
+
importedFiles = [];
|
|
111
|
+
effectiveCss = css;
|
|
112
|
+
analysis = analyzeProjectCSS(css);
|
|
113
|
+
} else {
|
|
114
|
+
const inlined = inlineDirectiveImports(css, { resolve, from: options.cssPath });
|
|
115
|
+
importedFiles = inlined.files;
|
|
116
|
+
effectiveCss = inlined.css;
|
|
117
|
+
analysis = analyzeProjectCSS(inlined.css);
|
|
118
|
+
for (const warning of inlined.warnings) {
|
|
119
|
+
if (analysis.warningSeen.has(warning)) continue;
|
|
120
|
+
analysis.warningSeen.add(warning);
|
|
121
|
+
analysis.warnings.push(warning);
|
|
122
|
+
analysis.diagnostics.push(diagnosticFromWarning(warning, null));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return analysis;
|
|
127
|
+
};
|
|
128
|
+
const ensureSnapshot = () => {
|
|
129
|
+
snapshot ??= createThemeSnapshot(ensureAnalysis().theme);
|
|
130
|
+
return snapshot;
|
|
131
|
+
};
|
|
132
|
+
return {
|
|
133
|
+
get css() {
|
|
134
|
+
return css;
|
|
135
|
+
},
|
|
136
|
+
setCss(next) {
|
|
137
|
+
if (next === css) return;
|
|
138
|
+
css = next;
|
|
139
|
+
analysis = null;
|
|
140
|
+
inspector = null;
|
|
141
|
+
enumeration = null;
|
|
142
|
+
tokens = null;
|
|
143
|
+
snapshot = null;
|
|
144
|
+
},
|
|
145
|
+
get theme() {
|
|
146
|
+
return ensureAnalysis().theme;
|
|
147
|
+
},
|
|
148
|
+
get diagnostics() {
|
|
149
|
+
return ensureAnalysis().diagnostics;
|
|
150
|
+
},
|
|
151
|
+
get inspector() {
|
|
152
|
+
inspector ??= createClassInspector(ensureAnalysis().theme);
|
|
153
|
+
return inspector;
|
|
154
|
+
},
|
|
155
|
+
enumerate() {
|
|
156
|
+
enumeration ??= enumerateClassNames(ensureAnalysis().theme);
|
|
157
|
+
return enumeration;
|
|
158
|
+
},
|
|
159
|
+
tokens() {
|
|
160
|
+
tokens ??= listThemeTokens(ensureAnalysis().theme);
|
|
161
|
+
return tokens;
|
|
162
|
+
},
|
|
163
|
+
snapshot: ensureSnapshot,
|
|
164
|
+
analyzeMerge(classes) {
|
|
165
|
+
return analyzeMerge(classes, ensureSnapshot());
|
|
166
|
+
},
|
|
167
|
+
get importedFiles() {
|
|
168
|
+
ensureAnalysis();
|
|
169
|
+
return importedFiles;
|
|
170
|
+
},
|
|
171
|
+
extractCandidates(content, path) {
|
|
172
|
+
return extractClassCandidates({ content, path });
|
|
173
|
+
},
|
|
174
|
+
swatch(name, stop) {
|
|
175
|
+
return resolveColorSwatch(ensureAnalysis().theme, name, stop);
|
|
176
|
+
},
|
|
177
|
+
sortClasses(classNames) {
|
|
178
|
+
inspector ??= createClassInspector(ensureAnalysis().theme);
|
|
179
|
+
return sortClassesWithInspector(inspector, classNames);
|
|
180
|
+
},
|
|
181
|
+
render(classNames, renderOptions = {}) {
|
|
182
|
+
const theme = ensureAnalysis().theme;
|
|
183
|
+
return renderStylesheet(theme, classNames, {
|
|
184
|
+
...renderOptions,
|
|
185
|
+
userCSS: renderOptions.userCSS ?? stripRIDirectives(effectiveCss)
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export {
|
|
192
|
+
analyzeMerge,
|
|
193
|
+
renderStylesheet,
|
|
194
|
+
sortClasses,
|
|
195
|
+
createEditorSession
|
|
196
|
+
};
|