@unpunnyfuns/swatchbook-blocks 0.54.0 → 0.56.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/dist/index.d.mts +72 -31
- package/dist/index.mjs +243 -168
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -2,12 +2,13 @@ import './style.css';
|
|
|
2
2
|
import Color from "colorjs.io";
|
|
3
3
|
import { Fragment, createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
4
4
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import {
|
|
5
|
+
import { buildResolveAt } from "@unpunnyfuns/swatchbook-core/resolve-at";
|
|
6
|
+
import { makeCssVar } from "@unpunnyfuns/swatchbook-core/css-var";
|
|
6
7
|
import { addons } from "storybook/preview-api";
|
|
7
|
-
import { axes, css, cssVarPrefix,
|
|
8
|
+
import { axes, cells, css, cssVarPrefix, defaultTuple, diagnostics, jointOverrides, listing, presets, varianceByPath } from "virtual:swatchbook/tokens";
|
|
9
|
+
import { dataAttr } from "@unpunnyfuns/swatchbook-core/data-attr";
|
|
8
10
|
import { fuzzyFilter } from "@unpunnyfuns/swatchbook-core/fuzzy";
|
|
9
11
|
import cx from "clsx";
|
|
10
|
-
import { analyzeAxisVariance } from "@unpunnyfuns/swatchbook-core/variance";
|
|
11
12
|
//#region src/format-color.ts
|
|
12
13
|
const COLOR_FORMATS = [
|
|
13
14
|
"hex",
|
|
@@ -56,7 +57,8 @@ function coerce(value) {
|
|
|
56
57
|
return null;
|
|
57
58
|
}
|
|
58
59
|
const alpha = typeof v.alpha === "number" ? v.alpha : void 0;
|
|
59
|
-
const
|
|
60
|
+
const hexVal = v["hex"];
|
|
61
|
+
const hex = typeof hexVal === "string" ? hexVal : void 0;
|
|
60
62
|
return {
|
|
61
63
|
colorSpace,
|
|
62
64
|
components,
|
|
@@ -217,33 +219,23 @@ function ensureSubscribed$1() {
|
|
|
217
219
|
if (subscribed$1 || typeof window === "undefined") return;
|
|
218
220
|
subscribed$1 = true;
|
|
219
221
|
const channel = addons.getChannel();
|
|
222
|
+
let lastFingerprint = "";
|
|
220
223
|
const onGlobals = (payload) => {
|
|
221
224
|
const globals = payload.globals;
|
|
222
225
|
if (!globals) return;
|
|
223
|
-
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
226
|
+
const incomingAxes = globals[AXES_GLOBAL_KEY];
|
|
227
|
+
const incomingFormat = globals[COLOR_FORMAT_GLOBAL_KEY];
|
|
228
|
+
const nextAxes = incomingAxes && typeof incomingAxes === "object" ? incomingAxes : snapshot$1.axes;
|
|
229
|
+
const nextFormat = isColorFormat(incomingFormat) ? incomingFormat : snapshot$1.format;
|
|
230
|
+
const fingerprint = `${nextFormat ?? ""}|${nextAxes ? JSON.stringify(nextAxes) : ""}`;
|
|
231
|
+
if (fingerprint === lastFingerprint) return;
|
|
232
|
+
lastFingerprint = fingerprint;
|
|
233
|
+
snapshot$1 = {
|
|
234
|
+
axes: nextAxes,
|
|
232
235
|
format: nextFormat
|
|
233
236
|
};
|
|
234
|
-
|
|
235
|
-
snapshot$1 = next;
|
|
236
|
-
for (const cb of listeners$1) cb();
|
|
237
|
-
}
|
|
237
|
+
for (const cb of listeners$1) cb();
|
|
238
238
|
};
|
|
239
|
-
/**
|
|
240
|
-
* `setGlobals` fires once on preview init carrying the URL-persisted user
|
|
241
|
-
* globals (Storybook stores toolbar selections in `?globals=…`). Without
|
|
242
|
-
* this listener, deeplinking to an MDX page with a non-default axis tuple
|
|
243
|
-
* or color format renders defaults for one frame before the first
|
|
244
|
-
* `updateGlobals` arrives. `emitGlobals()` reads from `userGlobals.get()`
|
|
245
|
-
* (current state), so the payload is never stale — safe to handle.
|
|
246
|
-
*/
|
|
247
239
|
channel.on("globalsUpdated", onGlobals);
|
|
248
240
|
channel.on("updateGlobals", onGlobals);
|
|
249
241
|
channel.on("setGlobals", onGlobals);
|
|
@@ -343,13 +335,14 @@ const TOKENS_UPDATED_EVENT = "swatchbook/tokens-updated";
|
|
|
343
335
|
let snapshot = {
|
|
344
336
|
axes,
|
|
345
337
|
presets,
|
|
346
|
-
permutations,
|
|
347
|
-
defaultPermutation,
|
|
348
|
-
permutationsResolved,
|
|
349
338
|
diagnostics,
|
|
350
339
|
css,
|
|
351
340
|
cssVarPrefix,
|
|
352
341
|
listing: listing ?? {},
|
|
342
|
+
cells: cells ?? {},
|
|
343
|
+
jointOverrides: jointOverrides ?? [],
|
|
344
|
+
varianceByPath: varianceByPath ?? {},
|
|
345
|
+
defaultTuple: defaultTuple ?? {},
|
|
353
346
|
version: 0
|
|
354
347
|
};
|
|
355
348
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -361,13 +354,14 @@ function ensureSubscribed() {
|
|
|
361
354
|
snapshot = {
|
|
362
355
|
axes: payload.axes ?? snapshot.axes,
|
|
363
356
|
presets: payload.presets ?? snapshot.presets,
|
|
364
|
-
permutations: payload.permutations ?? snapshot.permutations,
|
|
365
|
-
defaultPermutation: payload.defaultPermutation ?? snapshot.defaultPermutation,
|
|
366
|
-
permutationsResolved: payload.permutationsResolved ?? snapshot.permutationsResolved,
|
|
367
357
|
diagnostics: payload.diagnostics ?? snapshot.diagnostics,
|
|
368
358
|
css: payload.css ?? snapshot.css,
|
|
369
359
|
cssVarPrefix: payload.cssVarPrefix ?? snapshot.cssVarPrefix,
|
|
370
360
|
listing: payload.listing ?? snapshot.listing,
|
|
361
|
+
cells: payload.cells ?? snapshot.cells,
|
|
362
|
+
jointOverrides: payload.jointOverrides ?? snapshot.jointOverrides,
|
|
363
|
+
varianceByPath: payload.varianceByPath ?? snapshot.varianceByPath,
|
|
364
|
+
defaultTuple: payload.defaultTuple ?? snapshot.defaultTuple,
|
|
371
365
|
version: snapshot.version + 1
|
|
372
366
|
};
|
|
373
367
|
for (const cb of listeners) cb();
|
|
@@ -400,31 +394,46 @@ function ensureStylesheet(css) {
|
|
|
400
394
|
}
|
|
401
395
|
if (style.textContent !== css) style.textContent = css;
|
|
402
396
|
}
|
|
403
|
-
function defaultTuple(axes) {
|
|
397
|
+
function defaultTuple$1(axes) {
|
|
404
398
|
const out = {};
|
|
405
399
|
for (const axis of axes) out[axis.name] = axis.default;
|
|
406
400
|
return out;
|
|
407
401
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
402
|
+
/**
|
|
403
|
+
* Synthesize a permutation name from a tuple — same form
|
|
404
|
+
* `permutationID` produces server-side (axis values joined by ` · `).
|
|
405
|
+
* Used by the AxisVariance grid for `data-<prefix>-theme` attribution
|
|
406
|
+
* and similar display-only callers.
|
|
407
|
+
*/
|
|
408
|
+
function tupleToName(axes, tuple) {
|
|
409
|
+
return axes.map((a) => tuple[a.name] ?? a.default).join(" · ");
|
|
412
410
|
}
|
|
413
|
-
|
|
414
|
-
|
|
411
|
+
/**
|
|
412
|
+
* Reconstruct a `resolveAt` accessor from snapshot data. Both `cells`
|
|
413
|
+
* and `jointOverrides` ship as plain JSON in the same shape core uses
|
|
414
|
+
* internally — no Map reconstruction at the boundary. Stable identity
|
|
415
|
+
* across calls with the same snapshot — `useMemo` keyed on the
|
|
416
|
+
* snapshot fields produces a referentially stable function.
|
|
417
|
+
*/
|
|
418
|
+
function makeResolveAt(snapshot) {
|
|
419
|
+
const cells = snapshot.cells ?? {};
|
|
420
|
+
const jointOverrides = snapshot.jointOverrides ?? [];
|
|
421
|
+
const defaults = snapshot.defaultTuple ?? defaultTuple$1(snapshot.axes);
|
|
422
|
+
const resolver = buildResolveAt(snapshot.axes, cells, jointOverrides, defaults);
|
|
423
|
+
return (tuple) => resolver(tuple);
|
|
415
424
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
425
|
+
/**
|
|
426
|
+
* Build the `resolveAt` accessor for a snapshot. Prefers the
|
|
427
|
+
* snapshot's own `resolveAt` (the addon's preview decorator
|
|
428
|
+
* pre-builds one at module load — see `previewResolveAt` in
|
|
429
|
+
* `packages/addon/src/preview.tsx`), otherwise composes one from
|
|
430
|
+
* `cells` + `jointOverrides` via `makeResolveAt`. Hand-built
|
|
431
|
+
* snapshots should provide both via the test `withCellsShape`
|
|
432
|
+
* helper or by populating the fields directly.
|
|
433
|
+
*/
|
|
434
|
+
function snapshotResolveAt(snapshot) {
|
|
435
|
+
if (snapshot.resolveAt) return snapshot.resolveAt;
|
|
436
|
+
return makeResolveAt(snapshot);
|
|
428
437
|
}
|
|
429
438
|
/**
|
|
430
439
|
* Reads project data either from a mounted {@link SwatchbookProvider}
|
|
@@ -440,8 +449,56 @@ function snapshotToData(snapshot) {
|
|
|
440
449
|
*/
|
|
441
450
|
function useProject() {
|
|
442
451
|
const snapshot = useOptionalSwatchbookData();
|
|
452
|
+
const axes = snapshot?.axes;
|
|
453
|
+
const cells = snapshot?.cells;
|
|
454
|
+
const jointOverrides = snapshot?.jointOverrides;
|
|
455
|
+
const dataDefaultTuple = snapshot?.defaultTuple;
|
|
456
|
+
const activeAxes = snapshot?.activeAxes;
|
|
457
|
+
const activePermutation = snapshot?.activePermutation;
|
|
458
|
+
const diagnostics = snapshot?.diagnostics;
|
|
459
|
+
const cssVarPrefix = snapshot?.cssVarPrefix;
|
|
460
|
+
const listing = snapshot?.listing;
|
|
461
|
+
const varianceByPath = snapshot?.varianceByPath;
|
|
462
|
+
const resolveAt = useMemo(() => {
|
|
463
|
+
if (!snapshot) return null;
|
|
464
|
+
return snapshotResolveAt(snapshot);
|
|
465
|
+
}, [
|
|
466
|
+
axes,
|
|
467
|
+
cells,
|
|
468
|
+
jointOverrides,
|
|
469
|
+
dataDefaultTuple,
|
|
470
|
+
activePermutation
|
|
471
|
+
]);
|
|
472
|
+
const providerData = useMemo(() => {
|
|
473
|
+
if (!snapshot || !resolveAt || !axes || !activeAxes) return null;
|
|
474
|
+
return {
|
|
475
|
+
activePermutation: activePermutation ?? "",
|
|
476
|
+
activeAxes,
|
|
477
|
+
axes,
|
|
478
|
+
resolved: resolveAt(activeAxes),
|
|
479
|
+
diagnostics: diagnostics ?? [],
|
|
480
|
+
cssVarPrefix: cssVarPrefix ?? "",
|
|
481
|
+
listing: listing ?? {},
|
|
482
|
+
varianceByPath: varianceByPath ?? {},
|
|
483
|
+
resolveAt,
|
|
484
|
+
permutationNameForTuple: (tuple) => tupleToName(axes, tuple)
|
|
485
|
+
};
|
|
486
|
+
}, [
|
|
487
|
+
snapshot,
|
|
488
|
+
resolveAt,
|
|
489
|
+
axes,
|
|
490
|
+
cells,
|
|
491
|
+
jointOverrides,
|
|
492
|
+
dataDefaultTuple,
|
|
493
|
+
activePermutation,
|
|
494
|
+
activeAxes,
|
|
495
|
+
diagnostics,
|
|
496
|
+
cssVarPrefix,
|
|
497
|
+
listing,
|
|
498
|
+
varianceByPath
|
|
499
|
+
]);
|
|
443
500
|
const fallback = useVirtualModuleFallback(snapshot === null);
|
|
444
|
-
return
|
|
501
|
+
return providerData ?? fallback;
|
|
445
502
|
}
|
|
446
503
|
function useVirtualModuleFallback(enabled) {
|
|
447
504
|
const contextPermutation = useActivePermutation();
|
|
@@ -459,32 +516,46 @@ function useVirtualModuleFallback(enabled) {
|
|
|
459
516
|
if (!enabled) return;
|
|
460
517
|
ensureStylesheet(tokens.css);
|
|
461
518
|
}, [enabled, tokens.css]);
|
|
462
|
-
const activeAxes =
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
519
|
+
const activeAxes = useMemo(() => {
|
|
520
|
+
return Object.keys(contextAxes).length > 0 ? { ...contextAxes } : channelGlobals.axes ?? defaultTuple$1(tokens.axes);
|
|
521
|
+
}, [
|
|
522
|
+
contextAxes,
|
|
523
|
+
channelGlobals.axes,
|
|
524
|
+
tokens.axes
|
|
525
|
+
]);
|
|
526
|
+
const activePermutation = contextPermutation || tupleToName(tokens.axes, activeAxes);
|
|
527
|
+
const resolveAt = useMemo(() => makeResolveAt({
|
|
528
|
+
axes: tokens.axes,
|
|
529
|
+
cells: tokens.cells,
|
|
530
|
+
jointOverrides: tokens.jointOverrides,
|
|
531
|
+
defaultTuple: tokens.defaultTuple
|
|
532
|
+
}), [
|
|
533
|
+
tokens.axes,
|
|
534
|
+
tokens.cells,
|
|
535
|
+
tokens.jointOverrides,
|
|
536
|
+
tokens.defaultTuple
|
|
537
|
+
]);
|
|
538
|
+
return useMemo(() => ({
|
|
466
539
|
activePermutation,
|
|
467
540
|
activeAxes,
|
|
468
541
|
axes: tokens.axes,
|
|
469
|
-
|
|
470
|
-
permutationsResolved: tokens.permutationsResolved,
|
|
471
|
-
resolved: tokens.permutationsResolved[activePermutation] ?? {},
|
|
542
|
+
resolved: resolveAt(activeAxes),
|
|
472
543
|
diagnostics: tokens.diagnostics,
|
|
473
544
|
cssVarPrefix: tokens.cssVarPrefix,
|
|
474
|
-
listing: tokens.listing
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
545
|
+
listing: tokens.listing,
|
|
546
|
+
varianceByPath: tokens.varianceByPath,
|
|
547
|
+
resolveAt,
|
|
548
|
+
permutationNameForTuple: (tuple) => tupleToName(tokens.axes, tuple)
|
|
549
|
+
}), [
|
|
550
|
+
activePermutation,
|
|
551
|
+
activeAxes,
|
|
552
|
+
tokens.axes,
|
|
553
|
+
tokens.diagnostics,
|
|
554
|
+
tokens.cssVarPrefix,
|
|
555
|
+
tokens.listing,
|
|
556
|
+
tokens.varianceByPath,
|
|
557
|
+
resolveAt
|
|
558
|
+
]);
|
|
488
559
|
}
|
|
489
560
|
/**
|
|
490
561
|
* Resolve a token's CSS var reference, preferring the authoritative name
|
|
@@ -567,15 +638,6 @@ function BorderSample({ path }) {
|
|
|
567
638
|
//#endregion
|
|
568
639
|
//#region src/internal/data-attr.ts
|
|
569
640
|
/**
|
|
570
|
-
* Produce a prefixed `data-*` attribute name when `prefix` is set, bare
|
|
571
|
-
* `data-<key>` otherwise. Mirrors `dataAttr` in `@unpunnyfuns/swatchbook-core`
|
|
572
|
-
* so block wrappers and emitted-CSS selectors stay in lockstep without
|
|
573
|
-
* blocks taking a runtime dep on core.
|
|
574
|
-
*/
|
|
575
|
-
function dataAttr(prefix, key) {
|
|
576
|
-
return prefix ? `data-${prefix}-${key}` : `data-${key}`;
|
|
577
|
-
}
|
|
578
|
-
/**
|
|
579
641
|
* Marker attribute set on every block wrapper. Retained as a stable hook
|
|
580
642
|
* for consumer-side selectors (e.g. when a host app wants to target or
|
|
581
643
|
* override block chrome without relying on hashed class names).
|
|
@@ -610,59 +672,73 @@ function themeAttrs(prefix, themeName) {
|
|
|
610
672
|
}
|
|
611
673
|
//#endregion
|
|
612
674
|
//#region src/internal/sort-tokens.ts
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
675
|
+
const NUMERIC_TYPES = new Set([
|
|
676
|
+
"dimension",
|
|
677
|
+
"duration",
|
|
678
|
+
"fontWeight",
|
|
679
|
+
"opacity",
|
|
680
|
+
"number",
|
|
681
|
+
"lineHeight"
|
|
682
|
+
]);
|
|
683
|
+
const STRING_TYPES = new Set(["fontFamily", "strokeStyle"]);
|
|
684
|
+
function computeSortKey(token) {
|
|
685
|
+
const type = token.$type;
|
|
686
|
+
if (!type) return { kind: "none" };
|
|
687
|
+
if (NUMERIC_TYPES.has(type)) {
|
|
688
|
+
const value = toMagnitude(token.$value);
|
|
689
|
+
return {
|
|
690
|
+
kind: "numeric",
|
|
691
|
+
value,
|
|
692
|
+
valid: Number.isFinite(value)
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
if (type === "color") return {
|
|
696
|
+
kind: "color",
|
|
697
|
+
key: colorKey(token.$value)
|
|
698
|
+
};
|
|
699
|
+
if (STRING_TYPES.has(type)) return {
|
|
700
|
+
kind: "string",
|
|
701
|
+
value: toDisplayable(token.$value)
|
|
702
|
+
};
|
|
703
|
+
return { kind: "none" };
|
|
704
|
+
}
|
|
627
705
|
function sortTokens(entries, options = {}) {
|
|
628
706
|
const by = options.by ?? "path";
|
|
629
707
|
const dir = options.dir ?? "asc";
|
|
630
708
|
const sign = dir === "desc" ? -1 : 1;
|
|
631
709
|
if (by === "none") return dir === "desc" ? [...entries].toReversed() : [...entries];
|
|
632
710
|
if (by === "path") return [...entries].toSorted(([a], [b]) => sign * a.localeCompare(b, void 0, { numeric: true }));
|
|
711
|
+
const keys = /* @__PURE__ */ new Map();
|
|
712
|
+
for (const [, token] of entries) keys.set(token, computeSortKey(token));
|
|
633
713
|
return [...entries].toSorted(([aPath, aTok], [bPath, bTok]) => {
|
|
634
|
-
const cmp = compareValue(aTok, bTok);
|
|
714
|
+
const cmp = compareValue(aTok, bTok, keys);
|
|
635
715
|
if (cmp !== 0) return sign * cmp;
|
|
636
716
|
return sign * aPath.localeCompare(bPath, void 0, { numeric: true });
|
|
637
717
|
});
|
|
638
718
|
}
|
|
639
|
-
function compareValue(a, b) {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
if (
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
if (
|
|
647
|
-
if (
|
|
648
|
-
if (
|
|
719
|
+
function compareValue(a, b, keys) {
|
|
720
|
+
if (a.$type !== b.$type) return String(a.$type ?? "").localeCompare(String(b.$type ?? ""));
|
|
721
|
+
const ak = keys.get(a);
|
|
722
|
+
const bk = keys.get(b);
|
|
723
|
+
if (!ak || !bk) return 0;
|
|
724
|
+
if (ak.kind !== bk.kind) return 0;
|
|
725
|
+
if (ak.kind === "numeric" && bk.kind === "numeric") {
|
|
726
|
+
if (ak.valid && bk.valid) return ak.value - bk.value;
|
|
727
|
+
if (ak.valid) return -1;
|
|
728
|
+
if (bk.valid) return 1;
|
|
649
729
|
return 0;
|
|
650
730
|
}
|
|
651
|
-
if (
|
|
652
|
-
const
|
|
653
|
-
const
|
|
654
|
-
if (!
|
|
655
|
-
if (!
|
|
656
|
-
if (!
|
|
657
|
-
if (
|
|
658
|
-
if (
|
|
659
|
-
return
|
|
660
|
-
}
|
|
661
|
-
if (type === "fontFamily" || type === "strokeStyle") {
|
|
662
|
-
const as = toDisplayable(a.$value);
|
|
663
|
-
const bs = toDisplayable(b.$value);
|
|
664
|
-
return as.localeCompare(bs, void 0, { numeric: true });
|
|
731
|
+
if (ak.kind === "color" && bk.kind === "color") {
|
|
732
|
+
const a3 = ak.key;
|
|
733
|
+
const b3 = bk.key;
|
|
734
|
+
if (!a3 && !b3) return 0;
|
|
735
|
+
if (!a3) return 1;
|
|
736
|
+
if (!b3) return -1;
|
|
737
|
+
if (a3.l !== b3.l) return a3.l - b3.l;
|
|
738
|
+
if (a3.c !== b3.c) return a3.c - b3.c;
|
|
739
|
+
return a3.h - b3.h;
|
|
665
740
|
}
|
|
741
|
+
if (ak.kind === "string" && bk.kind === "string") return ak.value.localeCompare(bk.value, void 0, { numeric: true });
|
|
666
742
|
return 0;
|
|
667
743
|
}
|
|
668
744
|
function toMagnitude(v) {
|
|
@@ -682,6 +758,14 @@ function toMagnitude(v) {
|
|
|
682
758
|
}
|
|
683
759
|
return NaN;
|
|
684
760
|
}
|
|
761
|
+
/**
|
|
762
|
+
* Coerce a possibly-null/undefined number to 0 — `coords` returns
|
|
763
|
+
* `(number | null)[]` and `noUncheckedIndexedAccess` adds `undefined`
|
|
764
|
+
* on top. `typeof` narrows the union for the comparator below.
|
|
765
|
+
*/
|
|
766
|
+
function safeNumber(v) {
|
|
767
|
+
return typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
768
|
+
}
|
|
685
769
|
function colorKey(v) {
|
|
686
770
|
if (!v || typeof v !== "object") return null;
|
|
687
771
|
try {
|
|
@@ -698,9 +782,9 @@ function colorKey(v) {
|
|
|
698
782
|
} else return null;
|
|
699
783
|
const [l, chroma, h] = new Color(source).to("oklch").coords;
|
|
700
784
|
return {
|
|
701
|
-
l:
|
|
702
|
-
c:
|
|
703
|
-
h:
|
|
785
|
+
l: safeNumber(l),
|
|
786
|
+
c: safeNumber(chroma),
|
|
787
|
+
h: safeNumber(h)
|
|
704
788
|
};
|
|
705
789
|
} catch {
|
|
706
790
|
return null;
|
|
@@ -2030,9 +2114,9 @@ function GradientPalette({ filter, caption, sortBy = "path", sortDir = "asc" })
|
|
|
2030
2114
|
* True when rendering inside Chromatic's snapshot runner. Chromatic's
|
|
2031
2115
|
* browser ships a recognisable user-agent string; checked here so
|
|
2032
2116
|
* motion-looping components can fall back to their static state for
|
|
2033
|
-
* deterministic snapshots
|
|
2034
|
-
*
|
|
2035
|
-
*
|
|
2117
|
+
* deterministic snapshots. Per-component detection rather than the
|
|
2118
|
+
* global `chromatic.prefersReducedMotion: true` parameter — that
|
|
2119
|
+
* parameter is incompatible with Chromatic's verification parser.
|
|
2036
2120
|
*/
|
|
2037
2121
|
function isChromatic() {
|
|
2038
2122
|
if (typeof navigator === "undefined") return false;
|
|
@@ -2656,7 +2740,7 @@ function StrokeStyleSample({ filter, caption, sortBy = "path", sortDir = "asc" }
|
|
|
2656
2740
|
//#region src/token-detail/internal.ts
|
|
2657
2741
|
function useTokenDetailData(path) {
|
|
2658
2742
|
const project = useProject();
|
|
2659
|
-
const { activePermutation, activeAxes, axes,
|
|
2743
|
+
const { activePermutation, activeAxes, axes, resolved, cssVarPrefix, varianceByPath, resolveAt, permutationNameForTuple } = project;
|
|
2660
2744
|
const typedResolved = resolved;
|
|
2661
2745
|
return {
|
|
2662
2746
|
token: typedResolved[path],
|
|
@@ -2664,10 +2748,11 @@ function useTokenDetailData(path) {
|
|
|
2664
2748
|
activePermutation,
|
|
2665
2749
|
activeAxes,
|
|
2666
2750
|
axes,
|
|
2667
|
-
permutations,
|
|
2668
|
-
permutationsResolved,
|
|
2669
2751
|
resolved: typedResolved,
|
|
2670
|
-
cssVarPrefix
|
|
2752
|
+
cssVarPrefix,
|
|
2753
|
+
varianceByPath,
|
|
2754
|
+
resolveAt,
|
|
2755
|
+
permutationNameForTuple
|
|
2671
2756
|
};
|
|
2672
2757
|
}
|
|
2673
2758
|
//#endregion
|
|
@@ -2792,27 +2877,30 @@ function treeHasTruncation(nodes) {
|
|
|
2792
2877
|
//#endregion
|
|
2793
2878
|
//#region src/token-detail/AxisVariance.tsx
|
|
2794
2879
|
function AxisVariance({ path }) {
|
|
2795
|
-
const { token, cssVar, axes,
|
|
2880
|
+
const { token, cssVar, axes, activeAxes, cssVarPrefix, varianceByPath, resolveAt, permutationNameForTuple } = useTokenDetailData(path);
|
|
2796
2881
|
const colorFormat = useColorFormat();
|
|
2797
2882
|
const tokenType = token?.$type;
|
|
2798
2883
|
const isColor = tokenType === "color";
|
|
2799
2884
|
const formatFn = (t) => valueFor(t, tokenType, colorFormat);
|
|
2800
2885
|
const variance = useMemo(() => {
|
|
2801
|
-
const result =
|
|
2802
|
-
return {
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2886
|
+
const result = varianceByPath[path];
|
|
2887
|
+
if (!result) return { kind: "constant" };
|
|
2888
|
+
switch (result.kind) {
|
|
2889
|
+
case "constant": return { kind: "constant" };
|
|
2890
|
+
case "single": return {
|
|
2891
|
+
kind: "one-axis",
|
|
2892
|
+
axis: result.axis,
|
|
2893
|
+
varyingAxes: result.varyingAxes
|
|
2894
|
+
};
|
|
2895
|
+
case "multi": return {
|
|
2896
|
+
kind: "multi-axis",
|
|
2897
|
+
varyingAxes: result.varyingAxes
|
|
2898
|
+
};
|
|
2899
|
+
}
|
|
2900
|
+
}, [path, varianceByPath]);
|
|
2901
|
+
if (axes.length === 0) return /* @__PURE__ */ jsx(Fragment$1, {});
|
|
2813
2902
|
if (variance.kind === "constant") {
|
|
2814
|
-
const
|
|
2815
|
-
const value = anyPermutation ? formatFn(permutationsResolved[anyPermutation.name]?.[path]) : "—";
|
|
2903
|
+
const value = formatFn(resolveAt(activeAxes)[path]);
|
|
2816
2904
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
|
|
2817
2905
|
className: "sb-token-detail__section-header",
|
|
2818
2906
|
children: "Values across axes"
|
|
@@ -2831,16 +2919,12 @@ function AxisVariance({ path }) {
|
|
|
2831
2919
|
"aria-hidden": true
|
|
2832
2920
|
}),
|
|
2833
2921
|
value,
|
|
2834
|
-
/* @__PURE__ */
|
|
2922
|
+
/* @__PURE__ */ jsx("span", {
|
|
2835
2923
|
style: {
|
|
2836
2924
|
opacity: .6,
|
|
2837
2925
|
marginLeft: 8
|
|
2838
2926
|
},
|
|
2839
|
-
children:
|
|
2840
|
-
"same across all ",
|
|
2841
|
-
permutations.length,
|
|
2842
|
-
" tuples"
|
|
2843
|
-
]
|
|
2927
|
+
children: "same across every axis"
|
|
2844
2928
|
})
|
|
2845
2929
|
]
|
|
2846
2930
|
})
|
|
@@ -2848,8 +2932,7 @@ function AxisVariance({ path }) {
|
|
|
2848
2932
|
})] });
|
|
2849
2933
|
}
|
|
2850
2934
|
if (variance.kind === "one-axis") {
|
|
2851
|
-
const axisName = variance.
|
|
2852
|
-
if (!axisName) return /* @__PURE__ */ jsx(Fragment$1, {});
|
|
2935
|
+
const axisName = variance.axis;
|
|
2853
2936
|
const axis = axes.find((a) => a.name === axisName);
|
|
2854
2937
|
if (!axis) return /* @__PURE__ */ jsx(Fragment$1, {});
|
|
2855
2938
|
const contextValues = axis.contexts.map((ctx) => {
|
|
@@ -2857,14 +2940,10 @@ function AxisVariance({ path }) {
|
|
|
2857
2940
|
...activeAxes,
|
|
2858
2941
|
[axisName]: ctx
|
|
2859
2942
|
};
|
|
2860
|
-
const name = permutations.find((t) => {
|
|
2861
|
-
const input = t.input;
|
|
2862
|
-
return Object.keys(input).every((k) => input[k] === target[k]);
|
|
2863
|
-
})?.name ?? "";
|
|
2864
2943
|
return {
|
|
2865
2944
|
ctx,
|
|
2866
|
-
themeName:
|
|
2867
|
-
value:
|
|
2945
|
+
themeName: permutationNameForTuple(target) ?? "",
|
|
2946
|
+
value: formatFn(resolveAt(target)[path])
|
|
2868
2947
|
};
|
|
2869
2948
|
});
|
|
2870
2949
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -2930,12 +3009,13 @@ function AxisVariance({ path }) {
|
|
|
2930
3009
|
className: "sb-token-detail__theme-cell",
|
|
2931
3010
|
children: row
|
|
2932
3011
|
}), colAxis.contexts.map((col) => {
|
|
2933
|
-
const
|
|
3012
|
+
const target = {
|
|
2934
3013
|
...activeAxes,
|
|
2935
3014
|
[rowAxis.name]: row,
|
|
2936
3015
|
[colAxis.name]: col
|
|
2937
|
-
}
|
|
2938
|
-
const
|
|
3016
|
+
};
|
|
3017
|
+
const name = permutationNameForTuple(target);
|
|
3018
|
+
const value = formatFn(resolveAt(target)[path]);
|
|
2939
3019
|
return /* @__PURE__ */ jsxs("td", {
|
|
2940
3020
|
className: "sb-token-detail__theme-cell",
|
|
2941
3021
|
"data-row": row,
|
|
@@ -2965,12 +3045,6 @@ function valueFor(token, $type, format) {
|
|
|
2965
3045
|
if (!token) return "—";
|
|
2966
3046
|
return formatTokenValue(token.$value, $type, format);
|
|
2967
3047
|
}
|
|
2968
|
-
function tupleName(permutations, tuple) {
|
|
2969
|
-
return permutations.find((t) => {
|
|
2970
|
-
const input = t.input;
|
|
2971
|
-
return Object.keys(input).every((k) => input[k] === tuple[k]);
|
|
2972
|
-
})?.name;
|
|
2973
|
-
}
|
|
2974
3048
|
//#endregion
|
|
2975
3049
|
//#region src/token-detail/CompositeBreakdown.tsx
|
|
2976
3050
|
function CompositeBreakdown({ path }) {
|
|
@@ -3702,6 +3776,7 @@ function buildTree(resolved, root, typeFilter) {
|
|
|
3702
3776
|
let node = rootNode;
|
|
3703
3777
|
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
3704
3778
|
const seg = segments[i];
|
|
3779
|
+
if (seg === void 0) continue;
|
|
3705
3780
|
const prefix = [...rootSegments, ...segments.slice(0, i + 1)].join(".");
|
|
3706
3781
|
let child = node.children.find((c) => c.kind === "group" && c.segment === seg);
|
|
3707
3782
|
if (!child) {
|