@weasel-js/theme 1.9.3 → 1.10.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 +51 -4
- package/dist/{chunk-NUILKH2Z.js → chunk-2PY2YTDY.js} +43 -69
- package/dist/chunk-2PY2YTDY.js.map +1 -0
- package/dist/chunk-3NIEJ77B.js +245 -0
- package/dist/chunk-3NIEJ77B.js.map +1 -0
- package/dist/{chunk-7FYXA7TA.js → chunk-JX2OC444.js} +221 -131
- package/dist/chunk-JX2OC444.js.map +1 -0
- package/dist/chunk-P5F3GZV6.js +54 -0
- package/dist/chunk-P5F3GZV6.js.map +1 -0
- package/dist/{definition-DACR1H4A.d.ts → definition-CSeERbSL.d.ts} +87 -28
- package/dist/engine.d.ts +13 -17
- package/dist/engine.js +227 -36
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +55 -10
- package/dist/index.js +57 -28
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +15 -4
- package/dist/react.js +19 -8
- package/dist/react.js.map +1 -1
- package/dist/themes/platinum.d.ts +22 -0
- package/dist/themes/platinum.js +802 -0
- package/dist/themes/platinum.js.map +1 -0
- package/dist/themes/win9x.d.ts +16 -0
- package/dist/themes/win9x.js +788 -0
- package/dist/themes/win9x.js.map +1 -0
- package/dist/tokens.css +32 -5
- package/package.json +11 -2
- package/dist/chunk-7FYXA7TA.js.map +0 -1
- package/dist/chunk-NUILKH2Z.js.map +0 -1
package/dist/engine.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { overrideKey, AXES_EXT, ALPHA_EXT } from './chunk-Z675UQ26.js';
|
|
2
|
-
import {
|
|
3
|
-
export { CHROMA_WEIGHT, DEFAULT_CONSTRAINTS, anchorFromHex, chromaCap, contrast, deltaE, floorDegrees, generate, hexToRgb, hueGap, hueName, luminance, toHex, toHexPreview, toLab, toLch, vividAt } from './chunk-
|
|
2
|
+
import { toLch, toHex, generate, DEFAULT_CONSTRAINTS, resolveTokens, mixAlpha, themeAxes, tokensAt, contrast, tokenAt } from './chunk-2PY2YTDY.js';
|
|
3
|
+
export { CHROMA_WEIGHT, DEFAULT_CONSTRAINTS, anchorFromHex, chromaCap, contrast, deltaE, floorDegrees, generate, hexToRgb, hueGap, hueName, luminance, toHex, toHexPreview, toLab, toLch, vividAt } from './chunk-2PY2YTDY.js';
|
|
4
|
+
import { mergeAxes, fullSelection, pick, enumerateSelections, pickAll, selectionKey, isByAxis } from './chunk-P5F3GZV6.js';
|
|
5
|
+
import { isPlainObject } from '@weasel-js/registry';
|
|
4
6
|
|
|
5
7
|
// src/engine/steps.ts
|
|
6
8
|
var stepList = (x) => Array.isArray(x) ? [...new Set(x.filter((s) => typeof s === "string"))] : [];
|
|
@@ -217,6 +219,20 @@ function axisDependencies(definition, lookup) {
|
|
|
217
219
|
return result;
|
|
218
220
|
}
|
|
219
221
|
|
|
222
|
+
// src/engine/axisIssues.ts
|
|
223
|
+
function axisIssues(axes) {
|
|
224
|
+
const issues = [];
|
|
225
|
+
for (const [name, def] of Object.entries(axes)) {
|
|
226
|
+
const values = Object.keys(def.values ?? {});
|
|
227
|
+
if (values.length === 0) {
|
|
228
|
+
issues.push({ kind: "invalid", path: `axes.${name}`, message: `axis "${name}" has no values` });
|
|
229
|
+
} else if (!values.includes(def.default)) {
|
|
230
|
+
issues.push({ kind: "invalid", path: `axes.${name}`, message: `axis "${name}" defaults to "${def.default}", which is not one of its values (${values.join(", ")})` });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return issues;
|
|
234
|
+
}
|
|
235
|
+
|
|
220
236
|
// src/engine/ramps.ts
|
|
221
237
|
var MAX_CHROMA = 0.4;
|
|
222
238
|
var smoothstep = (t) => t * t * (3 - 2 * t);
|
|
@@ -290,12 +306,10 @@ function scale(steps, p) {
|
|
|
290
306
|
});
|
|
291
307
|
return out;
|
|
292
308
|
}
|
|
293
|
-
|
|
294
|
-
// src/engine/semantics.ts
|
|
295
309
|
var TOKEN_REF2 = /^\{([^}.]+)\}$/;
|
|
296
310
|
var HEX = /^#[0-9a-f]{6}$/i;
|
|
297
311
|
var MAX_DEPTH = 32;
|
|
298
|
-
var isRecord =
|
|
312
|
+
var isRecord = isPlainObject;
|
|
299
313
|
var refTarget = (value) => typeof value === "string" ? TOKEN_REF2.exec(value.trim())?.[1] : void 0;
|
|
300
314
|
function deriveSemantics(rules, ctx) {
|
|
301
315
|
const done = /* @__PURE__ */ new Map();
|
|
@@ -577,12 +591,12 @@ var Reader = class {
|
|
|
577
591
|
}
|
|
578
592
|
record(x, path) {
|
|
579
593
|
if (x === void 0) return {};
|
|
580
|
-
if (
|
|
594
|
+
if (isPlainObject(x)) return x;
|
|
581
595
|
this.fail(path, "expected an object");
|
|
582
596
|
return {};
|
|
583
597
|
}
|
|
584
598
|
};
|
|
585
|
-
var isRecord2 =
|
|
599
|
+
var isRecord2 = isPlainObject;
|
|
586
600
|
var stepNames = (x) => Array.isArray(x) && x.every((s) => typeof s === "string") ? x : void 0;
|
|
587
601
|
function rampColors(name, r, steps, ctx) {
|
|
588
602
|
const path = `ramps.${name}`;
|
|
@@ -726,7 +740,7 @@ function inferTypes(tokens, provenance, failed, issues) {
|
|
|
726
740
|
issues.push({ kind: "untyped-pin", token: name });
|
|
727
741
|
}
|
|
728
742
|
}
|
|
729
|
-
var isPinObject = (v) =>
|
|
743
|
+
var isPinObject = (v) => isPlainObject(v) && "value" in v;
|
|
730
744
|
var NAMED_LAYERS = ["ramps", "scales", "semantics", "components", "pins"];
|
|
731
745
|
var SAFE_NAME = /^[A-Za-z0-9_-]+$/;
|
|
732
746
|
var isSafeName = (name) => SAFE_NAME.test(name);
|
|
@@ -746,6 +760,7 @@ function withoutUnsafeNames(def, issues) {
|
|
|
746
760
|
function derive(definition, selection = {}, lookup) {
|
|
747
761
|
const issues = [];
|
|
748
762
|
const def = withoutUnsafeNames(mergeChain(definition, lookup), issues);
|
|
763
|
+
issues.push(...axisIssues(def.axes ?? {}));
|
|
749
764
|
const sel = fullSelection(def.axes ?? {}, selection);
|
|
750
765
|
const seeds = {};
|
|
751
766
|
for (const [k, v] of Object.entries(def.seeds ?? {})) {
|
|
@@ -937,23 +952,14 @@ function bakeOver(definition, merged, above, lookup) {
|
|
|
937
952
|
const axes = merged.axes ?? {};
|
|
938
953
|
const own = table(definition, axes, lookup);
|
|
939
954
|
const at = (sel, name) => own.get(selectionKey(axes, sel))?.[name];
|
|
940
|
-
const inherited = (sel, name) =>
|
|
941
|
-
const full = fullSelection(axes, sel);
|
|
942
|
-
for (let i = above.length - 1; i >= 0; i--) {
|
|
943
|
-
const tokens2 = above[i].tokens;
|
|
944
|
-
if (!Object.hasOwn(tokens2, name)) continue;
|
|
945
|
-
const picked = pick(tokens2[name], full);
|
|
946
|
-
if (picked.ok) return picked.value;
|
|
947
|
-
}
|
|
948
|
-
return void 0;
|
|
949
|
-
};
|
|
955
|
+
const inherited = (sel, name) => tokenAt(above, name, fullSelection(axes, sel));
|
|
950
956
|
const produced = new Set([...own.values()].flatMap((t) => Object.keys(t)));
|
|
951
957
|
const ordered = definitionOrder(merged).filter((n) => produced.has(n));
|
|
952
958
|
const names = [...ordered, ...[...produced].filter((n) => !ordered.includes(n))];
|
|
953
959
|
const selections = enumerateSelections(axes);
|
|
954
960
|
const tokens = {};
|
|
955
961
|
for (const name of names) {
|
|
956
|
-
if (selections.every((sel) => same(at(sel, name), inherited(sel, name)))) continue;
|
|
962
|
+
if (selections.every((sel) => at(sel, name) === void 0 || same(at(sel, name), inherited(sel, name)))) continue;
|
|
957
963
|
const varying = Object.keys(axes).filter(
|
|
958
964
|
(axis) => selections.some((sel) => Object.keys(axes[axis].values).some((v) => !same(at(sel, name), at({ ...sel, [axis]: v }, name))))
|
|
959
965
|
);
|
|
@@ -998,7 +1004,7 @@ function cssValue(name, token) {
|
|
|
998
1004
|
const target = refTarget2(token);
|
|
999
1005
|
if (target === null) return resolveTokens({ [name]: token })[name];
|
|
1000
1006
|
if (token.alpha === void 0) return `var(--wzl-${target})`;
|
|
1001
|
-
return `
|
|
1007
|
+
return mixAlpha(`var(--wzl-${target})`, token.alpha);
|
|
1002
1008
|
}
|
|
1003
1009
|
function axisSets(axes) {
|
|
1004
1010
|
const names = Object.keys(axes);
|
|
@@ -1030,21 +1036,16 @@ function combineAxes(own, other) {
|
|
|
1030
1036
|
var Resolved = class {
|
|
1031
1037
|
axes;
|
|
1032
1038
|
names;
|
|
1039
|
+
/** Root first. */
|
|
1033
1040
|
chain;
|
|
1034
1041
|
memo = /* @__PURE__ */ new Map();
|
|
1035
1042
|
constructor(axes, chain) {
|
|
1036
1043
|
this.axes = axes;
|
|
1037
1044
|
this.chain = chain;
|
|
1038
|
-
this.names = [...new Set(
|
|
1045
|
+
this.names = [...new Set(chain.flatMap((t) => Object.keys(t.tokens)))];
|
|
1039
1046
|
}
|
|
1040
1047
|
token(name, sel) {
|
|
1041
|
-
|
|
1042
|
-
for (const t of this.chain) {
|
|
1043
|
-
if (!Object.hasOwn(t.tokens, name)) continue;
|
|
1044
|
-
const picked = pick(t.tokens[name], full);
|
|
1045
|
-
if (picked.ok) return picked.value;
|
|
1046
|
-
}
|
|
1047
|
-
return void 0;
|
|
1048
|
+
return tokenAt(this.chain, name, fullSelection(this.axes, sel));
|
|
1048
1049
|
}
|
|
1049
1050
|
/** What a browser computes: every `var()` substituted, down to literals. */
|
|
1050
1051
|
expanded(name, sel, stack = []) {
|
|
@@ -1064,7 +1065,7 @@ function chainOf(baked, byName) {
|
|
|
1064
1065
|
if (!baked.extends) return [baked];
|
|
1065
1066
|
const parent = byName.get(baked.extends);
|
|
1066
1067
|
if (!parent) throw new Error(`Theme "${baked.name}" extends "${baked.extends}", which is not being emitted`);
|
|
1067
|
-
return [
|
|
1068
|
+
return [...chainOf(parent, byName), baked];
|
|
1068
1069
|
}
|
|
1069
1070
|
var union = (axes, ...sets) => {
|
|
1070
1071
|
const all = new Set(sets.flatMap((s) => s ?? []));
|
|
@@ -1249,6 +1250,138 @@ function toDTCG(theme) {
|
|
|
1249
1250
|
|
|
1250
1251
|
// src/hooks.ts
|
|
1251
1252
|
var TOKEN_HOOKS = [
|
|
1253
|
+
{
|
|
1254
|
+
name: "titlebar-surface",
|
|
1255
|
+
type: "color",
|
|
1256
|
+
value: "var(--_edge)",
|
|
1257
|
+
description: "Background of the strip a `titlebar` frame carries its title in: a color, a gradient, or stripes. Unset, the frame\u2019s edge color. A frame that names a tone paints the tone instead."
|
|
1258
|
+
},
|
|
1259
|
+
{
|
|
1260
|
+
name: "titlebar-fg",
|
|
1261
|
+
type: "color",
|
|
1262
|
+
value: "var(--_edge-ink)",
|
|
1263
|
+
description: "Text color on a `titlebar` frame\u2019s strip. Unset, black or white, whichever reads on the edge color."
|
|
1264
|
+
},
|
|
1265
|
+
{
|
|
1266
|
+
name: "titlebar-align",
|
|
1267
|
+
type: "string",
|
|
1268
|
+
value: "start",
|
|
1269
|
+
description: "Text alignment of a `titlebar` frame\u2019s title along its strip."
|
|
1270
|
+
},
|
|
1271
|
+
{
|
|
1272
|
+
name: "titlebar-weight",
|
|
1273
|
+
type: "fontWeight",
|
|
1274
|
+
value: "var(--wzl-font-weight-bold)",
|
|
1275
|
+
description: "Font weight of a `titlebar` frame\u2019s title."
|
|
1276
|
+
},
|
|
1277
|
+
{
|
|
1278
|
+
name: "titlebar-label-surface",
|
|
1279
|
+
type: "color",
|
|
1280
|
+
value: "transparent",
|
|
1281
|
+
description: "Background behind a `titlebar` frame\u2019s title alone, for a strip drawn in stripes that must not run through the letters."
|
|
1282
|
+
},
|
|
1283
|
+
{
|
|
1284
|
+
name: "titlebar-label-pad",
|
|
1285
|
+
type: "dimension",
|
|
1286
|
+
value: "0",
|
|
1287
|
+
description: "Inline padding of the patch --wzl-titlebar-label-surface paints behind a `titlebar` frame\u2019s title."
|
|
1288
|
+
},
|
|
1289
|
+
{
|
|
1290
|
+
name: "titlebar-border",
|
|
1291
|
+
type: "border",
|
|
1292
|
+
value: "1px solid var(--_edge)",
|
|
1293
|
+
description: "Border of a `titlebar` frame. A theme whose --wzl-bevel-raised draws the edge sets it to a border of no width."
|
|
1294
|
+
},
|
|
1295
|
+
{
|
|
1296
|
+
name: "titlebar-inset",
|
|
1297
|
+
type: "dimension",
|
|
1298
|
+
value: "0",
|
|
1299
|
+
description: "Padding between a `titlebar` frame\u2019s edge and its strip and body: the width of the bevel a theme draws there."
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
name: "bevel-raised",
|
|
1303
|
+
type: "shadow",
|
|
1304
|
+
value: "none",
|
|
1305
|
+
description: "Box shadow of a raised face: a Button, a PropertyPanel, a menu, popover, tooltip, or Dialog, a thumb, the chosen segment of a segmented control, a toolbar\u2019s strip, and every edge of a tab but the one its panel is on. A theme that draws its edges in relief declares it; unset, each keeps the shadow it draws for itself, which for most is none."
|
|
1306
|
+
},
|
|
1307
|
+
{
|
|
1308
|
+
name: "bevel-pressed",
|
|
1309
|
+
type: "shadow",
|
|
1310
|
+
value: "none",
|
|
1311
|
+
description: "Box shadow of a Button held down, or of a Button or a toolbar\u2019s button that stays down. Unset, a Button draws its own inset (--btn-relief-pressed) and a toolbar\u2019s button none."
|
|
1312
|
+
},
|
|
1313
|
+
{
|
|
1314
|
+
name: "bevel-sunken",
|
|
1315
|
+
type: "shadow",
|
|
1316
|
+
value: "none",
|
|
1317
|
+
description: "Box shadow of a well: the frame a field draws its value in, a checkbox, a radio, the track of a switch, a slider, or a segmented control, and a cell of a flat one."
|
|
1318
|
+
},
|
|
1319
|
+
{
|
|
1320
|
+
name: "field-border",
|
|
1321
|
+
type: "border",
|
|
1322
|
+
value: "1px solid var(--wzl-border)",
|
|
1323
|
+
description: "Border of a field\u2019s frame. A theme whose --wzl-bevel-sunken draws the edge sets it to a border of no width."
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
name: "field-focus-shadow",
|
|
1327
|
+
type: "shadow",
|
|
1328
|
+
value: "0 0 0 1px var(--wzl-focus-ring)",
|
|
1329
|
+
description: "Box shadow of a field\u2019s frame while it holds focus. It replaces --wzl-bevel-sunken there, so a beveled theme restates the bevel in it."
|
|
1330
|
+
},
|
|
1331
|
+
{
|
|
1332
|
+
name: "button-radius",
|
|
1333
|
+
type: "dimension",
|
|
1334
|
+
value: "calc(var(--btn-height) * 0.1)",
|
|
1335
|
+
description: "Corner radius of a Button. Unset, a tenth of its height."
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
name: "button-surface",
|
|
1339
|
+
type: "color",
|
|
1340
|
+
value: "var(--btn-glass)",
|
|
1341
|
+
description: "Background of a secondary Button. Unset, neutral glass mixed from the surfaces."
|
|
1342
|
+
},
|
|
1343
|
+
{
|
|
1344
|
+
name: "button-pressed-surface",
|
|
1345
|
+
type: "color",
|
|
1346
|
+
value: "var(--btn-glass-pressed)",
|
|
1347
|
+
description: "Background of a secondary Button while it is held down."
|
|
1348
|
+
},
|
|
1349
|
+
{
|
|
1350
|
+
name: "button-primary-surface",
|
|
1351
|
+
type: "color",
|
|
1352
|
+
value: "var(--btn-glass)",
|
|
1353
|
+
description: "Background of a primary Button. Unset, glass tinted with --wzl-accent."
|
|
1354
|
+
},
|
|
1355
|
+
{
|
|
1356
|
+
name: "button-primary-pressed-surface",
|
|
1357
|
+
type: "color",
|
|
1358
|
+
value: "var(--btn-glass-pressed)",
|
|
1359
|
+
description: "Background of a primary Button while it is held down."
|
|
1360
|
+
},
|
|
1361
|
+
{
|
|
1362
|
+
name: "button-primary-fg",
|
|
1363
|
+
type: "color",
|
|
1364
|
+
value: "var(--wzl-fg-on-accent)",
|
|
1365
|
+
description: "Text color of a primary Button, for a theme whose --wzl-button-primary-surface is not an accent fill."
|
|
1366
|
+
},
|
|
1367
|
+
{
|
|
1368
|
+
name: "button-primary-bevel",
|
|
1369
|
+
type: "shadow",
|
|
1370
|
+
value: "var(--wzl-bevel-raised)",
|
|
1371
|
+
description: "Box shadow of a primary Button, where it differs from --wzl-bevel-raised: the heavier frame of a default button."
|
|
1372
|
+
},
|
|
1373
|
+
{
|
|
1374
|
+
name: "button-gloss",
|
|
1375
|
+
type: "number",
|
|
1376
|
+
value: "1",
|
|
1377
|
+
description: "Opacity of the specular sheen over a Button\u2019s upper half. 0 for a flat face."
|
|
1378
|
+
},
|
|
1379
|
+
{
|
|
1380
|
+
name: "button-text-shadow",
|
|
1381
|
+
type: "shadow",
|
|
1382
|
+
value: "var(--btn-engraving)",
|
|
1383
|
+
description: "Text shadow of a primary or secondary Button\u2019s label. Unset, an engraving stamp under the glyphs in dark mode."
|
|
1384
|
+
},
|
|
1252
1385
|
{
|
|
1253
1386
|
name: "detail-figure-min-width",
|
|
1254
1387
|
type: "dimension",
|
|
@@ -1321,6 +1454,12 @@ var TOKEN_HOOKS = [
|
|
|
1321
1454
|
value: "300px",
|
|
1322
1455
|
description: "Width of the Prefs category column."
|
|
1323
1456
|
},
|
|
1457
|
+
{
|
|
1458
|
+
name: "prop-columns",
|
|
1459
|
+
type: "string",
|
|
1460
|
+
value: "1fr 1fr",
|
|
1461
|
+
description: "Column tracks of a Properties list, group body, and subpanel. A container too narrow for two columns sets `minmax(0, 1fr)` to stack every row."
|
|
1462
|
+
},
|
|
1324
1463
|
{
|
|
1325
1464
|
name: "prop-number-width",
|
|
1326
1465
|
type: "dimension",
|
|
@@ -1380,6 +1519,60 @@ var TOKEN_HOOKS = [
|
|
|
1380
1519
|
type: "dimension",
|
|
1381
1520
|
value: "calc(var(--wzl-control-h-xs) + var(--wzl-space-2))",
|
|
1382
1521
|
description: "Indent of each Tree level. Unset, it is one twisty and one gap, so a child\u2019s twisty sits under its parent\u2019s label."
|
|
1522
|
+
},
|
|
1523
|
+
{
|
|
1524
|
+
name: "tree-font-size",
|
|
1525
|
+
type: "dimension",
|
|
1526
|
+
value: "var(--wzl-font-size-sm)",
|
|
1527
|
+
description: "Size of a Tree row\u2019s text."
|
|
1528
|
+
},
|
|
1529
|
+
{
|
|
1530
|
+
name: "tree-fold-size",
|
|
1531
|
+
type: "dimension",
|
|
1532
|
+
value: "16px",
|
|
1533
|
+
description: "Size of the leading glyph a Tree folds a branch by, where its branches fold by their glyphs."
|
|
1534
|
+
},
|
|
1535
|
+
{
|
|
1536
|
+
name: "tree-guide",
|
|
1537
|
+
type: "color",
|
|
1538
|
+
value: "var(--wzl-fg-subtle)",
|
|
1539
|
+
description: "Color of the bracket a Tree draws down a branch."
|
|
1540
|
+
},
|
|
1541
|
+
{
|
|
1542
|
+
name: "tree-leaf-indent",
|
|
1543
|
+
type: "dimension",
|
|
1544
|
+
value: "0",
|
|
1545
|
+
description: "How far in from its branches' glyphs a Tree with guides sets a row that folds nothing."
|
|
1546
|
+
},
|
|
1547
|
+
{
|
|
1548
|
+
name: "dialog-max-width",
|
|
1549
|
+
type: "dimension",
|
|
1550
|
+
value: "900px",
|
|
1551
|
+
description: "Widest a Dialog grows, modal or inline, before its contents wrap or scroll."
|
|
1552
|
+
},
|
|
1553
|
+
{
|
|
1554
|
+
name: "prefs-across-gap",
|
|
1555
|
+
type: "dimension",
|
|
1556
|
+
value: "28px",
|
|
1557
|
+
description: "Gap between the two columns of rows a PrefsForm pane sets side by side."
|
|
1558
|
+
},
|
|
1559
|
+
{
|
|
1560
|
+
name: "prefs-control-min",
|
|
1561
|
+
type: "dimension",
|
|
1562
|
+
value: "80px",
|
|
1563
|
+
description: "Narrowest a PrefsForm row\u2019s control gets in a two-across pane before the row wraps it under its label."
|
|
1564
|
+
},
|
|
1565
|
+
{
|
|
1566
|
+
name: "prop-panel-actions-basis",
|
|
1567
|
+
type: "dimension",
|
|
1568
|
+
value: "auto",
|
|
1569
|
+
description: "Width a PropertyPanel\u2019s title row gives its actions. Set, it holds that width whatever the actions are."
|
|
1570
|
+
},
|
|
1571
|
+
{
|
|
1572
|
+
name: "prop-panel-actions-align",
|
|
1573
|
+
type: "string",
|
|
1574
|
+
value: "center",
|
|
1575
|
+
description: "How a PropertyPanel\u2019s title row lines its actions up with the title: center, or baseline for actions that are text."
|
|
1383
1576
|
}
|
|
1384
1577
|
];
|
|
1385
1578
|
|
|
@@ -1434,9 +1627,6 @@ function chainOf2(baked, byName) {
|
|
|
1434
1627
|
if (baked.extends && !parent) throw new Error(`Theme "${baked.name}" extends "${baked.extends}", which is not in themes/`);
|
|
1435
1628
|
return [...parent ? chainOf2(parent, byName) : [], baked];
|
|
1436
1629
|
}
|
|
1437
|
-
function tokensAt(chain, sel) {
|
|
1438
|
-
return Object.assign({}, ...chain.map((t) => pickAll(t.tokens, sel)));
|
|
1439
|
-
}
|
|
1440
1630
|
function emitThemes(themes) {
|
|
1441
1631
|
const byName = new Map(themes.map((t) => [t.baked.name, t.baked]));
|
|
1442
1632
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -1506,11 +1696,12 @@ function generateTokens(definitions) {
|
|
|
1506
1696
|
const roots = definitions.filter((d) => !d.extends);
|
|
1507
1697
|
if (roots.length !== 1) throw new Error(`themes/ needs exactly one theme that extends nothing; found ${roots.length}`);
|
|
1508
1698
|
const ordered = [roots[0], ...definitions.filter((d) => d.extends)];
|
|
1509
|
-
const problems = ordered.flatMap(
|
|
1510
|
-
|
|
1699
|
+
const problems = ordered.flatMap((def) => {
|
|
1700
|
+
const selections = enumerateSelections(mergeChain(def, lookup).axes ?? {});
|
|
1701
|
+
return (selections.length > 0 ? selections : [{}]).flatMap(
|
|
1511
1702
|
(sel) => derive(def, sel, lookup).issues.map((issue) => `${def.name} ${JSON.stringify(sel)}: ${JSON.stringify(issue)}`)
|
|
1512
|
-
)
|
|
1513
|
-
);
|
|
1703
|
+
);
|
|
1704
|
+
});
|
|
1514
1705
|
if (problems.length > 0) return { ok: false, problems };
|
|
1515
1706
|
const themes = ordered.map((definition) => ({
|
|
1516
1707
|
definition,
|