@mortenbrudvik/waveui 0.16.0 → 0.17.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/README.md +66 -17
- package/dist/components/input/Label.cjs +1 -1
- package/dist/components/input/Label.cjs.map +1 -1
- package/dist/components/input/Label.mjs +1 -0
- package/dist/components/input/Label.mjs.map +1 -1
- package/dist/components/portal/Portal.cjs +1 -1
- package/dist/components/portal/Portal.cjs.map +1 -1
- package/dist/components/portal/Portal.mjs +12 -11
- package/dist/components/portal/Portal.mjs.map +1 -1
- package/dist/components/provider/WaveProvider.cjs +1 -1
- package/dist/components/provider/WaveProvider.cjs.map +1 -1
- package/dist/components/provider/WaveProvider.mjs +59 -35
- package/dist/components/provider/WaveProvider.mjs.map +1 -1
- package/dist/components/typography/Text.cjs +1 -1
- package/dist/components/typography/Text.cjs.map +1 -1
- package/dist/components/typography/Text.mjs +11 -7
- package/dist/components/typography/Text.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +257 -10
- package/dist/index.d.ts +257 -10
- package/dist/index.mjs +143 -140
- package/dist/lib/brand.cjs +2 -0
- package/dist/lib/brand.cjs.map +1 -0
- package/dist/lib/brand.mjs +358 -0
- package/dist/lib/brand.mjs.map +1 -0
- package/dist/lib/cn.cjs +1 -1
- package/dist/lib/cn.cjs.map +1 -1
- package/dist/lib/cn.mjs +5 -1
- package/dist/lib/cn.mjs.map +1 -1
- package/dist/lib/tokens.cjs +2 -0
- package/dist/lib/tokens.cjs.map +1 -0
- package/dist/lib/tokens.mjs +43 -0
- package/dist/lib/tokens.mjs.map +1 -0
- package/dist/lib/waveTokens.cjs +2 -0
- package/dist/lib/waveTokens.cjs.map +1 -0
- package/dist/lib/waveTokens.mjs +24 -0
- package/dist/lib/waveTokens.mjs.map +1 -0
- package/dist/styles.css +1 -1
- package/package.json +3 -1
- package/src/styles/tokens.css +210 -10
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { warnOnce as e } from "./dev.mjs";
|
|
2
|
+
//#region src/lib/brand.ts
|
|
3
|
+
var t = [
|
|
4
|
+
10,
|
|
5
|
+
20,
|
|
6
|
+
30,
|
|
7
|
+
40,
|
|
8
|
+
50,
|
|
9
|
+
60,
|
|
10
|
+
70,
|
|
11
|
+
80,
|
|
12
|
+
90,
|
|
13
|
+
100,
|
|
14
|
+
110,
|
|
15
|
+
120,
|
|
16
|
+
130,
|
|
17
|
+
140,
|
|
18
|
+
150,
|
|
19
|
+
160
|
|
20
|
+
], n = 7, r = /* @__PURE__ */ Object.freeze({
|
|
21
|
+
10: "#061724",
|
|
22
|
+
20: "#082338",
|
|
23
|
+
30: "#0a2e4a",
|
|
24
|
+
40: "#0c3b5e",
|
|
25
|
+
50: "#0e4775",
|
|
26
|
+
60: "#0f548c",
|
|
27
|
+
70: "#115ea3",
|
|
28
|
+
80: "#0f6cbd",
|
|
29
|
+
90: "#2886de",
|
|
30
|
+
100: "#479ef5",
|
|
31
|
+
110: "#62abf5",
|
|
32
|
+
120: "#77b7f7",
|
|
33
|
+
130: "#96c6fa",
|
|
34
|
+
140: "#b4d6fa",
|
|
35
|
+
150: "#cfe4fa",
|
|
36
|
+
160: "#ebf3fc"
|
|
37
|
+
}), i = .005, a = [
|
|
38
|
+
10,
|
|
39
|
+
20,
|
|
40
|
+
30,
|
|
41
|
+
40,
|
|
42
|
+
50,
|
|
43
|
+
60,
|
|
44
|
+
70,
|
|
45
|
+
80,
|
|
46
|
+
140
|
|
47
|
+
];
|
|
48
|
+
function o(e) {
|
|
49
|
+
if (typeof e != "string") return;
|
|
50
|
+
let t = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(e);
|
|
51
|
+
if (!t) return;
|
|
52
|
+
let n = t[1].length === 3 ? t[1].replace(/./g, "$&$&") : t[1];
|
|
53
|
+
return [
|
|
54
|
+
0,
|
|
55
|
+
2,
|
|
56
|
+
4
|
|
57
|
+
].map((e) => parseInt(n.slice(e, e + 2), 16));
|
|
58
|
+
}
|
|
59
|
+
function s(e) {
|
|
60
|
+
let t = e / 255;
|
|
61
|
+
return t <= .04045 ? t / 12.92 : ((t + .055) / 1.055) ** 2.4;
|
|
62
|
+
}
|
|
63
|
+
function c(e) {
|
|
64
|
+
let t = Math.min(1, Math.max(0, e));
|
|
65
|
+
return 255 * (t <= .0031308 ? t * 12.92 : 1.055 * t ** (1 / 2.4) - .055);
|
|
66
|
+
}
|
|
67
|
+
function l([e, t, n]) {
|
|
68
|
+
return .2126 * e + .7152 * t + .0722 * n;
|
|
69
|
+
}
|
|
70
|
+
function u([e, t, n]) {
|
|
71
|
+
let r = Math.cbrt(.4122214708 * e + .5363325363 * t + .0514459929 * n), i = Math.cbrt(.2119034982 * e + .6806995451 * t + .1073969566 * n), a = Math.cbrt(.0883024619 * e + .2817188376 * t + .6299787005 * n);
|
|
72
|
+
return [
|
|
73
|
+
.2104542553 * r + .793617785 * i - .0040720468 * a,
|
|
74
|
+
1.9779984951 * r - 2.428592205 * i + .4505937099 * a,
|
|
75
|
+
.0259040371 * r + .7827717662 * i - .808675766 * a
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
function d(e, t, n) {
|
|
79
|
+
let r = t * Math.cos(n), i = t * Math.sin(n), a = (e + .3963377774 * r + .2158037573 * i) ** 3, o = (e - .1055613458 * r - .0638541728 * i) ** 3, s = (e - .0894841775 * r - 1.291485548 * i) ** 3;
|
|
80
|
+
return [
|
|
81
|
+
4.0767416621 * a - 3.3077115913 * o + .2309699292 * s,
|
|
82
|
+
-1.2684380046 * a + 2.6097574011 * o - .3413193965 * s,
|
|
83
|
+
-.0041960863 * a - .7034186147 * o + 1.707614701 * s
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
function f(e) {
|
|
87
|
+
let [, t, n] = u(e);
|
|
88
|
+
return [Math.hypot(t, n), Math.atan2(n, t)];
|
|
89
|
+
}
|
|
90
|
+
function p(e) {
|
|
91
|
+
return e.every((e) => e >= -1e-9 && e <= 1 + 1e-9);
|
|
92
|
+
}
|
|
93
|
+
function m(e, t, n) {
|
|
94
|
+
if (p(d(e, t, n))) return t;
|
|
95
|
+
let r = 0, i = t;
|
|
96
|
+
for (let t = 0; t < 32; t++) {
|
|
97
|
+
let t = (r + i) / 2;
|
|
98
|
+
p(d(e, t, n)) ? r = t : i = t;
|
|
99
|
+
}
|
|
100
|
+
return r;
|
|
101
|
+
}
|
|
102
|
+
function h(e, t, n) {
|
|
103
|
+
let r = (e) => d(e, m(e, t, n), n).map((e) => Math.min(1, Math.max(0, e))), i = 0, a = 1;
|
|
104
|
+
for (let t = 0; t < 40; t++) {
|
|
105
|
+
let t = (i + a) / 2;
|
|
106
|
+
l(r(t)) < e ? i = t : a = t;
|
|
107
|
+
}
|
|
108
|
+
return r((i + a) / 2);
|
|
109
|
+
}
|
|
110
|
+
function g(e, t, n, r) {
|
|
111
|
+
let i = e.map((e) => Math.round(c(e))), a = [
|
|
112
|
+
0,
|
|
113
|
+
-1,
|
|
114
|
+
1
|
|
115
|
+
], o = i, u = Infinity;
|
|
116
|
+
for (let e of a) for (let c of n ? [e] : a) for (let d of n ? [e] : a) {
|
|
117
|
+
let n = i.map((t, n) => Math.min(255, Math.max(0, t + [
|
|
118
|
+
e,
|
|
119
|
+
c,
|
|
120
|
+
d
|
|
121
|
+
][n]))), a = l(n.map(s)), f = Math.abs(a - t) + +(r ? a > t : a < t);
|
|
122
|
+
f < u && (o = n, u = f);
|
|
123
|
+
}
|
|
124
|
+
return `#${o.map((e) => e.toString(16).padStart(2, "0")).join("")}`;
|
|
125
|
+
}
|
|
126
|
+
var _ = "#ffffff", v = "#000000", y = "#ebebeb", b = "#107c10", x = "#383838", S = {
|
|
127
|
+
light: [
|
|
128
|
+
[
|
|
129
|
+
"primary",
|
|
130
|
+
80,
|
|
131
|
+
"subtle-selected",
|
|
132
|
+
y,
|
|
133
|
+
4.5
|
|
134
|
+
],
|
|
135
|
+
[
|
|
136
|
+
"primary",
|
|
137
|
+
80,
|
|
138
|
+
"selected",
|
|
139
|
+
160,
|
|
140
|
+
4.5
|
|
141
|
+
],
|
|
142
|
+
[
|
|
143
|
+
"primary-hover",
|
|
144
|
+
70,
|
|
145
|
+
"primary-foreground",
|
|
146
|
+
_,
|
|
147
|
+
4.5
|
|
148
|
+
],
|
|
149
|
+
[
|
|
150
|
+
"primary-pressed",
|
|
151
|
+
40,
|
|
152
|
+
"primary-foreground",
|
|
153
|
+
_,
|
|
154
|
+
4.5
|
|
155
|
+
],
|
|
156
|
+
[
|
|
157
|
+
"selected",
|
|
158
|
+
160,
|
|
159
|
+
"success",
|
|
160
|
+
b,
|
|
161
|
+
4.5
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
"selected-foreground",
|
|
165
|
+
60,
|
|
166
|
+
"selected",
|
|
167
|
+
160,
|
|
168
|
+
4.5
|
|
169
|
+
],
|
|
170
|
+
[
|
|
171
|
+
"selected-foreground",
|
|
172
|
+
60,
|
|
173
|
+
"selected-hover",
|
|
174
|
+
150,
|
|
175
|
+
4.5
|
|
176
|
+
],
|
|
177
|
+
[
|
|
178
|
+
"selected-foreground",
|
|
179
|
+
60,
|
|
180
|
+
"selected-pressed",
|
|
181
|
+
140,
|
|
182
|
+
4.5
|
|
183
|
+
],
|
|
184
|
+
[
|
|
185
|
+
"selected-hover",
|
|
186
|
+
150,
|
|
187
|
+
"selected",
|
|
188
|
+
160,
|
|
189
|
+
1.15
|
|
190
|
+
],
|
|
191
|
+
[
|
|
192
|
+
"selected-pressed",
|
|
193
|
+
140,
|
|
194
|
+
"selected-hover",
|
|
195
|
+
150,
|
|
196
|
+
1.15
|
|
197
|
+
],
|
|
198
|
+
[
|
|
199
|
+
"ring",
|
|
200
|
+
80,
|
|
201
|
+
"subtle-selected",
|
|
202
|
+
y,
|
|
203
|
+
3
|
|
204
|
+
]
|
|
205
|
+
],
|
|
206
|
+
dark: [
|
|
207
|
+
[
|
|
208
|
+
"primary",
|
|
209
|
+
110,
|
|
210
|
+
"subtle-selected",
|
|
211
|
+
x,
|
|
212
|
+
4.5
|
|
213
|
+
],
|
|
214
|
+
[
|
|
215
|
+
"primary-hover",
|
|
216
|
+
120,
|
|
217
|
+
"primary-foreground",
|
|
218
|
+
v,
|
|
219
|
+
4.5
|
|
220
|
+
],
|
|
221
|
+
[
|
|
222
|
+
"primary-pressed",
|
|
223
|
+
90,
|
|
224
|
+
"primary-foreground",
|
|
225
|
+
v,
|
|
226
|
+
4.5
|
|
227
|
+
],
|
|
228
|
+
[
|
|
229
|
+
"selected",
|
|
230
|
+
20,
|
|
231
|
+
"success",
|
|
232
|
+
"#5db55d",
|
|
233
|
+
4.5
|
|
234
|
+
],
|
|
235
|
+
[
|
|
236
|
+
"selected-foreground",
|
|
237
|
+
110,
|
|
238
|
+
"selected",
|
|
239
|
+
20,
|
|
240
|
+
4.5
|
|
241
|
+
],
|
|
242
|
+
[
|
|
243
|
+
"selected-foreground",
|
|
244
|
+
110,
|
|
245
|
+
"selected-hover",
|
|
246
|
+
40,
|
|
247
|
+
4.5
|
|
248
|
+
],
|
|
249
|
+
[
|
|
250
|
+
"selected-foreground",
|
|
251
|
+
110,
|
|
252
|
+
"selected-pressed",
|
|
253
|
+
10,
|
|
254
|
+
4.5
|
|
255
|
+
],
|
|
256
|
+
[
|
|
257
|
+
"selected-hover",
|
|
258
|
+
40,
|
|
259
|
+
"selected",
|
|
260
|
+
20,
|
|
261
|
+
1.15
|
|
262
|
+
],
|
|
263
|
+
[
|
|
264
|
+
"selected-pressed",
|
|
265
|
+
10,
|
|
266
|
+
"selected-hover",
|
|
267
|
+
40,
|
|
268
|
+
1.15
|
|
269
|
+
],
|
|
270
|
+
[
|
|
271
|
+
"ring",
|
|
272
|
+
100,
|
|
273
|
+
"subtle-selected",
|
|
274
|
+
x,
|
|
275
|
+
3
|
|
276
|
+
],
|
|
277
|
+
[
|
|
278
|
+
"ring",
|
|
279
|
+
100,
|
|
280
|
+
"selected",
|
|
281
|
+
20,
|
|
282
|
+
3
|
|
283
|
+
]
|
|
284
|
+
]
|
|
285
|
+
};
|
|
286
|
+
function C(e) {
|
|
287
|
+
let t = o(e);
|
|
288
|
+
return t && l(t.map(s));
|
|
289
|
+
}
|
|
290
|
+
function w(t) {
|
|
291
|
+
for (let [n, r] of Object.entries(S)) for (let [i, a, o, s, c] of r) {
|
|
292
|
+
let r = C(t[a]), l = C(typeof s == "number" ? t[s] : s);
|
|
293
|
+
if (r === void 0 || l === void 0) continue;
|
|
294
|
+
let u = (Math.max(r, l) + .05) / (Math.min(r, l) + .05);
|
|
295
|
+
u >= c || e(`createBrandTokens:contrast:${n}:${i}:${o}`, `createBrandTokens: in the ${n} theme, \`${i}\` on \`${o}\` (stop ${a} on ${typeof s == "number" ? `stop ${s}` : s}) is ${Math.floor(u * 100) / 100}:1; needs ${c}:1.`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
var T;
|
|
299
|
+
function E() {
|
|
300
|
+
if (T) return T;
|
|
301
|
+
let e = t.map((e) => o(r[e]).map(s)), [i, a] = f(e[n]);
|
|
302
|
+
T = {
|
|
303
|
+
luminance: [],
|
|
304
|
+
chroma: [],
|
|
305
|
+
hue: []
|
|
306
|
+
};
|
|
307
|
+
for (let t of e) {
|
|
308
|
+
let [e, n] = f(t);
|
|
309
|
+
T.luminance.push(l(t)), T.chroma.push(e / i), T.hue.push(n - a);
|
|
310
|
+
}
|
|
311
|
+
return T;
|
|
312
|
+
}
|
|
313
|
+
function D(e) {
|
|
314
|
+
let n = {};
|
|
315
|
+
return t.forEach((t, r) => {
|
|
316
|
+
n[`brand${t}`] = e(t, r);
|
|
317
|
+
}), n;
|
|
318
|
+
}
|
|
319
|
+
function O([e, t, n]) {
|
|
320
|
+
let [r, o] = f([
|
|
321
|
+
s(e),
|
|
322
|
+
s(t),
|
|
323
|
+
s(n)
|
|
324
|
+
]), c = E(), l = r < i;
|
|
325
|
+
return D((e, t) => {
|
|
326
|
+
let n = c.luminance[t];
|
|
327
|
+
return g(l ? [
|
|
328
|
+
n,
|
|
329
|
+
n,
|
|
330
|
+
n
|
|
331
|
+
] : h(n, r * c.chroma[t], o + c.hue[t]), n, l, a.includes(e));
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
function k(t) {
|
|
335
|
+
let n = [], i = {}, a = D((e) => {
|
|
336
|
+
let a = t[e];
|
|
337
|
+
return typeof a == "string" && o(a) ? i[e] = a : (n.push(e), i[e] = r[e]);
|
|
338
|
+
});
|
|
339
|
+
if (n.length > 0) {
|
|
340
|
+
let t = n.length > 1;
|
|
341
|
+
e("createBrandTokens:ramp", `createBrandTokens: the ramp has no #rgb or #rrggbb colour at the stop${t ? "s" : ""} ${n.join(", ")}, so the default ramp's colour${t ? "s are" : " is"} used there.`);
|
|
342
|
+
}
|
|
343
|
+
try {
|
|
344
|
+
process.env.NODE_ENV !== "production" && w(i);
|
|
345
|
+
} catch {}
|
|
346
|
+
return a;
|
|
347
|
+
}
|
|
348
|
+
function A(t) {
|
|
349
|
+
if (typeof t == "object" && t) return k(t);
|
|
350
|
+
let n = o(t);
|
|
351
|
+
if (n) return O(n);
|
|
352
|
+
let i = typeof t == "string" ? `"${t.length > 32 ? `${t.slice(0, 32)}…` : t}"` : t == null ? String(t) : `a ${typeof t}`;
|
|
353
|
+
return e("createBrandTokens:seed", `createBrandTokens: the seed ${i} is not a #rgb or #rrggbb colour, so the default brand ramp is used.`), D((e) => r[e]);
|
|
354
|
+
}
|
|
355
|
+
//#endregion
|
|
356
|
+
export { S as BRAND_CONTRAST_PAIRS, r as DEFAULT_BRAND_RAMP, a as ROUNDS_DARKER, w as checkBrandRamp, A as createBrandTokens };
|
|
357
|
+
|
|
358
|
+
//# sourceMappingURL=brand.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brand.mjs","names":["BRAND_STOPS","SEED_INDEX","DEFAULT_BRAND_RAMP","GREY_CHROMA","ROUNDS_DARKER","parseHex","value","match","digits","offset","toLinear","channel","toEncoded","linear","luminance","r","g","b","toOklab","l","m","s","fromOklch","a","chroma","hue","lightness","chromaAndHue","rgb","inGamut","fitChroma","low","high","step","middle","colourAtLuminance","colourAt","target","toHex","rounded","offsets","best","bestRank","red","green","grey","blue","candidate","index","rank","darker","WHITE","BLACK","LIGHT_SUBTLE_SELECTED","LIGHT_SUCCESS","DARK_SUBTLE_SELECTED","BRAND_CONTRAST_PAIRS","luminanceOf","checkBrandRamp","theme","pairs","token","stop","against","colour","minimum","own","ramp","other","ratio","warnOnce","defaultShape","getDefaultShape","colours","seedChroma","seedHue","toTokens","tokens","colourOf","rampFromSeed","shape","rampFromStops","invalid","used","several","createBrandTokens","seed","shown"],"sources":["../../src/lib/brand.ts"],"sourcesContent":["/**\n * Brand ramps: `createBrandTokens` builds the 16 brand tokens from a seed colour, or takes a full\n * ramp, which it checks against the pairs the themes read from it in development. Server-safe and\n * pure: no DOM and no React; its only run-time import is the development warnings. The colour\n * maths (sRGB, linear light, OKLab and OKLCH) is small and local to it.\n */\nimport { warnOnce } from './dev';\n\n/**\n * A stop of the brand ramp, from 10 (the darkest) to 160 (the lightest) in steps of 10: the stops\n * of Fluent's `BrandVariants` and of the `--wave-brand-N` tokens.\n */\nexport type BrandStop =\n 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 | 100 | 110 | 120 | 130 | 140 | 150 | 160;\n\n/**\n * A full brand ramp: a hex colour (`#rgb` or `#rrggbb`) for each of the 16 stops, darkest first.\n * The shape of Fluent's `BrandVariants`, which `createLightTheme(brand)` and\n * `createDarkTheme(brand)` take. The themes read the light primary from stop 80 (hover 70, pressed\n * 40, focus ring 80), the light selection from stops 160, 150 and 140 with its text at 60, the\n * dark primary from stop 110 (hover 120, pressed 90, focus ring 100) and the dark selection from\n * stops 20, 40 and 10 with its text at 110. A ramp whose stops have the luminance of the default\n * ramp's keeps the contrast of the light and dark themes; the high-contrast theme reads no stop.\n */\nexport type BrandRamp = Readonly<Record<BrandStop, string>>;\n\n/**\n * The 16 brand tokens, `brand10` to `brand160`: the overrides of `--wave-brand-10` to\n * `--wave-brand-160`, in the shape `WaveProvider tokens` and `getTokenStyle` take. Where Fluent's\n * `createLightTheme(brand)` builds a whole theme from a `BrandVariants` ramp, Wave applies the\n * ramp as these tokens over its named themes; the high-contrast theme reads none of them.\n */\nexport type BrandTokens = { [K in `brand${BrandStop}`]: string };\n\nconst BRAND_STOPS: readonly BrandStop[] = [\n 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160,\n];\n\n/** The index of stop 80 in `BRAND_STOPS`: the stop a seed's chroma and hue describe. */\nconst SEED_INDEX = 7;\n\n/**\n * The default brand ramp: the fallbacks of the `--wave-brand-N` declarations of `tokens.css`\n * (Fluent's brand ramp), which a test keeps equal.\n */\nexport const DEFAULT_BRAND_RAMP: BrandRamp = /* @__PURE__ */ Object.freeze({\n 10: '#061724',\n 20: '#082338',\n 30: '#0a2e4a',\n 40: '#0c3b5e',\n 50: '#0e4775',\n 60: '#0f548c',\n 70: '#115ea3',\n 80: '#0f6cbd',\n 90: '#2886de',\n 100: '#479ef5',\n 110: '#62abf5',\n 120: '#77b7f7',\n 130: '#96c6fa',\n 140: '#b4d6fa',\n 150: '#cfe4fa',\n 160: '#ebf3fc',\n});\n\n/** Under this OKLCH chroma a seed has no visible hue, and its ramp is grey. */\nconst GREY_CHROMA = 0.005;\n\n/**\n * The stops a generated ramp rounds darker, because the themes pair them with lighter colours:\n * 10 to 80 are fills under light text, text and focus rings on light surfaces, and the dark\n * theme's selection fills under light text; 140, the light theme's pressed selection fill, must\n * stay a visible step below the hover fill at 150. The other stops round lighter: the dark\n * theme's fills under dark text, its text and focus ring on dark surfaces, and the light theme's\n * selection fills under dark text (30, 50 and 130 are read by no theme; their side is arbitrary).\n * Three stops have pairs on both sides and take the side of the thinner one: 40 rounds darker for\n * the dark selected text on it (4.81:1) against its steps above the dark selection fills at 20 and\n * 10 (1.38 and 1.56); 150 rounds lighter for its step above 140 (1.157) against its step below\n * 160 (1.163); 140 rounds darker for that step against the light selected text at 60 on it\n * (5.23:1). So the pairs whose two stops round the same way (150 and 160, 40 and 20, 10 and 40,\n * 60 and 140) can lose up to one rounding step of contrast, and each has more margin over its\n * floor (1.15 between the states of a fill, 4.5 for text) than that. A test derives the sides\n * from the pairs of tokens.css and keeps this list equal to them.\n */\nexport const ROUNDS_DARKER: readonly BrandStop[] = [10, 20, 30, 40, 50, 60, 70, 80, 140];\n\n// ---------------------------------------------------------------------------------------------\n// Colour maths\n// ---------------------------------------------------------------------------------------------\n\ntype Triple = [number, number, number];\n\n/** `#rgb` or `#rrggbb` (any case) as 8-bit channels; `undefined` for anything else. */\nfunction parseHex(value: unknown): Triple | undefined {\n if (typeof value !== 'string') return undefined;\n const match = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(value);\n if (!match) return undefined;\n const digits = match[1].length === 3 ? match[1].replace(/./g, '$&$&') : match[1];\n return [0, 2, 4].map((offset) => parseInt(digits.slice(offset, offset + 2), 16)) as Triple;\n}\n\n/** An 8-bit sRGB channel in linear light (0 to 1). */\nfunction toLinear(channel: number): number {\n const value = channel / 255;\n return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;\n}\n\n/** A linear channel as an unrounded 8-bit sRGB value. */\nfunction toEncoded(linear: number): number {\n const value = Math.min(1, Math.max(0, linear));\n return 255 * (value <= 0.0031308 ? value * 12.92 : 1.055 * value ** (1 / 2.4) - 0.055);\n}\n\n/** The WCAG relative luminance of a linear colour. */\nfunction luminance([r, g, b]: Triple): number {\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\n/** A linear sRGB colour in OKLab (lightness, a, b). */\nfunction toOklab([r, g, b]: Triple): Triple {\n const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);\n const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);\n const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);\n return [\n 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,\n 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,\n ];\n}\n\n/** An OKLCH colour (hue in radians) in linear sRGB, which may lie outside the gamut. */\nfunction fromOklch(lightness: number, chroma: number, hue: number): Triple {\n const a = chroma * Math.cos(hue);\n const b = chroma * Math.sin(hue);\n const l = (lightness + 0.3963377774 * a + 0.2158037573 * b) ** 3;\n const m = (lightness - 0.1055613458 * a - 0.0638541728 * b) ** 3;\n const s = (lightness - 0.0894841775 * a - 1.291485548 * b) ** 3;\n return [\n 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,\n -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,\n -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s,\n ];\n}\n\n/** A linear sRGB colour as OKLCH chroma and hue (radians). */\nfunction chromaAndHue(rgb: Triple): [chroma: number, hue: number] {\n const [, a, b] = toOklab(rgb);\n return [Math.hypot(a, b), Math.atan2(b, a)];\n}\n\nfunction inGamut(rgb: Triple): boolean {\n return rgb.every((channel) => channel >= -1e-9 && channel <= 1 + 1e-9);\n}\n\n/** `chroma` at this lightness and hue, reduced by bisection until the colour fits sRGB. */\nfunction fitChroma(lightness: number, chroma: number, hue: number): number {\n if (inGamut(fromOklch(lightness, chroma, hue))) return chroma;\n let low = 0;\n let high = chroma;\n for (let step = 0; step < 32; step++) {\n const middle = (low + high) / 2;\n if (inGamut(fromOklch(lightness, middle, hue))) low = middle;\n else high = middle;\n }\n return low;\n}\n\n/** The colour of this hue and (at most) this chroma whose luminance is `target`, by bisection. */\nfunction colourAtLuminance(target: number, chroma: number, hue: number): Triple {\n const colourAt = (lightness: number): Triple =>\n fromOklch(lightness, fitChroma(lightness, chroma, hue), hue).map((channel) =>\n Math.min(1, Math.max(0, channel)),\n ) as Triple;\n let low = 0;\n let high = 1;\n for (let step = 0; step < 40; step++) {\n const middle = (low + high) / 2;\n if (luminance(colourAt(middle)) < target) low = middle;\n else high = middle;\n }\n return colourAt((low + high) / 2);\n}\n\n/**\n * A linear colour as `#rrggbb`, rounded on the safe side: of the 8-bit colours at most one step\n * from it on each channel, the one nearest `target` in luminance that is no lighter (`darker`) or\n * no darker than it. So rounding never takes contrast from a stop against a colour that does not\n * round the same way (a colour of the theme, or a stop that rounds the other way); two stops that\n * round the same way lose at most one rounding step between them. A grey stays a grey.\n */\nfunction toHex(rgb: Triple, target: number, grey: boolean, darker: boolean): string {\n const rounded = rgb.map((channel) => Math.round(toEncoded(channel)));\n const offsets = [0, -1, 1];\n let best = rounded;\n let bestRank = Infinity;\n for (const red of offsets) {\n for (const green of grey ? [red] : offsets) {\n for (const blue of grey ? [red] : offsets) {\n const candidate = rounded.map((channel, index) =>\n Math.min(255, Math.max(0, channel + [red, green, blue][index])),\n );\n const value = luminance(candidate.map(toLinear) as Triple);\n // A colour past the target on the unsafe side ranks after every other (one step below\n // the rounded colour is always on the dark side, one above on the light side).\n const rank =\n Math.abs(value - target) + ((darker ? value > target : value < target) ? 1 : 0);\n if (rank < bestRank) {\n best = candidate;\n bestRank = rank;\n }\n }\n }\n }\n return `#${best.map((channel) => channel.toString(16).padStart(2, '0')).join('')}`;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Checking a full ramp\n// ---------------------------------------------------------------------------------------------\n\n// Colours of the light and dark themes that a checked pair reads a stop against: the values of\n// their tokens in tokens.css, which a test keeps equal.\nconst WHITE = '#ffffff';\nconst BLACK = '#000000';\nconst LIGHT_SUBTLE_SELECTED = '#ebebeb';\nconst LIGHT_SUCCESS = '#107c10';\nconst DARK_SUBTLE_SELECTED = '#383838';\nconst DARK_SUCCESS = '#5db55d';\n\n/**\n * A pair the check measures: the token that reads a stop, the stop, the token it is read against,\n * that token's colour (a colour of the theme, or the stop it reads) and the least contrast the\n * pair needs (4.5 for text, 3 for a focus ring, 1.15 between the states of a fill).\n */\ntype BrandContrastPair = readonly [\n token: string,\n stop: BrandStop,\n against: string,\n colour: string | BrandStop,\n minimum: number,\n];\n\n/**\n * Where the light and dark themes read the ramp: every `var(--wave-brand-N)` of their groups in\n * tokens.css, as the pairs the check of a full ramp measures. Of the pairs of the contrast matrix\n * that read a stop, it keeps the one theme colour that bounds each token's stop (the closest in\n * luminance at its minimum: the darkest light surface under the light primary text, the lightest\n * dark surface under the dark primary text, the lightest text on the light selection fill, the\n * darkest text on the dark one, the on-brand text of the fill states), and every pair of two stops\n * those bounds do not already decide. Tests keep it in step with tokens.css and prove that a ramp\n * that passes these pairs passes every pair of the matrix that reads a stop. High contrast reads\n * no stop.\n */\nexport const BRAND_CONTRAST_PAIRS: Readonly<\n Record<'light' | 'dark', readonly BrandContrastPair[]>\n> = {\n light: [\n ['primary', 80, 'subtle-selected', LIGHT_SUBTLE_SELECTED, 4.5],\n ['primary', 80, 'selected', 160, 4.5],\n ['primary-hover', 70, 'primary-foreground', WHITE, 4.5],\n ['primary-pressed', 40, 'primary-foreground', WHITE, 4.5],\n ['selected', 160, 'success', LIGHT_SUCCESS, 4.5],\n ['selected-foreground', 60, 'selected', 160, 4.5],\n ['selected-foreground', 60, 'selected-hover', 150, 4.5],\n ['selected-foreground', 60, 'selected-pressed', 140, 4.5],\n ['selected-hover', 150, 'selected', 160, 1.15],\n ['selected-pressed', 140, 'selected-hover', 150, 1.15],\n ['ring', 80, 'subtle-selected', LIGHT_SUBTLE_SELECTED, 3],\n ],\n dark: [\n ['primary', 110, 'subtle-selected', DARK_SUBTLE_SELECTED, 4.5],\n ['primary-hover', 120, 'primary-foreground', BLACK, 4.5],\n ['primary-pressed', 90, 'primary-foreground', BLACK, 4.5],\n ['selected', 20, 'success', DARK_SUCCESS, 4.5],\n ['selected-foreground', 110, 'selected', 20, 4.5],\n ['selected-foreground', 110, 'selected-hover', 40, 4.5],\n ['selected-foreground', 110, 'selected-pressed', 10, 4.5],\n ['selected-hover', 40, 'selected', 20, 1.15],\n ['selected-pressed', 10, 'selected-hover', 40, 1.15],\n ['ring', 100, 'subtle-selected', DARK_SUBTLE_SELECTED, 3],\n ['ring', 100, 'selected', 20, 3],\n ],\n};\n\n/** The WCAG relative luminance of a `#rgb` or `#rrggbb` colour; `undefined` for anything else. */\nfunction luminanceOf(value: unknown): number | undefined {\n const rgb = parseHex(value);\n return rgb && luminance(rgb.map(toLinear) as Triple);\n}\n\n/**\n * The development check of a full ramp (R8): warns once per pair of `BRAND_CONTRAST_PAIRS` whose\n * contrast is below its minimum, naming the theme, the tokens, the stops and the ratio (rounded\n * down, so a failing ratio never reads as its minimum). Advisory: it never throws, never changes\n * the ramp, and skips a stop that is not a hex colour.\n */\nexport function checkBrandRamp(ramp: BrandRamp): void {\n for (const [theme, pairs] of Object.entries(BRAND_CONTRAST_PAIRS)) {\n for (const [token, stop, against, colour, minimum] of pairs) {\n const own = luminanceOf(ramp[stop]);\n const other = luminanceOf(typeof colour === 'number' ? ramp[colour] : colour);\n if (own === undefined || other === undefined) continue;\n const ratio = (Math.max(own, other) + 0.05) / (Math.min(own, other) + 0.05);\n if (ratio >= minimum) continue;\n warnOnce(\n `createBrandTokens:contrast:${theme}:${token}:${against}`,\n `createBrandTokens: in the ${theme} theme, \\`${token}\\` on \\`${against}\\` (stop ${stop} on ` +\n `${typeof colour === 'number' ? `stop ${colour}` : colour}) is ` +\n `${Math.floor(ratio * 100) / 100}:1; needs ${minimum}:1.`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------------------------\n// Ramps\n// ---------------------------------------------------------------------------------------------\n\n/**\n * The shape of the default ramp, per stop: its luminance, its chroma as a share of stop 80's, and\n * its hue's offset from stop 80's (radians). Computed on first use.\n */\nlet defaultShape: { luminance: number[]; chroma: number[]; hue: number[] } | undefined;\n\nfunction getDefaultShape(): NonNullable<typeof defaultShape> {\n if (defaultShape) return defaultShape;\n const colours = BRAND_STOPS.map(\n (stop) => (parseHex(DEFAULT_BRAND_RAMP[stop]) as Triple).map(toLinear) as Triple,\n );\n const [seedChroma, seedHue] = chromaAndHue(colours[SEED_INDEX]);\n defaultShape = { luminance: [], chroma: [], hue: [] };\n for (const colour of colours) {\n const [chroma, hue] = chromaAndHue(colour);\n defaultShape.luminance.push(luminance(colour));\n defaultShape.chroma.push(chroma / seedChroma);\n defaultShape.hue.push(hue - seedHue);\n }\n return defaultShape;\n}\n\nfunction toTokens(colourOf: (stop: BrandStop, index: number) => string): BrandTokens {\n const tokens: Partial<BrandTokens> = {};\n BRAND_STOPS.forEach((stop, index) => {\n tokens[`brand${stop}`] = colourOf(stop, index);\n });\n return tokens as BrandTokens;\n}\n\nfunction rampFromSeed([red, green, blue]: Triple): BrandTokens {\n const [chroma, hue] = chromaAndHue([toLinear(red), toLinear(green), toLinear(blue)]);\n const shape = getDefaultShape();\n const grey = chroma < GREY_CHROMA;\n return toTokens((stop, index) => {\n const target = shape.luminance[index];\n const colour: Triple = grey\n ? [target, target, target]\n : colourAtLuminance(target, chroma * shape.chroma[index], hue + shape.hue[index]);\n return toHex(colour, target, grey, ROUNDS_DARKER.includes(stop));\n });\n}\n\nfunction rampFromStops(ramp: BrandRamp): BrandTokens {\n const invalid: BrandStop[] = [];\n // The colours the tokens take, checked below: the ramp's, or the default's where it has none.\n const used = {} as Record<BrandStop, string>;\n const tokens = toTokens((stop) => {\n const value: unknown = ramp[stop];\n if (typeof value === 'string' && parseHex(value)) return (used[stop] = value);\n invalid.push(stop);\n return (used[stop] = DEFAULT_BRAND_RAMP[stop]);\n });\n if (invalid.length > 0) {\n const several = invalid.length > 1;\n warnOnce(\n 'createBrandTokens:ramp',\n `createBrandTokens: the ramp has no #rgb or #rrggbb colour at the stop${several ? 's' : ''} ` +\n `${invalid.join(', ')}, so the default ramp's colour${several ? 's are' : ' is'} used there.`,\n );\n }\n // The mode is read here as `lib/dev` reads it, written out so a bundler replaces it: a\n // production bundle then drops the check and its table. Without a bundler and without\n // `process` (an unbundled import in a browser), the read throws and the check is skipped.\n try {\n if (process.env.NODE_ENV !== 'production') checkBrandRamp(used);\n } catch {\n // No `process`: see above.\n }\n return tokens;\n}\n\n/**\n * The brand tokens of a brand colour or of a full ramp, to pass as `WaveProvider tokens` (alone or\n * spread with other overrides) or to `getTokenStyle`. Wave's counterpart of Fluent's\n * `createLightTheme(brand)` and `createDarkTheme(brand)`, which take a full `BrandVariants` ramp;\n * Wave also builds the ramp from one colour. The high-contrast theme ignores the brand: its colours\n * are fixed.\n *\n * From a seed (`#rgb` or `#rrggbb`, any case, with the `#`), each stop keeps the **luminance of the\n * default ramp's stop** and takes its hue and colourfulness from the seed: the seed's OKLCH chroma\n * and hue, shaped per stop like the default ramp (less colourful toward both ends, the hue\n * drifting a few degrees as the default's does), reduced where the colour would leave sRGB, and\n * rounded to a neighbouring 8-bit colour on the side that keeps its contrast. Contrast depends\n * only on luminance, so every text, fill, stroke and focus-ring pair of the light and dark themes\n * keeps, to within 8-bit rounding, the contrast it has with the default ramp, and stays above the\n * floor the themes are held to (4.5:1 for text, 3:1 for strokes, graphics and focus rings, 1.15:1\n * between the states of a fill), whatever the seed. The cost: the seed sets hue and\n * colourfulness, not lightness, so the primary fill (stop 80) is the seed's hue at the default's\n * lightness, and a light seed gives a darker button than itself. For a brand whose exact colours\n * matter, pass a full `BrandRamp`. The default seed `#0f6cbd` gives the default ramp, and a grey\n * seed (black, white or any grey) a grey ramp.\n *\n * A full `BrandRamp` is returned as tokens with its colours unchanged; a stop that is missing or\n * not a hex colour takes the default ramp's colour, with a development warning. In development the\n * ramp is also checked against the pairs the light and dark themes read from it (the primary\n * colour as text and as a fill under its text, the hover and pressed fills, the selection fills\n * and their text, the focus ring): each pair below its minimum (4.5:1 for text, 3:1 for the focus\n * ring, 1.15:1 between the states of a fill) logs one warning naming the theme, the tokens, the\n * stops and the ratio. The check is advisory: the ramp applies as given. Any other seed returns\n * the default ramp, with a development warning.\n *\n * Pure and server-safe; it returns a new object on each call, so compute it once (at module scope,\n * or memoised) rather than on every render.\n *\n * @example\n * const brand = createBrandTokens('#c43e00');\n * <WaveProvider tokens={brand}>…</WaveProvider>\n *\n * @example\n * <WaveProvider tokens={{ ...createBrandTokens('#c43e00'), fontFamily: 'Inter, sans-serif' }}>\n */\nexport function createBrandTokens(seed: string | BrandRamp): BrandTokens {\n if (typeof seed === 'object' && seed !== null) return rampFromStops(seed);\n const rgb = parseHex(seed);\n if (rgb) return rampFromSeed(rgb);\n // A long string is cut, so the console never holds a whole document passed by mistake.\n const shown =\n typeof seed === 'string'\n ? `\"${seed.length > 32 ? `${seed.slice(0, 32)}…` : seed}\"`\n : seed === null || seed === undefined\n ? String(seed)\n : `a ${typeof seed}`;\n warnOnce(\n 'createBrandTokens:seed',\n `createBrandTokens: the seed ${shown} is not a #rgb or #rrggbb colour, so the default brand ` +\n 'ramp is used.',\n );\n return toTokens((stop) => DEFAULT_BRAND_RAMP[stop]);\n}\n"],"mappings":"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"}
|
package/dist/lib/cn.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
let e=require("clsx");var t=(0,require("tailwind-merge").extendTailwindMerge)({extend:{classGroups:{duration:[{duration:[`wave-ultra-fast`,`wave-faster`,`wave-fast`,`wave-normal`,`wave-gentle`,`wave-slow`,`wave-slower`,`wave-ultra-slow`]}]},theme:{ease:[`wave-accelerate-max`,`wave-accelerate-mid`,`wave-accelerate-min`,`wave-decelerate-max`,`wave-decelerate-mid`,`wave-decelerate-min`,`wave-easy-ease-max`,`wave-easy-ease`,`wave-linear`],text:[`caption-2`,`caption-1`,`body-1`,`body-2`,`subtitle-2`,`subtitle-1`,`title-3`,`title-2`,`title-1`,`large-title`,`display`],shadow:[`2`,`4`,`8`,`16`,`28`,`64`],font:[`wave`],animate:[`wave-spin`,`wave-spin-slow`,`wave-pulse`,`wave-indeterminate`,`wave-indeterminate-rtl`]}}});function n(...n){return t((0,e.clsx)(n))}exports.cn=n,exports.twMerge=t;
|
|
1
|
+
let e=require("clsx");var t=(0,require("tailwind-merge").extendTailwindMerge)({extend:{classGroups:{duration:[{duration:[`wave-ultra-fast`,`wave-faster`,`wave-fast`,`wave-normal`,`wave-gentle`,`wave-slow`,`wave-slower`,`wave-ultra-slow`]}]},theme:{ease:[`wave-accelerate-max`,`wave-accelerate-mid`,`wave-accelerate-min`,`wave-decelerate-max`,`wave-decelerate-mid`,`wave-decelerate-min`,`wave-easy-ease-max`,`wave-easy-ease`,`wave-linear`],text:[`caption-2`,`caption-1`,`body-1`,`body-2`,`subtitle-2`,`subtitle-1`,`title-3`,`title-2`,`title-1`,`large-title`,`display`],shadow:[`2`,`4`,`8`,`16`,`28`,`64`],font:[`wave`,`wave-mono`,`wave-numeric`],animate:[`wave-spin`,`wave-spin-slow`,`wave-pulse`,`wave-indeterminate`,`wave-indeterminate-rtl`]}}});function n(...n){return t((0,e.clsx)(n))}exports.cn=n,exports.twMerge=t;
|
|
2
2
|
//# sourceMappingURL=cn.cjs.map
|
package/dist/lib/cn.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cn.cjs","names":["extendTailwindMerge","clsx","twMerge","cn","inputs"],"sources":["../../src/lib/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n/**\n * tailwind-merge configured with the Wave theme scales, so custom utilities are grouped\n * correctly: `text-body-1` is a font size (not a text colour), `shadow-4` is a shadow size (not a\n * shadow colour), `font-wave`
|
|
1
|
+
{"version":3,"file":"cn.cjs","names":["extendTailwindMerge","clsx","twMerge","cn","inputs"],"sources":["../../src/lib/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n/**\n * tailwind-merge configured with the Wave theme scales, so custom utilities are grouped\n * correctly: `text-body-1` is a font size (not a text colour), `shadow-4` is a shadow size (not a\n * shadow colour), `font-wave` and its monospace and numeric siblings are font families (never a\n * weight or a size), `animate-wave-*` are animations, and the motion\n * tokens `duration-wave-*` and `ease-wave-*` are transition durations and timing functions.\n */\nexport const twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n duration: [\n {\n duration: [\n 'wave-ultra-fast',\n 'wave-faster',\n 'wave-fast',\n 'wave-normal',\n 'wave-gentle',\n 'wave-slow',\n 'wave-slower',\n 'wave-ultra-slow',\n ],\n },\n ],\n },\n theme: {\n ease: [\n 'wave-accelerate-max',\n 'wave-accelerate-mid',\n 'wave-accelerate-min',\n 'wave-decelerate-max',\n 'wave-decelerate-mid',\n 'wave-decelerate-min',\n 'wave-easy-ease-max',\n 'wave-easy-ease',\n 'wave-linear',\n ],\n text: [\n 'caption-2',\n 'caption-1',\n 'body-1',\n 'body-2',\n 'subtitle-2',\n 'subtitle-1',\n 'title-3',\n 'title-2',\n 'title-1',\n 'large-title',\n 'display',\n ],\n shadow: ['2', '4', '8', '16', '28', '64'],\n font: ['wave', 'wave-mono', 'wave-numeric'],\n animate: [\n 'wave-spin',\n 'wave-spin-slow',\n 'wave-pulse',\n 'wave-indeterminate',\n 'wave-indeterminate-rtl',\n ],\n },\n },\n});\n\n/**\n * Joins class names (clsx) and resolves Tailwind conflicts so the **last** class wins — pass\n * internal classes first and the consumer's `className` last.\n *\n * A later class replaces only a conflicting class **of the same variant**. Variant and state\n * classes such as the gated `not-disabled:not-aria-disabled:hover:bg-…` or `data-[selected]:bg-…`\n * are kept next to a bare `hover:bg-…`/`bg-…` and win by specificity; override them with the same\n * prefix (`not-disabled:not-aria-disabled:hover:bg-error`), the same data variant, or the important\n * modifier (`hover:bg-error!`).\n *\n * @example\n * cn('text-body-1 text-foreground', className) // className=\"text-primary\" keeps text-body-1\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":"sBAUA,IAAaE,GAAA,0BAAUF,CAAAA,CAAAA,oBAAAA,CAAoB,CACzC,OAAQ,CACN,YAAa,CACX,SAAU,CACR,CACE,SAAU,CACR,kBACA,cACA,YACA,cACA,cACA,YACA,cACA,iBACF,CACF,CACF,CACF,EACA,MAAO,CACL,KAAM,CACJ,sBACA,sBACA,sBACA,sBACA,sBACA,sBACA,qBACA,iBACA,aACF,EACA,KAAM,CACJ,YACA,YACA,SACA,SACA,aACA,aACA,UACA,UACA,UACA,cACA,SACF,EACA,OAAQ,CAAC,IAAK,IAAK,IAAK,KAAM,KAAM,IAAI,EACxC,KAAM,CAAC,OAAQ,YAAa,cAAc,EAC1C,QAAS,CACP,YACA,iBACA,aACA,qBACA,wBACF,CACF,CACF,CACF,CAAC,EAeD,SAAgBG,EAAG,GAAGC,EAA8B,CAClD,OAAOF,GAAA,EAAQD,EAAA,KAAA,CAAKG,CAAM,CAAC,CAC7B"}
|
package/dist/lib/cn.mjs
CHANGED
package/dist/lib/cn.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cn.mjs","names":["twMerge","extendTailwindMerge","cn","inputs","clsx"],"sources":["../../src/lib/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n/**\n * tailwind-merge configured with the Wave theme scales, so custom utilities are grouped\n * correctly: `text-body-1` is a font size (not a text colour), `shadow-4` is a shadow size (not a\n * shadow colour), `font-wave`
|
|
1
|
+
{"version":3,"file":"cn.mjs","names":["twMerge","extendTailwindMerge","cn","inputs","clsx"],"sources":["../../src/lib/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n/**\n * tailwind-merge configured with the Wave theme scales, so custom utilities are grouped\n * correctly: `text-body-1` is a font size (not a text colour), `shadow-4` is a shadow size (not a\n * shadow colour), `font-wave` and its monospace and numeric siblings are font families (never a\n * weight or a size), `animate-wave-*` are animations, and the motion\n * tokens `duration-wave-*` and `ease-wave-*` are transition durations and timing functions.\n */\nexport const twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n duration: [\n {\n duration: [\n 'wave-ultra-fast',\n 'wave-faster',\n 'wave-fast',\n 'wave-normal',\n 'wave-gentle',\n 'wave-slow',\n 'wave-slower',\n 'wave-ultra-slow',\n ],\n },\n ],\n },\n theme: {\n ease: [\n 'wave-accelerate-max',\n 'wave-accelerate-mid',\n 'wave-accelerate-min',\n 'wave-decelerate-max',\n 'wave-decelerate-mid',\n 'wave-decelerate-min',\n 'wave-easy-ease-max',\n 'wave-easy-ease',\n 'wave-linear',\n ],\n text: [\n 'caption-2',\n 'caption-1',\n 'body-1',\n 'body-2',\n 'subtitle-2',\n 'subtitle-1',\n 'title-3',\n 'title-2',\n 'title-1',\n 'large-title',\n 'display',\n ],\n shadow: ['2', '4', '8', '16', '28', '64'],\n font: ['wave', 'wave-mono', 'wave-numeric'],\n animate: [\n 'wave-spin',\n 'wave-spin-slow',\n 'wave-pulse',\n 'wave-indeterminate',\n 'wave-indeterminate-rtl',\n ],\n },\n },\n});\n\n/**\n * Joins class names (clsx) and resolves Tailwind conflicts so the **last** class wins — pass\n * internal classes first and the consumer's `className` last.\n *\n * A later class replaces only a conflicting class **of the same variant**. Variant and state\n * classes such as the gated `not-disabled:not-aria-disabled:hover:bg-…` or `data-[selected]:bg-…`\n * are kept next to a bare `hover:bg-…`/`bg-…` and win by specificity; override them with the same\n * prefix (`not-disabled:not-aria-disabled:hover:bg-error`), the same data variant, or the important\n * modifier (`hover:bg-error!`).\n *\n * @example\n * cn('text-body-1 text-foreground', className) // className=\"text-primary\" keeps text-body-1\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";;;AAUA,IAAaA,IAAUC,EAAoB,EACzC,QAAQ;CACN,aAAa,EACX,UAAU,CACR,EACE,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,EACF,CACF,EACF;CACA,OAAO;EACL,MAAM;GACJ;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,MAAM;GACJ;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,QAAQ;GAAC;GAAK;GAAK;GAAK;GAAM;GAAM;EAAI;EACxC,MAAM;GAAC;GAAQ;GAAa;EAAc;EAC1C,SAAS;GACP;GACA;GACA;GACA;GACA;EACF;CACF;AACF,EACF,CAAC;AAeD,SAAgBC,EAAG,GAAGC,GAA8B;CAClD,OAAOH,EAAQI,EAAKD,CAAM,CAAC;AAC7B"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./dev.cjs");function t(e){return`--wave-${e.replace(/([A-Za-z])(\d)/g,`$1-$2`).replace(/[A-Z]/g,e=>`-${e}`).toLowerCase()}`}var n=/^[a-z][A-Za-z0-9]*$/,r=/[;{}]/;function i(e){let i=[];if(e==null)return{style:void 0,invalid:i};let a={},o=!0;for(let[s,c]of Object.entries(e))c!==void 0&&(n.test(s)?typeof c==`string`&&!r.test(c)||typeof c==`number`&&Number.isFinite(c)?(a[t(s)]=String(c),o=!1):i.push({key:s,reason:`value`}):i.push({key:s,reason:`name`}));return{style:o?void 0:a,invalid:i}}function a(t){let{style:n,invalid:r}=i(t);for(let{key:t,reason:n}of r)n===`name`?e.warnOnce(`tokens:name:${t}`,`getTokenStyle: \`${t}\` is not a token name, so it is skipped. Token names are the CSS variable in camelCase without its \`--wave-\` prefix (\`primaryForeground\` for \`--wave-primary-foreground\`).`):e.warnOnce(`tokens:value:${t}`,`getTokenStyle: the value of \`${t}\` is skipped: it must be a finite number or a string without \`;\`, \`{\` or \`}\`.`);return n}function o(e,t){if(t===null)return{};if(t===void 0)return e;let n=Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0));return{...e,...n}}exports.collectTokenStyle=i,exports.getTokenStyle=a,exports.mergeTokenOverrides=o,exports.tokenVariable=t;
|
|
2
|
+
//# sourceMappingURL=tokens.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.cjs","names":["require_dev","tokenVariable","name","capital","TOKEN_NAME","DECLARATION_BREAK","collectTokenStyle","invalid","overrides","style","empty","key","value","getTokenStyle","reason","mergeTokenOverrides","own","parent","defined"],"sources":["../../src/lib/tokens.ts"],"sourcesContent":["/**\n * The design tokens in JavaScript: their names, the overrides `WaveProvider` takes and the inline\n * style that applies them. Server-safe and light enough for the provider: it imports only types\n * and the development warnings, never the list of token names (`waveTokens.ts`).\n */\nimport type * as React from 'react';\nimport { warnOnce } from './dev';\nimport type { WAVE_TOKEN_NAMES } from './waveTokens';\n\n/**\n * The name of a design token: its CSS custom property without the `--wave-` prefix, in camelCase.\n * `--wave-primary-foreground` is `primaryForeground`, `--wave-brand-80` is `brand80` and\n * `--wave-palette-red-tint` is `paletteRedTint`.\n */\nexport type WaveTokenName = (typeof WAVE_TOKEN_NAMES)[number];\n\n/** The shape of `waveTokens`: every token name mapped to the CSS value that reads the token. */\nexport type WaveTokens = { readonly [K in WaveTokenName]: string };\n\n/**\n * Token overrides: CSS values by token name, as `WaveProvider tokens` and `getTokenStyle` take\n * them. A number is written as its string (`zOverlay: 2000`); a key whose value is `undefined`\n * sets nothing.\n */\nexport type WaveTokenOverrides = { [K in WaveTokenName]?: string | number };\n\n/**\n * The inline style that applies token overrides: a React style object whose `--wave-*` custom\n * properties set the tokens, so it can be merged with other style properties.\n */\nexport type TokenStyle = React.CSSProperties & { [K in `--wave-${string}`]?: string };\n\n/**\n * The CSS custom property of a token name at the type level: `TokenVariable<'brand80'>` is\n * `'--wave-brand-80'`, by the rule of {@link tokenVariable}. It spells out the literal values of\n * `waveTokens`. It walks the name one character at a time (tail-recursive, so long names stay\n * within the compiler's depth limit): `AfterLetter` says whether the previous character was a\n * letter, `Done` holds the converted text so far.\n */\nexport type TokenVariable<\n Name extends string,\n AfterLetter extends boolean = false,\n Done extends string = '',\n> = Name extends `${infer Char}${infer Rest}`\n ? Char extends '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'\n ? TokenVariable<Rest, false, `${Done}${AfterLetter extends true ? '-' : ''}${Char}`>\n : Char extends Lowercase<Char>\n ? TokenVariable<Rest, true, `${Done}${Char}`>\n : TokenVariable<Rest, true, `${Done}-${Lowercase<Char>}`>\n : `--wave-${Done}`;\n\n/**\n * The CSS custom property of a token name: a hyphen before each capital letter and before a digit\n * run that follows a letter, lowercased, with the `--wave-` prefix. `'paletteRedTint'` gives\n * `'--wave-palette-red-tint'` and `'brand80'` gives `'--wave-brand-80'`. The name is not checked\n * against the list of tokens.\n */\nexport function tokenVariable(name: string): string {\n return `--wave-${name\n .replace(/([A-Za-z])(\\d)/g, '$1-$2')\n .replace(/[A-Z]/g, (capital) => `-${capital}`)\n .toLowerCase()}`;\n}\n\n/** A camelCase identifier: the only key shape a token name can have. */\nconst TOKEN_NAME = /^[a-z][A-Za-z0-9]*$/;\n\n/**\n * The characters no token value may hold. React writes a custom property's value into the\n * server-rendered `style` attribute as text, where a semicolon would end the declaration and let\n * the rest of the value declare a property of its own (and a brace could close the rule around\n * it); in the client the CSSOM refuses a value with a semicolon, so the two renders would also\n * differ.\n */\nconst DECLARATION_BREAK = /[;{}]/;\n\n/**\n * The custom properties of `overrides`, and the entries it skipped. Pure: it never warns, so the\n * provider can call it during render; {@link getTokenStyle} reports the skipped entries.\n *\n * `undefined` values are skipped first (they set nothing); a key that is not a camelCase\n * identifier is skipped with the reason `'name'`, and a value that is neither a finite number nor a\n * string without `;`, `{` or `}` with the reason `'value'`. Numbers are written as strings, and the\n * style keeps the order of the input. `style` is `undefined` when nothing is left.\n */\nexport function collectTokenStyle(overrides: WaveTokenOverrides | null | undefined): {\n style: TokenStyle | undefined;\n invalid: readonly { key: string; reason: 'name' | 'value' }[];\n} {\n const invalid: { key: string; reason: 'name' | 'value' }[] = [];\n if (overrides == null) return { style: undefined, invalid };\n const style: Record<string, string> = {};\n let empty = true;\n for (const [key, value] of Object.entries(overrides as Record<string, unknown>)) {\n if (value === undefined) continue;\n if (!TOKEN_NAME.test(key)) {\n invalid.push({ key, reason: 'name' });\n } else if (\n (typeof value === 'string' && !DECLARATION_BREAK.test(value)) ||\n (typeof value === 'number' && Number.isFinite(value))\n ) {\n style[tokenVariable(key)] = String(value);\n empty = false;\n } else {\n invalid.push({ key, reason: 'value' });\n }\n }\n return { style: empty ? undefined : (style as TokenStyle), invalid };\n}\n\n/**\n * The inline style that applies token overrides: one `--wave-*` custom property per entry, the\n * object `WaveProvider` puts on its root and its portals. Use it where no provider renders, such\n * as a Server Component's document element. Server-safe.\n *\n * Returns `undefined` for `null`, `undefined` or a map with nothing to set. An `undefined` value is\n * skipped, a number is written as its string, and the properties keep the order of the input. A\n * key that is not a camelCase identifier, or a value that is neither a finite number nor a string\n * without `;`, `{` or `}` (which could add a declaration of its own to a server-rendered `style`\n * attribute), is skipped with a development warning (once per key). Names are not checked against\n * the list of tokens: TypeScript refuses a misspelled one, and in JavaScript it sets a property\n * nothing reads.\n *\n * @example\n * // app/layout.tsx (a Server Component)\n * <html style={getTokenStyle({ brand80: '#c43e00' })}>\n *\n * @example\n * <div style={{ ...getTokenStyle(overrides), padding: 16 }} />\n */\nexport function getTokenStyle(\n overrides: WaveTokenOverrides | null | undefined,\n): TokenStyle | undefined {\n const { style, invalid } = collectTokenStyle(overrides);\n for (const { key, reason } of invalid) {\n if (reason === 'name') {\n warnOnce(\n `tokens:name:${key}`,\n `getTokenStyle: \\`${key}\\` is not a token name, so it is skipped. Token names are the CSS ` +\n 'variable in camelCase without its `--wave-` prefix (`primaryForeground` for ' +\n '`--wave-primary-foreground`).',\n );\n } else {\n warnOnce(\n `tokens:value:${key}`,\n `getTokenStyle: the value of \\`${key}\\` is skipped: it must be a finite number or a string ` +\n 'without `;`, `{` or `}`.',\n );\n }\n }\n return style;\n}\n\n/**\n * The overrides of a nested provider: `own` merged key by key over `parent`. `undefined` inherits\n * `parent` as it is, `null` clears everything inherited, and a key whose own value is `undefined`\n * keeps the parent's value.\n */\nexport function mergeTokenOverrides(\n parent: WaveTokenOverrides,\n own: WaveTokenOverrides | null | undefined,\n): WaveTokenOverrides {\n if (own === null) return {};\n if (own === undefined) return parent;\n // Spread, never assignment, so a `__proto__` key is an own entry like any other.\n const defined = Object.fromEntries(\n Object.entries(own).filter(([, value]) => value !== undefined),\n );\n return { ...parent, ...defined };\n}\n"],"mappings":"6BAyDA,SAAgBC,EAAc,EAAsB,CAClD,MAAO,UAAUC,EACd,QAAQ,kBAAmB,OAAO,CAAC,CACnC,QAAQ,SAAW,GAAY,IAAIC,GAAS,CAAC,CAC7C,YAAY,GACjB,CAGA,IAAMC,EAAa,sBASbC,EAAoB,QAW1B,SAAgBC,EAAkB,EAGhC,CACA,IAAMC,EAAuD,CAAC,EAC9D,GAAIC,GAAa,KAAM,MAAO,CAAE,MAAO,IAAA,GAAW,SAAQ,EAC1D,IAAMC,EAAgC,CAAC,EACnCC,EAAQ,GACZ,IAAK,GAAM,CAACC,EAAKC,KAAU,OAAO,QAAQJ,CAAoC,EACxEI,IAAU,IAAA,KACTR,EAAW,KAAKO,CAAG,EAGrB,OAAOC,GAAU,UAAY,CAACP,EAAkB,KAAKO,CAAK,GAC1D,OAAOA,GAAU,UAAY,OAAO,SAASA,CAAK,GAEnD,EAAMX,EAAcU,CAAG,GAAK,OAAOC,CAAK,EACxC,EAAQ,IAERL,EAAQ,KAAK,CAAE,MAAK,OAAQ,OAAQ,CAAC,EARrCA,EAAQ,KAAK,CAAE,MAAK,OAAQ,MAAO,CAAC,GAWxC,MAAO,CAAE,MAAOG,EAAQ,IAAA,GAAaD,EAAsB,SAAQ,CACrE,CAsBA,SAAgBI,EACd,EACwB,CACxB,GAAM,CAAE,QAAO,WAAYP,EAAkBE,CAAS,EACtD,IAAK,GAAM,CAAE,MAAK,YAAYD,EACxBO,IAAW,OACbd,EAAA,SACE,eAAeW,IACf,oBAAoBA,EAAI,kLAG1B,EAEAX,EAAA,SACE,gBAAgBW,IAChB,iCAAiCA,EAAI,qFAEvC,EAGJ,OAAOF,CACT,CAOA,SAAgBM,EACd,EACA,EACoB,CACpB,GAAIC,IAAQ,KAAM,MAAO,CAAC,EAC1B,GAAIA,IAAQ,IAAA,GAAW,OAAOC,EAE9B,IAAMC,EAAU,OAAO,YACrB,OAAO,QAAQF,CAAG,CAAC,CAAC,QAAQ,EAAGJ,KAAWA,IAAU,IAAA,EAAS,CAC/D,EACA,MAAO,CAAE,GAAGK,EAAQ,GAAGC,CAAQ,CACjC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { warnOnce as e } from "./dev.mjs";
|
|
2
|
+
//#region src/lib/tokens.ts
|
|
3
|
+
function t(e) {
|
|
4
|
+
return `--wave-${e.replace(/([A-Za-z])(\d)/g, "$1-$2").replace(/[A-Z]/g, (e) => `-${e}`).toLowerCase()}`;
|
|
5
|
+
}
|
|
6
|
+
var n = /^[a-z][A-Za-z0-9]*$/, r = /[;{}]/;
|
|
7
|
+
function i(e) {
|
|
8
|
+
let i = [];
|
|
9
|
+
if (e == null) return {
|
|
10
|
+
style: void 0,
|
|
11
|
+
invalid: i
|
|
12
|
+
};
|
|
13
|
+
let a = {}, o = !0;
|
|
14
|
+
for (let [s, c] of Object.entries(e)) c !== void 0 && (n.test(s) ? typeof c == "string" && !r.test(c) || typeof c == "number" && Number.isFinite(c) ? (a[t(s)] = String(c), o = !1) : i.push({
|
|
15
|
+
key: s,
|
|
16
|
+
reason: "value"
|
|
17
|
+
}) : i.push({
|
|
18
|
+
key: s,
|
|
19
|
+
reason: "name"
|
|
20
|
+
}));
|
|
21
|
+
return {
|
|
22
|
+
style: o ? void 0 : a,
|
|
23
|
+
invalid: i
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function a(t) {
|
|
27
|
+
let { style: n, invalid: r } = i(t);
|
|
28
|
+
for (let { key: t, reason: n } of r) n === "name" ? e(`tokens:name:${t}`, `getTokenStyle: \`${t}\` is not a token name, so it is skipped. Token names are the CSS variable in camelCase without its \`--wave-\` prefix (\`primaryForeground\` for \`--wave-primary-foreground\`).`) : e(`tokens:value:${t}`, `getTokenStyle: the value of \`${t}\` is skipped: it must be a finite number or a string without \`;\`, \`{\` or \`}\`.`);
|
|
29
|
+
return n;
|
|
30
|
+
}
|
|
31
|
+
function o(e, t) {
|
|
32
|
+
if (t === null) return {};
|
|
33
|
+
if (t === void 0) return e;
|
|
34
|
+
let n = Object.fromEntries(Object.entries(t).filter(([, e]) => e !== void 0));
|
|
35
|
+
return {
|
|
36
|
+
...e,
|
|
37
|
+
...n
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { i as collectTokenStyle, a as getTokenStyle, o as mergeTokenOverrides, t as tokenVariable };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=tokens.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.mjs","names":["tokenVariable","name","capital","TOKEN_NAME","DECLARATION_BREAK","collectTokenStyle","invalid","overrides","style","empty","key","value","getTokenStyle","reason","warnOnce","mergeTokenOverrides","own","parent","defined"],"sources":["../../src/lib/tokens.ts"],"sourcesContent":["/**\n * The design tokens in JavaScript: their names, the overrides `WaveProvider` takes and the inline\n * style that applies them. Server-safe and light enough for the provider: it imports only types\n * and the development warnings, never the list of token names (`waveTokens.ts`).\n */\nimport type * as React from 'react';\nimport { warnOnce } from './dev';\nimport type { WAVE_TOKEN_NAMES } from './waveTokens';\n\n/**\n * The name of a design token: its CSS custom property without the `--wave-` prefix, in camelCase.\n * `--wave-primary-foreground` is `primaryForeground`, `--wave-brand-80` is `brand80` and\n * `--wave-palette-red-tint` is `paletteRedTint`.\n */\nexport type WaveTokenName = (typeof WAVE_TOKEN_NAMES)[number];\n\n/** The shape of `waveTokens`: every token name mapped to the CSS value that reads the token. */\nexport type WaveTokens = { readonly [K in WaveTokenName]: string };\n\n/**\n * Token overrides: CSS values by token name, as `WaveProvider tokens` and `getTokenStyle` take\n * them. A number is written as its string (`zOverlay: 2000`); a key whose value is `undefined`\n * sets nothing.\n */\nexport type WaveTokenOverrides = { [K in WaveTokenName]?: string | number };\n\n/**\n * The inline style that applies token overrides: a React style object whose `--wave-*` custom\n * properties set the tokens, so it can be merged with other style properties.\n */\nexport type TokenStyle = React.CSSProperties & { [K in `--wave-${string}`]?: string };\n\n/**\n * The CSS custom property of a token name at the type level: `TokenVariable<'brand80'>` is\n * `'--wave-brand-80'`, by the rule of {@link tokenVariable}. It spells out the literal values of\n * `waveTokens`. It walks the name one character at a time (tail-recursive, so long names stay\n * within the compiler's depth limit): `AfterLetter` says whether the previous character was a\n * letter, `Done` holds the converted text so far.\n */\nexport type TokenVariable<\n Name extends string,\n AfterLetter extends boolean = false,\n Done extends string = '',\n> = Name extends `${infer Char}${infer Rest}`\n ? Char extends '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'\n ? TokenVariable<Rest, false, `${Done}${AfterLetter extends true ? '-' : ''}${Char}`>\n : Char extends Lowercase<Char>\n ? TokenVariable<Rest, true, `${Done}${Char}`>\n : TokenVariable<Rest, true, `${Done}-${Lowercase<Char>}`>\n : `--wave-${Done}`;\n\n/**\n * The CSS custom property of a token name: a hyphen before each capital letter and before a digit\n * run that follows a letter, lowercased, with the `--wave-` prefix. `'paletteRedTint'` gives\n * `'--wave-palette-red-tint'` and `'brand80'` gives `'--wave-brand-80'`. The name is not checked\n * against the list of tokens.\n */\nexport function tokenVariable(name: string): string {\n return `--wave-${name\n .replace(/([A-Za-z])(\\d)/g, '$1-$2')\n .replace(/[A-Z]/g, (capital) => `-${capital}`)\n .toLowerCase()}`;\n}\n\n/** A camelCase identifier: the only key shape a token name can have. */\nconst TOKEN_NAME = /^[a-z][A-Za-z0-9]*$/;\n\n/**\n * The characters no token value may hold. React writes a custom property's value into the\n * server-rendered `style` attribute as text, where a semicolon would end the declaration and let\n * the rest of the value declare a property of its own (and a brace could close the rule around\n * it); in the client the CSSOM refuses a value with a semicolon, so the two renders would also\n * differ.\n */\nconst DECLARATION_BREAK = /[;{}]/;\n\n/**\n * The custom properties of `overrides`, and the entries it skipped. Pure: it never warns, so the\n * provider can call it during render; {@link getTokenStyle} reports the skipped entries.\n *\n * `undefined` values are skipped first (they set nothing); a key that is not a camelCase\n * identifier is skipped with the reason `'name'`, and a value that is neither a finite number nor a\n * string without `;`, `{` or `}` with the reason `'value'`. Numbers are written as strings, and the\n * style keeps the order of the input. `style` is `undefined` when nothing is left.\n */\nexport function collectTokenStyle(overrides: WaveTokenOverrides | null | undefined): {\n style: TokenStyle | undefined;\n invalid: readonly { key: string; reason: 'name' | 'value' }[];\n} {\n const invalid: { key: string; reason: 'name' | 'value' }[] = [];\n if (overrides == null) return { style: undefined, invalid };\n const style: Record<string, string> = {};\n let empty = true;\n for (const [key, value] of Object.entries(overrides as Record<string, unknown>)) {\n if (value === undefined) continue;\n if (!TOKEN_NAME.test(key)) {\n invalid.push({ key, reason: 'name' });\n } else if (\n (typeof value === 'string' && !DECLARATION_BREAK.test(value)) ||\n (typeof value === 'number' && Number.isFinite(value))\n ) {\n style[tokenVariable(key)] = String(value);\n empty = false;\n } else {\n invalid.push({ key, reason: 'value' });\n }\n }\n return { style: empty ? undefined : (style as TokenStyle), invalid };\n}\n\n/**\n * The inline style that applies token overrides: one `--wave-*` custom property per entry, the\n * object `WaveProvider` puts on its root and its portals. Use it where no provider renders, such\n * as a Server Component's document element. Server-safe.\n *\n * Returns `undefined` for `null`, `undefined` or a map with nothing to set. An `undefined` value is\n * skipped, a number is written as its string, and the properties keep the order of the input. A\n * key that is not a camelCase identifier, or a value that is neither a finite number nor a string\n * without `;`, `{` or `}` (which could add a declaration of its own to a server-rendered `style`\n * attribute), is skipped with a development warning (once per key). Names are not checked against\n * the list of tokens: TypeScript refuses a misspelled one, and in JavaScript it sets a property\n * nothing reads.\n *\n * @example\n * // app/layout.tsx (a Server Component)\n * <html style={getTokenStyle({ brand80: '#c43e00' })}>\n *\n * @example\n * <div style={{ ...getTokenStyle(overrides), padding: 16 }} />\n */\nexport function getTokenStyle(\n overrides: WaveTokenOverrides | null | undefined,\n): TokenStyle | undefined {\n const { style, invalid } = collectTokenStyle(overrides);\n for (const { key, reason } of invalid) {\n if (reason === 'name') {\n warnOnce(\n `tokens:name:${key}`,\n `getTokenStyle: \\`${key}\\` is not a token name, so it is skipped. Token names are the CSS ` +\n 'variable in camelCase without its `--wave-` prefix (`primaryForeground` for ' +\n '`--wave-primary-foreground`).',\n );\n } else {\n warnOnce(\n `tokens:value:${key}`,\n `getTokenStyle: the value of \\`${key}\\` is skipped: it must be a finite number or a string ` +\n 'without `;`, `{` or `}`.',\n );\n }\n }\n return style;\n}\n\n/**\n * The overrides of a nested provider: `own` merged key by key over `parent`. `undefined` inherits\n * `parent` as it is, `null` clears everything inherited, and a key whose own value is `undefined`\n * keeps the parent's value.\n */\nexport function mergeTokenOverrides(\n parent: WaveTokenOverrides,\n own: WaveTokenOverrides | null | undefined,\n): WaveTokenOverrides {\n if (own === null) return {};\n if (own === undefined) return parent;\n // Spread, never assignment, so a `__proto__` key is an own entry like any other.\n const defined = Object.fromEntries(\n Object.entries(own).filter(([, value]) => value !== undefined),\n );\n return { ...parent, ...defined };\n}\n"],"mappings":";;AAyDA,SAAgBA,EAAc,GAAsB;CAClD,OAAO,UAAUC,EACd,QAAQ,mBAAmB,OAAO,CAAC,CACnC,QAAQ,WAAW,MAAY,IAAIC,GAAS,CAAC,CAC7C,YAAY;AACjB;AAGA,IAAMC,IAAa,uBASbC,IAAoB;AAW1B,SAAgBC,EAAkB,GAGhC;CACA,IAAMC,IAAuD,CAAC;CAC9D,IAAIC,KAAa,MAAM,OAAO;EAAE,OAAO,KAAA;EAAW;CAAQ;CAC1D,IAAMC,IAAgC,CAAC,GACnCC,IAAQ;CACZ,KAAK,IAAM,CAACC,GAAKC,MAAU,OAAO,QAAQJ,CAAoC,GAC5E,AAAII,MAAU,KAAA,MACTR,EAAW,KAAKO,CAAG,IAGrB,OAAOC,KAAU,YAAY,CAACP,EAAkB,KAAKO,CAAK,KAC1D,OAAOA,KAAU,YAAY,OAAO,SAASA,CAAK,KAEnD,EAAMX,EAAcU,CAAG,KAAK,OAAOC,CAAK,GACxC,IAAQ,MAERL,EAAQ,KAAK;EAAE;EAAK,QAAQ;CAAQ,CAAC,IARrCA,EAAQ,KAAK;EAAE;EAAK,QAAQ;CAAO,CAAC;CAWxC,OAAO;EAAE,OAAOG,IAAQ,KAAA,IAAaD;EAAsB;CAAQ;AACrE;AAsBA,SAAgBI,EACd,GACwB;CACxB,IAAM,EAAE,UAAO,eAAYP,EAAkBE,CAAS;CACtD,KAAK,IAAM,EAAE,QAAK,eAAYD,GAC5B,AAAIO,MAAW,SACbC,EACE,eAAeJ,KACf,oBAAoBA,EAAI,kLAG1B,IAEAI,EACE,gBAAgBJ,KAChB,iCAAiCA,EAAI,qFAEvC;CAGJ,OAAOF;AACT;AAOA,SAAgBO,EACd,GACA,GACoB;CACpB,IAAIC,MAAQ,MAAM,OAAO,CAAC;CAC1B,IAAIA,MAAQ,KAAA,GAAW,OAAOC;CAE9B,IAAMC,IAAU,OAAO,YACrB,OAAO,QAAQF,CAAG,CAAC,CAAC,QAAQ,GAAGL,OAAWA,MAAU,KAAA,CAAS,CAC/D;CACA,OAAO;EAAE,GAAGM;EAAQ,GAAGC;CAAQ;AACjC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./tokens.cjs");var t=`fontFamily.fontFamilyMonospace.fontFamilyNumeric.zOverlay.zToast.zTooltip.durationUltraFast.durationFaster.durationFast.durationNormal.durationGentle.durationSlow.durationSlower.durationUltraSlow.curveAccelerateMax.curveAccelerateMid.curveAccelerateMin.curveDecelerateMax.curveDecelerateMid.curveDecelerateMin.curveEasyEaseMax.curveEasyEase.curveLinear.brand10.brand20.brand30.brand40.brand50.brand60.brand70.brand80.brand90.brand100.brand110.brand120.brand130.brand140.brand150.brand160.grey2.grey4.grey6.grey8.grey10.grey12.grey14.grey16.grey20.grey24.grey26.grey30.grey34.grey38.grey40.grey44.grey50.grey60.grey68.grey74.grey78.grey82.grey86.grey88.grey90.grey92.grey94.grey96.grey98.background.foreground.card.secondary.muted.mutedForeground.mutedHover.mutedPressed.primary.primaryForeground.primaryHover.primaryPressed.destructive.destructiveForeground.error.errorForeground.subtle.subtleHover.subtlePressed.subtleSelected.selected.selectedForeground.selectedHover.selectedPressed.border.stroke.strokeHover.strokeAccessible.input.inputFilledDarker.inputFilledStroke.ring.success.successForeground.successTint.successTintForeground.warning.warningForeground.warningTint.warningTintForeground.errorTint.errorTintForeground.severe.severeForeground.severeTint.severeTintForeground.info.infoForeground.infoTint.infoTintForeground.inverted.invertedForeground.invertedBorder.track.skeleton.rating.presenceAvailable.presenceBusy.presenceAway.presenceOffline.presenceOof.presenceGlyph.backdrop.paletteRed.paletteRedForeground.paletteRedTint.paletteRedTintForeground.paletteRedBorder.palettePumpkin.palettePumpkinForeground.palettePumpkinTint.palettePumpkinTintForeground.palettePumpkinBorder.paletteGold.paletteGoldForeground.paletteGoldTint.paletteGoldTintForeground.paletteGoldBorder.paletteForest.paletteForestForeground.paletteForestTint.paletteForestTintForeground.paletteForestBorder.paletteTeal.paletteTealForeground.paletteTealTint.paletteTealTintForeground.paletteTealBorder.paletteBlue.paletteBlueForeground.paletteBlueTint.paletteBlueTintForeground.paletteBlueBorder.paletteNavy.paletteNavyForeground.paletteNavyTint.paletteNavyTintForeground.paletteNavyBorder.paletteLavender.paletteLavenderForeground.paletteLavenderTint.paletteLavenderTintForeground.paletteLavenderBorder.palettePurple.palettePurpleForeground.palettePurpleTint.palettePurpleTintForeground.palettePurpleBorder.paletteMagenta.paletteMagentaForeground.paletteMagentaTint.paletteMagentaTintForeground.paletteMagentaBorder.paletteBrown.paletteBrownForeground.paletteBrownTint.paletteBrownTintForeground.paletteBrownBorder.paletteSteel.paletteSteelForeground.paletteSteelTint.paletteSteelTintForeground.paletteSteelBorder.shadow2.shadow4.shadow8.shadow16.shadow28.shadow64.cardForeground.secondaryForeground.accent.accentForeground.inputFilledLighter`.split(`.`);function n(){return Object.freeze(Object.fromEntries(t.map(t=>[t,`var(${e.tokenVariable(t)})`])))}var r=n(),i=Object.freeze([`paletteBlue`,`palettePurple`,`paletteBrown`,`paletteTeal`,`paletteRed`,`paletteNavy`,`palettePumpkin`,`paletteSteel`,`paletteGold`,`paletteLavender`,`paletteForest`,`paletteMagenta`]);exports.WAVE_TOKEN_NAMES=t,exports.chartPalette=i,exports.waveTokens=r;
|
|
2
|
+
//# sourceMappingURL=waveTokens.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waveTokens.cjs","names":["tokenVariable","require_tokens","WAVE_TOKEN_NAMES","createWaveTokens","name","waveTokens","chartPalette"],"sources":["../../src/lib/waveTokens.ts"],"sourcesContent":["/**\n * The typed token object and the chart palette. Server-safe. No component imports this module:\n * the provider converts token names with a rule, so the list of names reaches only the bundles\n * that use `waveTokens` or `chartPalette`.\n */\nimport { tokenVariable } from './tokens';\nimport type { TokenVariable, WaveTokenName } from './tokens';\n\n/**\n * The name of every `--wave-*` variable of `tokens.css`, in camelCase, in the file's groups and\n * order. A test parses `tokens.css` and fails when a variable is missing here or a name has none.\n */\nexport const WAVE_TOKEN_NAMES = [\n // Theme-independent constants: font families\n 'fontFamily',\n 'fontFamilyMonospace',\n 'fontFamilyNumeric',\n // z-index layers\n 'zOverlay',\n 'zToast',\n 'zTooltip',\n // Motion: durations and curves (Fluent's motion tokens)\n 'durationUltraFast',\n 'durationFaster',\n 'durationFast',\n 'durationNormal',\n 'durationGentle',\n 'durationSlow',\n 'durationSlower',\n 'durationUltraSlow',\n 'curveAccelerateMax',\n 'curveAccelerateMid',\n 'curveAccelerateMin',\n 'curveDecelerateMax',\n 'curveDecelerateMid',\n 'curveDecelerateMin',\n 'curveEasyEaseMax',\n 'curveEasyEase',\n 'curveLinear',\n // Brand ramp\n 'brand10',\n 'brand20',\n 'brand30',\n 'brand40',\n 'brand50',\n 'brand60',\n 'brand70',\n 'brand80',\n 'brand90',\n 'brand100',\n 'brand110',\n 'brand120',\n 'brand130',\n 'brand140',\n 'brand150',\n 'brand160',\n // Neutral grey ramp\n 'grey2',\n 'grey4',\n 'grey6',\n 'grey8',\n 'grey10',\n 'grey12',\n 'grey14',\n 'grey16',\n 'grey20',\n 'grey24',\n 'grey26',\n 'grey30',\n 'grey34',\n 'grey38',\n 'grey40',\n 'grey44',\n 'grey50',\n 'grey60',\n 'grey68',\n 'grey74',\n 'grey78',\n 'grey82',\n 'grey86',\n 'grey88',\n 'grey90',\n 'grey92',\n 'grey94',\n 'grey96',\n 'grey98',\n // Every theme group (light, dark, high contrast) declares the rest. Surfaces and text\n 'background',\n 'foreground',\n 'card',\n 'secondary',\n 'muted',\n 'mutedForeground',\n 'mutedHover',\n 'mutedPressed',\n // Primary (brand)\n 'primary',\n 'primaryForeground',\n 'primaryHover',\n 'primaryPressed',\n // Destructive / error\n 'destructive',\n 'destructiveForeground',\n 'error',\n 'errorForeground',\n // Subtle (transparent) controls and selection\n 'subtle',\n 'subtleHover',\n 'subtlePressed',\n 'subtleSelected',\n 'selected',\n 'selectedForeground',\n 'selectedHover',\n 'selectedPressed',\n // Strokes\n 'border',\n 'stroke',\n 'strokeHover',\n 'strokeAccessible',\n 'input',\n 'inputFilledDarker',\n 'inputFilledStroke',\n 'ring',\n // Status\n 'success',\n 'successForeground',\n 'successTint',\n 'successTintForeground',\n 'warning',\n 'warningForeground',\n 'warningTint',\n 'warningTintForeground',\n 'errorTint',\n 'errorTintForeground',\n 'severe',\n 'severeForeground',\n 'severeTint',\n 'severeTintForeground',\n 'info',\n 'infoForeground',\n 'infoTint',\n 'infoTintForeground',\n // Inverted surfaces (tooltips)\n 'inverted',\n 'invertedForeground',\n 'invertedBorder',\n // Tracks, placeholders, rating, presence, backdrop (the file declares the backdrop after the\n // palette)\n 'track',\n 'skeleton',\n 'rating',\n 'presenceAvailable',\n 'presenceBusy',\n 'presenceAway',\n 'presenceOffline',\n 'presenceOof',\n 'presenceGlyph',\n 'backdrop',\n // Persona palette: per hue the fill, its text, the tint, the tint's text and the border\n 'paletteRed',\n 'paletteRedForeground',\n 'paletteRedTint',\n 'paletteRedTintForeground',\n 'paletteRedBorder',\n 'palettePumpkin',\n 'palettePumpkinForeground',\n 'palettePumpkinTint',\n 'palettePumpkinTintForeground',\n 'palettePumpkinBorder',\n 'paletteGold',\n 'paletteGoldForeground',\n 'paletteGoldTint',\n 'paletteGoldTintForeground',\n 'paletteGoldBorder',\n 'paletteForest',\n 'paletteForestForeground',\n 'paletteForestTint',\n 'paletteForestTintForeground',\n 'paletteForestBorder',\n 'paletteTeal',\n 'paletteTealForeground',\n 'paletteTealTint',\n 'paletteTealTintForeground',\n 'paletteTealBorder',\n 'paletteBlue',\n 'paletteBlueForeground',\n 'paletteBlueTint',\n 'paletteBlueTintForeground',\n 'paletteBlueBorder',\n 'paletteNavy',\n 'paletteNavyForeground',\n 'paletteNavyTint',\n 'paletteNavyTintForeground',\n 'paletteNavyBorder',\n 'paletteLavender',\n 'paletteLavenderForeground',\n 'paletteLavenderTint',\n 'paletteLavenderTintForeground',\n 'paletteLavenderBorder',\n 'palettePurple',\n 'palettePurpleForeground',\n 'palettePurpleTint',\n 'palettePurpleTintForeground',\n 'palettePurpleBorder',\n 'paletteMagenta',\n 'paletteMagentaForeground',\n 'paletteMagentaTint',\n 'paletteMagentaTintForeground',\n 'paletteMagentaBorder',\n 'paletteBrown',\n 'paletteBrownForeground',\n 'paletteBrownTint',\n 'paletteBrownTintForeground',\n 'paletteBrownBorder',\n 'paletteSteel',\n 'paletteSteelForeground',\n 'paletteSteelTint',\n 'paletteSteelTintForeground',\n 'paletteSteelBorder',\n // Elevation\n 'shadow2',\n 'shadow4',\n 'shadow8',\n 'shadow16',\n 'shadow28',\n 'shadow64',\n // Derived (re-declared per theme so nested themes re-resolve them)\n 'cardForeground',\n 'secondaryForeground',\n 'accent',\n 'accentForeground',\n 'inputFilledLighter',\n] as const;\n\n// Object.fromEntries types its result as a record of strings; the names give it its keys.\nfunction createWaveTokens() {\n return Object.freeze(\n Object.fromEntries(WAVE_TOKEN_NAMES.map((name) => [name, `var(${tokenVariable(name)})`])),\n ) as typeof waveTokens;\n}\n\n/**\n * Every design token as the CSS value that reads it: `waveTokens.primary` is\n * `'var(--wave-primary)'`, typed as that literal. Use it where a style is written in JavaScript\n * (an inline style, a CSS-in-JS rule, the colours of an SVG chart), so the value follows the theme\n * and the provider's token overrides. The counterpart of Fluent's `tokens` object\n * (`tokens.colorBrandBackground`), with Wave's names: the CSS variable in camelCase without its\n * `--wave-` prefix. A canvas library cannot read a CSS variable: resolve the value with\n * `getComputedStyle` on an element inside the provider, and again when the theme changes.\n * Frozen and server-safe; no component imports it.\n *\n * @example\n * <span style={{ color: waveTokens.primary, boxShadow: waveTokens.shadow8 }} />\n */\nexport const waveTokens: { readonly [K in WaveTokenName]: `var(${TokenVariable<K>})` } =\n /* @__PURE__ */ createWaveTokens();\n\n/**\n * The 12 palette fills as token names, in the order a categorical chart gives them to its series.\n * The order keeps neighbouring series as far apart as the palette allows, for colour vision and\n * for hue: in the light and dark themes, every two neighbours (the first and second, the second\n * and third, up to the eleventh and twelfth) differ by at least 6.3 (OKLab ΔE ×100) under\n * simulated protanopia, deuteranopia and tritanopia and by at least 15.7 for full colour vision,\n * and their hues are at least 49° apart. The first six are the six fills that stay furthest apart\n * as a set, yet no six fills of the palette keep every pair apart for colour-vision deficiencies:\n * two series that are not neighbours can differ by only about 3.2 among the first six, and by\n * less further on. So colour never identifies a series on its own: every chart needs a second\n * encoding (a pattern, a marker shape or a direct label), whatever its number of series, and in\n * high contrast every palette fill is white. Read each colour through `waveTokens`\n * (`waveTokens[chartPalette[index]]`), so the series follow the theme. Frozen and server-safe.\n *\n * @example\n * const color = waveTokens[chartPalette[index % chartPalette.length]];\n */\nexport const chartPalette: readonly WaveTokenName[] = /* @__PURE__ */ Object.freeze([\n 'paletteBlue',\n 'palettePurple',\n 'paletteBrown',\n 'paletteTeal',\n 'paletteRed',\n 'paletteNavy',\n 'palettePumpkin',\n 'paletteSteel',\n 'paletteGold',\n 'paletteLavender',\n 'paletteForest',\n 'paletteMagenta',\n]);\n"],"mappings":"gCAYA,IAAaE,EAAmB,ixFA4NhC,EAGA,SAASC,GAAmB,CAC1B,OAAO,OAAO,OACZ,OAAO,YAAYD,EAAiB,IAAK,GAAS,CAACE,EAAM,OAAOJ,EAAAA,cAAcI,CAAI,EAAE,EAAE,CAAC,CAAC,CAC1F,CACF,CAeA,IAAaC,EACKF,EAAiB,EAmBtBG,EAAyD,OAAO,OAAO,CAClF,cACA,gBACA,eACA,cACA,aACA,cACA,iBACA,eACA,cACA,kBACA,gBACA,gBACF,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { tokenVariable as e } from "./tokens.mjs";
|
|
2
|
+
//#region src/lib/waveTokens.ts
|
|
3
|
+
var t = /* @__PURE__ */ "fontFamily.fontFamilyMonospace.fontFamilyNumeric.zOverlay.zToast.zTooltip.durationUltraFast.durationFaster.durationFast.durationNormal.durationGentle.durationSlow.durationSlower.durationUltraSlow.curveAccelerateMax.curveAccelerateMid.curveAccelerateMin.curveDecelerateMax.curveDecelerateMid.curveDecelerateMin.curveEasyEaseMax.curveEasyEase.curveLinear.brand10.brand20.brand30.brand40.brand50.brand60.brand70.brand80.brand90.brand100.brand110.brand120.brand130.brand140.brand150.brand160.grey2.grey4.grey6.grey8.grey10.grey12.grey14.grey16.grey20.grey24.grey26.grey30.grey34.grey38.grey40.grey44.grey50.grey60.grey68.grey74.grey78.grey82.grey86.grey88.grey90.grey92.grey94.grey96.grey98.background.foreground.card.secondary.muted.mutedForeground.mutedHover.mutedPressed.primary.primaryForeground.primaryHover.primaryPressed.destructive.destructiveForeground.error.errorForeground.subtle.subtleHover.subtlePressed.subtleSelected.selected.selectedForeground.selectedHover.selectedPressed.border.stroke.strokeHover.strokeAccessible.input.inputFilledDarker.inputFilledStroke.ring.success.successForeground.successTint.successTintForeground.warning.warningForeground.warningTint.warningTintForeground.errorTint.errorTintForeground.severe.severeForeground.severeTint.severeTintForeground.info.infoForeground.infoTint.infoTintForeground.inverted.invertedForeground.invertedBorder.track.skeleton.rating.presenceAvailable.presenceBusy.presenceAway.presenceOffline.presenceOof.presenceGlyph.backdrop.paletteRed.paletteRedForeground.paletteRedTint.paletteRedTintForeground.paletteRedBorder.palettePumpkin.palettePumpkinForeground.palettePumpkinTint.palettePumpkinTintForeground.palettePumpkinBorder.paletteGold.paletteGoldForeground.paletteGoldTint.paletteGoldTintForeground.paletteGoldBorder.paletteForest.paletteForestForeground.paletteForestTint.paletteForestTintForeground.paletteForestBorder.paletteTeal.paletteTealForeground.paletteTealTint.paletteTealTintForeground.paletteTealBorder.paletteBlue.paletteBlueForeground.paletteBlueTint.paletteBlueTintForeground.paletteBlueBorder.paletteNavy.paletteNavyForeground.paletteNavyTint.paletteNavyTintForeground.paletteNavyBorder.paletteLavender.paletteLavenderForeground.paletteLavenderTint.paletteLavenderTintForeground.paletteLavenderBorder.palettePurple.palettePurpleForeground.palettePurpleTint.palettePurpleTintForeground.palettePurpleBorder.paletteMagenta.paletteMagentaForeground.paletteMagentaTint.paletteMagentaTintForeground.paletteMagentaBorder.paletteBrown.paletteBrownForeground.paletteBrownTint.paletteBrownTintForeground.paletteBrownBorder.paletteSteel.paletteSteelForeground.paletteSteelTint.paletteSteelTintForeground.paletteSteelBorder.shadow2.shadow4.shadow8.shadow16.shadow28.shadow64.cardForeground.secondaryForeground.accent.accentForeground.inputFilledLighter".split(".");
|
|
4
|
+
function n() {
|
|
5
|
+
return Object.freeze(Object.fromEntries(t.map((t) => [t, `var(${e(t)})`])));
|
|
6
|
+
}
|
|
7
|
+
var r = /* @__PURE__ */ n(), i = /* @__PURE__ */ Object.freeze([
|
|
8
|
+
"paletteBlue",
|
|
9
|
+
"palettePurple",
|
|
10
|
+
"paletteBrown",
|
|
11
|
+
"paletteTeal",
|
|
12
|
+
"paletteRed",
|
|
13
|
+
"paletteNavy",
|
|
14
|
+
"palettePumpkin",
|
|
15
|
+
"paletteSteel",
|
|
16
|
+
"paletteGold",
|
|
17
|
+
"paletteLavender",
|
|
18
|
+
"paletteForest",
|
|
19
|
+
"paletteMagenta"
|
|
20
|
+
]);
|
|
21
|
+
//#endregion
|
|
22
|
+
export { t as WAVE_TOKEN_NAMES, i as chartPalette, r as waveTokens };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=waveTokens.mjs.map
|