@weasel-js/theme 1.9.3 → 1.9.4
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 +7 -0
- package/dist/{chunk-NUILKH2Z.js → chunk-7LCRXZDY.js} +43 -20
- package/dist/chunk-7LCRXZDY.js.map +1 -0
- package/dist/{chunk-7FYXA7TA.js → chunk-EFGZ56CE.js} +131 -51
- package/dist/chunk-EFGZ56CE.js.map +1 -0
- package/dist/{definition-DACR1H4A.d.ts → definition-GS7_Kz9D.d.ts} +8 -7
- package/dist/engine.d.ts +4 -4
- package/dist/engine.js +76 -36
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +19 -9
- package/dist/index.js +15 -7
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +6 -4
- package/dist/react.js.map +1 -1
- package/dist/tokens.css +8 -4
- package/package.json +3 -2
- package/dist/chunk-7FYXA7TA.js.map +0 -1
- package/dist/chunk-NUILKH2Z.js.map +0 -1
|
@@ -247,8 +247,8 @@ declare const THEMES: {
|
|
|
247
247
|
readonly '--wzl-slider-thumb-size': "8px";
|
|
248
248
|
readonly '--wzl-slider-track-slop': "6px";
|
|
249
249
|
readonly '--wzl-slider-thumb-slop': "6px";
|
|
250
|
-
readonly '--wzl-slider-track-mix': "
|
|
251
|
-
readonly '--wzl-slider-thumb-mix': "
|
|
250
|
+
readonly '--wzl-slider-track-mix': "40%";
|
|
251
|
+
readonly '--wzl-slider-thumb-mix': "100%";
|
|
252
252
|
readonly '--wzl-handle-size': "9px";
|
|
253
253
|
readonly '--wzl-handle-size-sm': "7px";
|
|
254
254
|
readonly '--wzl-handle-size-lg': "10px";
|
|
@@ -425,8 +425,8 @@ declare const THEMES: {
|
|
|
425
425
|
readonly '--wzl-slider-thumb-size': "8px";
|
|
426
426
|
readonly '--wzl-slider-track-slop': "6px";
|
|
427
427
|
readonly '--wzl-slider-thumb-slop': "6px";
|
|
428
|
-
readonly '--wzl-slider-track-mix': "
|
|
429
|
-
readonly '--wzl-slider-thumb-mix': "
|
|
428
|
+
readonly '--wzl-slider-track-mix': "40%";
|
|
429
|
+
readonly '--wzl-slider-thumb-mix': "100%";
|
|
430
430
|
readonly '--wzl-handle-size': "9px";
|
|
431
431
|
readonly '--wzl-handle-size-sm': "7px";
|
|
432
432
|
readonly '--wzl-handle-size-lg': "10px";
|
|
@@ -603,8 +603,8 @@ declare const THEMES: {
|
|
|
603
603
|
readonly '--wzl-slider-thumb-size': "8px";
|
|
604
604
|
readonly '--wzl-slider-track-slop': "6px";
|
|
605
605
|
readonly '--wzl-slider-thumb-slop': "6px";
|
|
606
|
-
readonly '--wzl-slider-track-mix': "
|
|
607
|
-
readonly '--wzl-slider-thumb-mix': "
|
|
606
|
+
readonly '--wzl-slider-track-mix': "40%";
|
|
607
|
+
readonly '--wzl-slider-thumb-mix': "100%";
|
|
608
608
|
readonly '--wzl-handle-size': "9px";
|
|
609
609
|
readonly '--wzl-handle-size-sm': "7px";
|
|
610
610
|
readonly '--wzl-handle-size-lg': "10px";
|
|
@@ -1221,7 +1221,8 @@ declare function themeAxes(theme: Theme): AxisDefs;
|
|
|
1221
1221
|
/**
|
|
1222
1222
|
* Merge the extends chain at a selection, resolve every alias, and key the
|
|
1223
1223
|
* result by CSS custom-property name. A missing or unknown axis value takes the
|
|
1224
|
-
* axis default
|
|
1224
|
+
* axis default, and a theme in the chain reads a value it never declared at its
|
|
1225
|
+
* own default for that axis.
|
|
1225
1226
|
*
|
|
1226
1227
|
* Pure — no DOM. An unresolvable reference throws rather than falling back.
|
|
1227
1228
|
*/
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { OklchDeg, oklchDegToHex } from '@weasel-js/paint';
|
|
2
|
-
import { T as ThemeDefinition, L as Lookup, F as FlatTokens, R as RawToken, S as Selection, B as BakedTheme, A as AxisDefs, a as Theme } from './definition-
|
|
3
|
-
export { C as CategoricalRampDef, b as ContrastRule, c as LightnessRampDef, d as LiteralRule, N as NumberParam, O as OffsetRule, P as PinObject, e as PinValue, f as RampDef, g as RefRule, h as ScaleDef, i as SemanticRule, j as StepRule, k as bake, l as bakeChain, m as mergeChain } from './definition-
|
|
2
|
+
import { T as ThemeDefinition, L as Lookup, F as FlatTokens, R as RawToken, S as Selection, B as BakedTheme, A as AxisDefs, a as Theme } from './definition-GS7_Kz9D.js';
|
|
3
|
+
export { C as CategoricalRampDef, b as ContrastRule, c as LightnessRampDef, d as LiteralRule, N as NumberParam, O as OffsetRule, P as PinObject, e as PinValue, f as RampDef, g as RefRule, h as ScaleDef, i as SemanticRule, j as StepRule, k as bake, l as bakeChain, m as mergeChain } from './definition-GS7_Kz9D.js';
|
|
4
4
|
|
|
5
5
|
/** A color in OKLCH: lightness 0–1, chroma, hue in degrees. paint's own type,
|
|
6
6
|
* under the name this engine has always called it. */
|
|
7
7
|
type Lch = OklchDeg;
|
|
8
|
-
/**
|
|
9
|
-
declare
|
|
8
|
+
/** A hex color to 0–255 channels, its alpha dropped. Throws on anything else. */
|
|
9
|
+
declare const hexToRgb: (hex: string) => [number, number, number];
|
|
10
10
|
/** OKLCH (lightness 0–1, chroma, hue in degrees) to `#rrggbb`. Chroma past the gamut is clipped at constant lightness. */
|
|
11
11
|
declare const toHex: typeof oklchDegToHex;
|
|
12
12
|
/** `#rrggbb` to OKLCH, hue in 0–360. */
|
package/dist/engine.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { overrideKey, AXES_EXT, ALPHA_EXT } from './chunk-Z675UQ26.js';
|
|
2
|
-
import { mergeAxes, toLch, toHex, generate, DEFAULT_CONSTRAINTS, fullSelection, pick, enumerateSelections, resolveTokens, pickAll, themeAxes, selectionKey, isByAxis, contrast } from './chunk-
|
|
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 { mergeAxes, toLch, toHex, generate, DEFAULT_CONSTRAINTS, fullSelection, pick, enumerateSelections, resolveTokens, mixAlpha, pickAll, themeAxes, tokensAt, selectionKey, isByAxis, contrast, tokenAt } from './chunk-7LCRXZDY.js';
|
|
3
|
+
export { CHROMA_WEIGHT, DEFAULT_CONSTRAINTS, anchorFromHex, chromaCap, contrast, deltaE, floorDegrees, generate, hexToRgb, hueGap, hueName, luminance, toHex, toHexPreview, toLab, toLch, vividAt } from './chunk-7LCRXZDY.js';
|
|
4
|
+
import { isPlainObject } from '@weasel-js/registry';
|
|
4
5
|
|
|
5
6
|
// src/engine/steps.ts
|
|
6
7
|
var stepList = (x) => Array.isArray(x) ? [...new Set(x.filter((s) => typeof s === "string"))] : [];
|
|
@@ -217,6 +218,20 @@ function axisDependencies(definition, lookup) {
|
|
|
217
218
|
return result;
|
|
218
219
|
}
|
|
219
220
|
|
|
221
|
+
// src/engine/axisIssues.ts
|
|
222
|
+
function axisIssues(axes) {
|
|
223
|
+
const issues = [];
|
|
224
|
+
for (const [name, def] of Object.entries(axes)) {
|
|
225
|
+
const values = Object.keys(def.values ?? {});
|
|
226
|
+
if (values.length === 0) {
|
|
227
|
+
issues.push({ kind: "invalid", path: `axes.${name}`, message: `axis "${name}" has no values` });
|
|
228
|
+
} else if (!values.includes(def.default)) {
|
|
229
|
+
issues.push({ kind: "invalid", path: `axes.${name}`, message: `axis "${name}" defaults to "${def.default}", which is not one of its values (${values.join(", ")})` });
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return issues;
|
|
233
|
+
}
|
|
234
|
+
|
|
220
235
|
// src/engine/ramps.ts
|
|
221
236
|
var MAX_CHROMA = 0.4;
|
|
222
237
|
var smoothstep = (t) => t * t * (3 - 2 * t);
|
|
@@ -290,12 +305,10 @@ function scale(steps, p) {
|
|
|
290
305
|
});
|
|
291
306
|
return out;
|
|
292
307
|
}
|
|
293
|
-
|
|
294
|
-
// src/engine/semantics.ts
|
|
295
308
|
var TOKEN_REF2 = /^\{([^}.]+)\}$/;
|
|
296
309
|
var HEX = /^#[0-9a-f]{6}$/i;
|
|
297
310
|
var MAX_DEPTH = 32;
|
|
298
|
-
var isRecord =
|
|
311
|
+
var isRecord = isPlainObject;
|
|
299
312
|
var refTarget = (value) => typeof value === "string" ? TOKEN_REF2.exec(value.trim())?.[1] : void 0;
|
|
300
313
|
function deriveSemantics(rules, ctx) {
|
|
301
314
|
const done = /* @__PURE__ */ new Map();
|
|
@@ -577,12 +590,12 @@ var Reader = class {
|
|
|
577
590
|
}
|
|
578
591
|
record(x, path) {
|
|
579
592
|
if (x === void 0) return {};
|
|
580
|
-
if (
|
|
593
|
+
if (isPlainObject(x)) return x;
|
|
581
594
|
this.fail(path, "expected an object");
|
|
582
595
|
return {};
|
|
583
596
|
}
|
|
584
597
|
};
|
|
585
|
-
var isRecord2 =
|
|
598
|
+
var isRecord2 = isPlainObject;
|
|
586
599
|
var stepNames = (x) => Array.isArray(x) && x.every((s) => typeof s === "string") ? x : void 0;
|
|
587
600
|
function rampColors(name, r, steps, ctx) {
|
|
588
601
|
const path = `ramps.${name}`;
|
|
@@ -726,7 +739,7 @@ function inferTypes(tokens, provenance, failed, issues) {
|
|
|
726
739
|
issues.push({ kind: "untyped-pin", token: name });
|
|
727
740
|
}
|
|
728
741
|
}
|
|
729
|
-
var isPinObject = (v) =>
|
|
742
|
+
var isPinObject = (v) => isPlainObject(v) && "value" in v;
|
|
730
743
|
var NAMED_LAYERS = ["ramps", "scales", "semantics", "components", "pins"];
|
|
731
744
|
var SAFE_NAME = /^[A-Za-z0-9_-]+$/;
|
|
732
745
|
var isSafeName = (name) => SAFE_NAME.test(name);
|
|
@@ -746,6 +759,7 @@ function withoutUnsafeNames(def, issues) {
|
|
|
746
759
|
function derive(definition, selection = {}, lookup) {
|
|
747
760
|
const issues = [];
|
|
748
761
|
const def = withoutUnsafeNames(mergeChain(definition, lookup), issues);
|
|
762
|
+
issues.push(...axisIssues(def.axes ?? {}));
|
|
749
763
|
const sel = fullSelection(def.axes ?? {}, selection);
|
|
750
764
|
const seeds = {};
|
|
751
765
|
for (const [k, v] of Object.entries(def.seeds ?? {})) {
|
|
@@ -937,23 +951,14 @@ function bakeOver(definition, merged, above, lookup) {
|
|
|
937
951
|
const axes = merged.axes ?? {};
|
|
938
952
|
const own = table(definition, axes, lookup);
|
|
939
953
|
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
|
-
};
|
|
954
|
+
const inherited = (sel, name) => tokenAt(above, name, fullSelection(axes, sel));
|
|
950
955
|
const produced = new Set([...own.values()].flatMap((t) => Object.keys(t)));
|
|
951
956
|
const ordered = definitionOrder(merged).filter((n) => produced.has(n));
|
|
952
957
|
const names = [...ordered, ...[...produced].filter((n) => !ordered.includes(n))];
|
|
953
958
|
const selections = enumerateSelections(axes);
|
|
954
959
|
const tokens = {};
|
|
955
960
|
for (const name of names) {
|
|
956
|
-
if (selections.every((sel) => same(at(sel, name), inherited(sel, name)))) continue;
|
|
961
|
+
if (selections.every((sel) => at(sel, name) === void 0 || same(at(sel, name), inherited(sel, name)))) continue;
|
|
957
962
|
const varying = Object.keys(axes).filter(
|
|
958
963
|
(axis) => selections.some((sel) => Object.keys(axes[axis].values).some((v) => !same(at(sel, name), at({ ...sel, [axis]: v }, name))))
|
|
959
964
|
);
|
|
@@ -998,7 +1003,7 @@ function cssValue(name, token) {
|
|
|
998
1003
|
const target = refTarget2(token);
|
|
999
1004
|
if (target === null) return resolveTokens({ [name]: token })[name];
|
|
1000
1005
|
if (token.alpha === void 0) return `var(--wzl-${target})`;
|
|
1001
|
-
return `
|
|
1006
|
+
return mixAlpha(`var(--wzl-${target})`, token.alpha);
|
|
1002
1007
|
}
|
|
1003
1008
|
function axisSets(axes) {
|
|
1004
1009
|
const names = Object.keys(axes);
|
|
@@ -1030,21 +1035,16 @@ function combineAxes(own, other) {
|
|
|
1030
1035
|
var Resolved = class {
|
|
1031
1036
|
axes;
|
|
1032
1037
|
names;
|
|
1038
|
+
/** Root first. */
|
|
1033
1039
|
chain;
|
|
1034
1040
|
memo = /* @__PURE__ */ new Map();
|
|
1035
1041
|
constructor(axes, chain) {
|
|
1036
1042
|
this.axes = axes;
|
|
1037
1043
|
this.chain = chain;
|
|
1038
|
-
this.names = [...new Set(
|
|
1044
|
+
this.names = [...new Set(chain.flatMap((t) => Object.keys(t.tokens)))];
|
|
1039
1045
|
}
|
|
1040
1046
|
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;
|
|
1047
|
+
return tokenAt(this.chain, name, fullSelection(this.axes, sel));
|
|
1048
1048
|
}
|
|
1049
1049
|
/** What a browser computes: every `var()` substituted, down to literals. */
|
|
1050
1050
|
expanded(name, sel, stack = []) {
|
|
@@ -1064,7 +1064,7 @@ function chainOf(baked, byName) {
|
|
|
1064
1064
|
if (!baked.extends) return [baked];
|
|
1065
1065
|
const parent = byName.get(baked.extends);
|
|
1066
1066
|
if (!parent) throw new Error(`Theme "${baked.name}" extends "${baked.extends}", which is not being emitted`);
|
|
1067
|
-
return [
|
|
1067
|
+
return [...chainOf(parent, byName), baked];
|
|
1068
1068
|
}
|
|
1069
1069
|
var union = (axes, ...sets) => {
|
|
1070
1070
|
const all = new Set(sets.flatMap((s) => s ?? []));
|
|
@@ -1380,6 +1380,48 @@ var TOKEN_HOOKS = [
|
|
|
1380
1380
|
type: "dimension",
|
|
1381
1381
|
value: "calc(var(--wzl-control-h-xs) + var(--wzl-space-2))",
|
|
1382
1382
|
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."
|
|
1383
|
+
},
|
|
1384
|
+
{
|
|
1385
|
+
name: "tree-font-size",
|
|
1386
|
+
type: "dimension",
|
|
1387
|
+
value: "var(--wzl-font-size-sm)",
|
|
1388
|
+
description: "Size of a Tree row\u2019s text."
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
name: "tree-fold-size",
|
|
1392
|
+
type: "dimension",
|
|
1393
|
+
value: "16px",
|
|
1394
|
+
description: "Size of the leading glyph a Tree folds a branch by, where its branches fold by their glyphs."
|
|
1395
|
+
},
|
|
1396
|
+
{
|
|
1397
|
+
name: "tree-guide",
|
|
1398
|
+
type: "color",
|
|
1399
|
+
value: "var(--wzl-fg-subtle)",
|
|
1400
|
+
description: "Color of the bracket a Tree draws down a branch."
|
|
1401
|
+
},
|
|
1402
|
+
{
|
|
1403
|
+
name: "dialog-max-width",
|
|
1404
|
+
type: "dimension",
|
|
1405
|
+
value: "900px",
|
|
1406
|
+
description: "Widest a Dialog grows, modal or inline, before its contents wrap or scroll."
|
|
1407
|
+
},
|
|
1408
|
+
{
|
|
1409
|
+
name: "prefs-across-gap",
|
|
1410
|
+
type: "dimension",
|
|
1411
|
+
value: "28px",
|
|
1412
|
+
description: "Gap between the two columns of rows a PrefsForm pane sets side by side."
|
|
1413
|
+
},
|
|
1414
|
+
{
|
|
1415
|
+
name: "prefs-control-min",
|
|
1416
|
+
type: "dimension",
|
|
1417
|
+
value: "80px",
|
|
1418
|
+
description: "Narrowest a PrefsForm row\u2019s control gets in a two-across pane before the row wraps it under its label."
|
|
1419
|
+
},
|
|
1420
|
+
{
|
|
1421
|
+
name: "prop-panel-actions-basis",
|
|
1422
|
+
type: "dimension",
|
|
1423
|
+
value: "auto",
|
|
1424
|
+
description: "Width a PropertyPanel\u2019s title row gives its actions. Set, it holds that width whatever the actions are."
|
|
1383
1425
|
}
|
|
1384
1426
|
];
|
|
1385
1427
|
|
|
@@ -1434,9 +1476,6 @@ function chainOf2(baked, byName) {
|
|
|
1434
1476
|
if (baked.extends && !parent) throw new Error(`Theme "${baked.name}" extends "${baked.extends}", which is not in themes/`);
|
|
1435
1477
|
return [...parent ? chainOf2(parent, byName) : [], baked];
|
|
1436
1478
|
}
|
|
1437
|
-
function tokensAt(chain, sel) {
|
|
1438
|
-
return Object.assign({}, ...chain.map((t) => pickAll(t.tokens, sel)));
|
|
1439
|
-
}
|
|
1440
1479
|
function emitThemes(themes) {
|
|
1441
1480
|
const byName = new Map(themes.map((t) => [t.baked.name, t.baked]));
|
|
1442
1481
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -1506,11 +1545,12 @@ function generateTokens(definitions) {
|
|
|
1506
1545
|
const roots = definitions.filter((d) => !d.extends);
|
|
1507
1546
|
if (roots.length !== 1) throw new Error(`themes/ needs exactly one theme that extends nothing; found ${roots.length}`);
|
|
1508
1547
|
const ordered = [roots[0], ...definitions.filter((d) => d.extends)];
|
|
1509
|
-
const problems = ordered.flatMap(
|
|
1510
|
-
|
|
1548
|
+
const problems = ordered.flatMap((def) => {
|
|
1549
|
+
const selections = enumerateSelections(mergeChain(def, lookup).axes ?? {});
|
|
1550
|
+
return (selections.length > 0 ? selections : [{}]).flatMap(
|
|
1511
1551
|
(sel) => derive(def, sel, lookup).issues.map((issue) => `${def.name} ${JSON.stringify(sel)}: ${JSON.stringify(issue)}`)
|
|
1512
|
-
)
|
|
1513
|
-
);
|
|
1552
|
+
);
|
|
1553
|
+
});
|
|
1514
1554
|
if (problems.length > 0) return { ok: false, problems };
|
|
1515
1555
|
const themes = ordered.map((definition) => ({
|
|
1516
1556
|
definition,
|