@unpunnyfuns/swatchbook-blocks 0.65.0 → 0.66.1
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 +25 -13
- package/dist/index.mjs +309 -245
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +124 -126
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -166,6 +166,7 @@ let snapshot = {
|
|
|
166
166
|
diagnostics: [],
|
|
167
167
|
css: "",
|
|
168
168
|
cssVarPrefix: "",
|
|
169
|
+
indicators: {},
|
|
169
170
|
listing: {},
|
|
170
171
|
tokenGraph: {
|
|
171
172
|
nodes: {},
|
|
@@ -185,6 +186,7 @@ function applyPatch(patch) {
|
|
|
185
186
|
diagnostics: patch.diagnostics ?? snapshot.diagnostics,
|
|
186
187
|
css: patch.css ?? snapshot.css,
|
|
187
188
|
cssVarPrefix: patch.cssVarPrefix ?? snapshot.cssVarPrefix,
|
|
189
|
+
indicators: patch.indicators ?? snapshot.indicators,
|
|
188
190
|
listing: patch.listing ?? snapshot.listing,
|
|
189
191
|
tokenGraph: patch.tokenGraph ?? snapshot.tokenGraph,
|
|
190
192
|
defaultTuple: patch.defaultTuple ?? snapshot.defaultTuple,
|
|
@@ -269,6 +271,7 @@ function useProject() {
|
|
|
269
271
|
const activeTheme = snapshot?.activeTheme;
|
|
270
272
|
const diagnostics = snapshot?.diagnostics;
|
|
271
273
|
const cssVarPrefix = snapshot?.cssVarPrefix;
|
|
274
|
+
const indicators = snapshot?.indicators;
|
|
272
275
|
const listing = snapshot?.listing;
|
|
273
276
|
const tokenGraph = snapshot?.tokenGraph;
|
|
274
277
|
const resolveAt = useMemo(() => {
|
|
@@ -285,6 +288,7 @@ function useProject() {
|
|
|
285
288
|
resolved: resolveAt(activeAxes),
|
|
286
289
|
diagnostics: diagnostics ?? [],
|
|
287
290
|
cssVarPrefix: cssVarPrefix ?? "",
|
|
291
|
+
indicators: indicators ?? {},
|
|
288
292
|
listing: listing ?? {},
|
|
289
293
|
varianceByPath: derivedVarianceByPath,
|
|
290
294
|
resolveAt
|
|
@@ -297,6 +301,7 @@ function useProject() {
|
|
|
297
301
|
activeAxes,
|
|
298
302
|
diagnostics,
|
|
299
303
|
cssVarPrefix,
|
|
304
|
+
indicators,
|
|
300
305
|
listing,
|
|
301
306
|
derivedVarianceByPath,
|
|
302
307
|
tokenGraph
|
|
@@ -330,6 +335,7 @@ function useVirtualModuleFallback(enabled) {
|
|
|
330
335
|
resolved: resolveAt(activeAxes),
|
|
331
336
|
diagnostics: tokens.diagnostics,
|
|
332
337
|
cssVarPrefix: tokens.cssVarPrefix,
|
|
338
|
+
indicators: tokens.indicators,
|
|
333
339
|
listing: tokens.listing,
|
|
334
340
|
varianceByPath: fallbackVarianceByPath,
|
|
335
341
|
resolveAt
|
|
@@ -339,6 +345,7 @@ function useVirtualModuleFallback(enabled) {
|
|
|
339
345
|
tokens.axes,
|
|
340
346
|
tokens.diagnostics,
|
|
341
347
|
tokens.cssVarPrefix,
|
|
348
|
+
tokens.indicators,
|
|
342
349
|
tokens.listing,
|
|
343
350
|
fallbackVarianceByPath,
|
|
344
351
|
resolveAt
|
|
@@ -760,6 +767,273 @@ function ColorPalette({ filter, groupBy, caption, sortBy = "path", sortDir = "as
|
|
|
760
767
|
});
|
|
761
768
|
}
|
|
762
769
|
//#endregion
|
|
770
|
+
//#region src/indicators/resolve.ts
|
|
771
|
+
/** Established-on set; `description` and `composes` are opt-in. */
|
|
772
|
+
const DEFAULT_INDICATORS = {
|
|
773
|
+
alias: true,
|
|
774
|
+
variance: true,
|
|
775
|
+
gamut: true,
|
|
776
|
+
deprecation: true,
|
|
777
|
+
description: false,
|
|
778
|
+
composes: false
|
|
779
|
+
};
|
|
780
|
+
/**
|
|
781
|
+
* Normalize an `IndicatorsProp` into a full enabled-map. Precedence
|
|
782
|
+
* (lowest→highest): `DEFAULT_INDICATORS` → `baseline` (the project-wide
|
|
783
|
+
* `config.indicators` default) → per-block `prop`. An explicit boolean
|
|
784
|
+
* `prop` (`true`/`false`) forces every key on/off and wins over the
|
|
785
|
+
* baseline; an object `prop` overlays on top of defaults+baseline; an
|
|
786
|
+
* absent `prop` leaves the result at defaults overlaid with baseline.
|
|
787
|
+
*/
|
|
788
|
+
function resolveIndicators(prop, baseline) {
|
|
789
|
+
if (prop === true) return {
|
|
790
|
+
alias: true,
|
|
791
|
+
variance: true,
|
|
792
|
+
gamut: true,
|
|
793
|
+
deprecation: true,
|
|
794
|
+
description: true,
|
|
795
|
+
composes: true
|
|
796
|
+
};
|
|
797
|
+
if (prop === false) return {
|
|
798
|
+
alias: false,
|
|
799
|
+
variance: false,
|
|
800
|
+
gamut: false,
|
|
801
|
+
deprecation: false,
|
|
802
|
+
description: false,
|
|
803
|
+
composes: false
|
|
804
|
+
};
|
|
805
|
+
return {
|
|
806
|
+
...DEFAULT_INDICATORS,
|
|
807
|
+
...baseline,
|
|
808
|
+
...prop
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
//#endregion
|
|
812
|
+
//#region src/indicators/RowIndicators.tsx
|
|
813
|
+
function relativeLabel(path, root) {
|
|
814
|
+
if (root && path.startsWith(`${root}.`)) return path.slice(root.length + 1);
|
|
815
|
+
return path;
|
|
816
|
+
}
|
|
817
|
+
const COMPOSITE_TYPES = new Set([
|
|
818
|
+
"border",
|
|
819
|
+
"typography",
|
|
820
|
+
"transition",
|
|
821
|
+
"gradient",
|
|
822
|
+
"shadow"
|
|
823
|
+
]);
|
|
824
|
+
function compositeFieldCount(token) {
|
|
825
|
+
if (!token.$type || !COMPOSITE_TYPES.has(token.$type)) return void 0;
|
|
826
|
+
const v = token.$value;
|
|
827
|
+
if (Array.isArray(v)) return v.length > 0 ? v.length : void 0;
|
|
828
|
+
if (v !== null && typeof v === "object") {
|
|
829
|
+
const n = Object.keys(v).length;
|
|
830
|
+
return n > 0 ? n : void 0;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* The forward alias chain for one row. Full chain in `aria-label`; visually
|
|
835
|
+
* capped to first … last beyond two hops (no width measurement). Each shown
|
|
836
|
+
* node navigates when in view, else renders as plain text.
|
|
837
|
+
*/
|
|
838
|
+
function ForwardChain({ chain, root, canReference, onReferenceClick }) {
|
|
839
|
+
const full = chain.map((p) => relativeLabel(p, root)).join(" → ");
|
|
840
|
+
const capped = chain.length > 2;
|
|
841
|
+
const shown = capped ? [chain[0], chain[chain.length - 1]] : [...chain];
|
|
842
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
843
|
+
className: "sb-indicator__alias-forward",
|
|
844
|
+
"data-testid": "row-indicator-alias-forward",
|
|
845
|
+
"aria-label": `aliases ${full}`,
|
|
846
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
847
|
+
className: "sb-indicator__alias-arrow",
|
|
848
|
+
"aria-hidden": true,
|
|
849
|
+
children: "→"
|
|
850
|
+
}), shown.map((target, i) => {
|
|
851
|
+
const label = relativeLabel(target, root);
|
|
852
|
+
return /* @__PURE__ */ jsxs("span", { children: [canReference(target) ? /* @__PURE__ */ jsx("button", {
|
|
853
|
+
type: "button",
|
|
854
|
+
className: "sb-indicator__alias-node",
|
|
855
|
+
"data-testid": "alias-node",
|
|
856
|
+
"aria-label": target,
|
|
857
|
+
onClick: (e) => {
|
|
858
|
+
e.stopPropagation();
|
|
859
|
+
onReferenceClick(target);
|
|
860
|
+
},
|
|
861
|
+
children: label
|
|
862
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
863
|
+
className: "sb-indicator__alias-node sb-indicator__alias-node--offview",
|
|
864
|
+
"data-testid": "alias-node",
|
|
865
|
+
title: "outside current view",
|
|
866
|
+
children: label
|
|
867
|
+
}), capped && i === 0 ? /* @__PURE__ */ jsxs("span", {
|
|
868
|
+
className: "sb-indicator__alias-arrow",
|
|
869
|
+
"aria-hidden": true,
|
|
870
|
+
children: [
|
|
871
|
+
" ",
|
|
872
|
+
"→ … →",
|
|
873
|
+
" "
|
|
874
|
+
]
|
|
875
|
+
}) : i < shown.length - 1 ? /* @__PURE__ */ jsxs("span", {
|
|
876
|
+
className: "sb-indicator__alias-arrow",
|
|
877
|
+
"aria-hidden": true,
|
|
878
|
+
children: [
|
|
879
|
+
" ",
|
|
880
|
+
"→",
|
|
881
|
+
" "
|
|
882
|
+
]
|
|
883
|
+
}) : null] }, target);
|
|
884
|
+
})]
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
function DeprecatedBadge({ deprecated }) {
|
|
888
|
+
const label = typeof deprecated === "string" ? `deprecated: ${deprecated}` : "deprecated";
|
|
889
|
+
return /* @__PURE__ */ jsx("span", {
|
|
890
|
+
className: "sb-indicator__deprecated",
|
|
891
|
+
"data-testid": "row-indicator-deprecated",
|
|
892
|
+
title: label,
|
|
893
|
+
"aria-label": label,
|
|
894
|
+
children: "deprecated"
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
function VarianceBadge({ variance }) {
|
|
898
|
+
if (variance.kind === "constant") return null;
|
|
899
|
+
const axes = variance.varyingAxes;
|
|
900
|
+
const label = variance.kind === "single" ? variance.axis : `${axes.length} axes`;
|
|
901
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
902
|
+
className: "sb-indicator__variance",
|
|
903
|
+
"data-testid": "row-indicator-variance",
|
|
904
|
+
"aria-label": `varies by ${axes.join(", ")}`,
|
|
905
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
906
|
+
className: "sb-indicator__variance-glyph",
|
|
907
|
+
"aria-hidden": true,
|
|
908
|
+
children: "⊹"
|
|
909
|
+
}), label]
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
function ReverseCount({ referents, canReference, onReferenceClick }) {
|
|
913
|
+
const [open, setOpen] = useState(false);
|
|
914
|
+
const wrapRef = useRef(null);
|
|
915
|
+
const count = referents.length;
|
|
916
|
+
const single = count === 1;
|
|
917
|
+
useEffect(() => {
|
|
918
|
+
if (single || !open) return;
|
|
919
|
+
(wrapRef.current?.querySelector("button[role=\"menuitem\"]:not(:disabled)"))?.focus();
|
|
920
|
+
const handlePointerDown = (e) => {
|
|
921
|
+
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
922
|
+
};
|
|
923
|
+
document.addEventListener("pointerdown", handlePointerDown);
|
|
924
|
+
return () => {
|
|
925
|
+
document.removeEventListener("pointerdown", handlePointerDown);
|
|
926
|
+
};
|
|
927
|
+
}, [open, single]);
|
|
928
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
929
|
+
ref: wrapRef,
|
|
930
|
+
className: "sb-indicator__reverse-wrap",
|
|
931
|
+
onKeyDown: (e) => {
|
|
932
|
+
if (e.key === "Escape") setOpen(false);
|
|
933
|
+
},
|
|
934
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
935
|
+
type: "button",
|
|
936
|
+
className: "sb-indicator__alias-reverse",
|
|
937
|
+
"data-testid": "row-indicator-alias-reverse",
|
|
938
|
+
"aria-label": `referenced by ${count} ${count === 1 ? "token" : "tokens"}`,
|
|
939
|
+
"aria-haspopup": single ? void 0 : "menu",
|
|
940
|
+
"aria-expanded": single ? void 0 : open,
|
|
941
|
+
onClick: (e) => {
|
|
942
|
+
e.stopPropagation();
|
|
943
|
+
if (single) onReferenceClick(referents[0]);
|
|
944
|
+
else setOpen((v) => !v);
|
|
945
|
+
},
|
|
946
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
947
|
+
className: "sb-indicator__alias-arrow",
|
|
948
|
+
"aria-hidden": true,
|
|
949
|
+
children: "←"
|
|
950
|
+
}), count]
|
|
951
|
+
}), !single && open && /* @__PURE__ */ jsx("ul", {
|
|
952
|
+
className: "sb-indicator__reverse-menu",
|
|
953
|
+
role: "menu",
|
|
954
|
+
children: referents.map((ref) => /* @__PURE__ */ jsx("li", {
|
|
955
|
+
role: "none",
|
|
956
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
957
|
+
type: "button",
|
|
958
|
+
role: "menuitem",
|
|
959
|
+
className: "sb-indicator__reverse-item",
|
|
960
|
+
disabled: !canReference(ref),
|
|
961
|
+
title: canReference(ref) ? void 0 : "outside current view",
|
|
962
|
+
onClick: (e) => {
|
|
963
|
+
e.stopPropagation();
|
|
964
|
+
setOpen(false);
|
|
965
|
+
onReferenceClick(ref);
|
|
966
|
+
},
|
|
967
|
+
children: ref
|
|
968
|
+
})
|
|
969
|
+
}, ref))
|
|
970
|
+
})]
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
/** Per-row indicator strip: alias references, variance, gamut, deprecation. */
|
|
974
|
+
function RowIndicators(props) {
|
|
975
|
+
const { token, root, variance, colorFormat, canReference, onReferenceClick } = props;
|
|
976
|
+
const en = props.enabled ?? resolveIndicators(void 0);
|
|
977
|
+
const aliasChain = Array.isArray(token.aliasChain) && token.aliasChain.length > 0 ? token.aliasChain : void 0;
|
|
978
|
+
const reverseCount = Array.isArray(token.aliasedBy) && token.aliasedBy.length > 0 ? token.aliasedBy.length : 0;
|
|
979
|
+
const isVarying = variance !== void 0 && variance.kind !== "constant";
|
|
980
|
+
const outOfGamut = token.$type === "color" && (formatColor(token.$value, colorFormat)?.outOfGamut ?? false);
|
|
981
|
+
const deprecated = token.$deprecated;
|
|
982
|
+
const isDeprecated = deprecated === true || typeof deprecated === "string" && deprecated.length > 0;
|
|
983
|
+
const description = typeof token.$description === "string" && token.$description.length > 0 ? token.$description : void 0;
|
|
984
|
+
const composesCount = en.composes ? compositeFieldCount(token) : void 0;
|
|
985
|
+
const showDeprecated = en.deprecation && isDeprecated;
|
|
986
|
+
const showForward = en.alias && aliasChain !== void 0;
|
|
987
|
+
const showReverse = en.alias && reverseCount > 0;
|
|
988
|
+
const showVariance = en.variance && isVarying;
|
|
989
|
+
const showGamut = en.gamut && outOfGamut;
|
|
990
|
+
const showDescription = en.description && description !== void 0;
|
|
991
|
+
const showComposes = composesCount !== void 0;
|
|
992
|
+
if (!showDeprecated && !showForward && !showReverse && !showVariance && !showGamut && !showDescription && !showComposes) return null;
|
|
993
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
994
|
+
className: "sb-indicator__indicators",
|
|
995
|
+
children: [
|
|
996
|
+
showDeprecated && deprecated !== void 0 && /* @__PURE__ */ jsx(DeprecatedBadge, { deprecated }),
|
|
997
|
+
showForward && aliasChain && /* @__PURE__ */ jsx(ForwardChain, {
|
|
998
|
+
chain: aliasChain,
|
|
999
|
+
root,
|
|
1000
|
+
canReference,
|
|
1001
|
+
onReferenceClick
|
|
1002
|
+
}),
|
|
1003
|
+
showReverse && token.aliasedBy && /* @__PURE__ */ jsx(ReverseCount, {
|
|
1004
|
+
referents: token.aliasedBy,
|
|
1005
|
+
canReference,
|
|
1006
|
+
onReferenceClick
|
|
1007
|
+
}),
|
|
1008
|
+
showComposes && composesCount !== void 0 && /* @__PURE__ */ jsxs("span", {
|
|
1009
|
+
className: "sb-indicator__composes",
|
|
1010
|
+
"data-testid": "row-indicator-composes",
|
|
1011
|
+
title: `composes ${composesCount} parts`,
|
|
1012
|
+
"aria-label": `composes ${composesCount} parts`,
|
|
1013
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1014
|
+
className: "sb-indicator__composes-glyph",
|
|
1015
|
+
"aria-hidden": true,
|
|
1016
|
+
children: "⊞"
|
|
1017
|
+
}), composesCount]
|
|
1018
|
+
}),
|
|
1019
|
+
showVariance && variance && /* @__PURE__ */ jsx(VarianceBadge, { variance }),
|
|
1020
|
+
showGamut && /* @__PURE__ */ jsx("span", {
|
|
1021
|
+
className: "sb-indicator__gamut",
|
|
1022
|
+
title: "Out of sRGB gamut for this format",
|
|
1023
|
+
"aria-label": "out of gamut",
|
|
1024
|
+
children: "⚠"
|
|
1025
|
+
}),
|
|
1026
|
+
showDescription && description !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
1027
|
+
className: "sb-indicator__description",
|
|
1028
|
+
"data-testid": "row-indicator-description",
|
|
1029
|
+
title: description,
|
|
1030
|
+
"aria-label": `description: ${description}`,
|
|
1031
|
+
children: "ⓘ"
|
|
1032
|
+
})
|
|
1033
|
+
]
|
|
1034
|
+
});
|
|
1035
|
+
}
|
|
1036
|
+
//#endregion
|
|
763
1037
|
//#region src/internal/CopyButton.tsx
|
|
764
1038
|
/**
|
|
765
1039
|
* Copy the given string to the clipboard and briefly surface a "Copied!"
|
|
@@ -862,11 +1136,16 @@ function usePersistedState(key, initial) {
|
|
|
862
1136
|
}
|
|
863
1137
|
//#endregion
|
|
864
1138
|
//#region src/ColorTable.tsx
|
|
1139
|
+
const NOOP_REFERENCE = () => {};
|
|
865
1140
|
const BASE_LABEL = "base";
|
|
866
1141
|
const COLUMN_COUNT = 6;
|
|
867
|
-
function ColorTable({ filter, caption, sortBy = "path", sortDir = "asc", searchable = true, onSelect, variants, id }) {
|
|
868
|
-
const { resolved, activeTheme, activeAxes, cssVarPrefix, listing } = useProject();
|
|
1142
|
+
function ColorTable({ filter, caption, sortBy = "path", sortDir = "asc", searchable = true, onSelect, variants, id, indicators }) {
|
|
1143
|
+
const { resolved, activeTheme, activeAxes, cssVarPrefix, listing, varianceByPath } = useProject();
|
|
869
1144
|
const colorFormat = useColorFormat();
|
|
1145
|
+
const enabledIndicators = useMemo(() => ({
|
|
1146
|
+
...resolveIndicators(indicators),
|
|
1147
|
+
gamut: false
|
|
1148
|
+
}), [indicators]);
|
|
870
1149
|
const blockKey = useBlockKey("ColorTable", [
|
|
871
1150
|
filter,
|
|
872
1151
|
caption,
|
|
@@ -900,6 +1179,8 @@ function ColorTable({ filter, caption, sortBy = "path", sortDir = "asc", searcha
|
|
|
900
1179
|
const variant = {
|
|
901
1180
|
label: match?.label ?? BASE_LABEL,
|
|
902
1181
|
path,
|
|
1182
|
+
token,
|
|
1183
|
+
variance: varianceByPath[path],
|
|
903
1184
|
cssVar: resolveCssVar(path, projectFields),
|
|
904
1185
|
value: active.value,
|
|
905
1186
|
outOfGamut: active.outOfGamut,
|
|
@@ -933,6 +1214,7 @@ function ColorTable({ filter, caption, sortBy = "path", sortDir = "asc", searcha
|
|
|
933
1214
|
resolved,
|
|
934
1215
|
listing,
|
|
935
1216
|
cssVarPrefix,
|
|
1217
|
+
varianceByPath,
|
|
936
1218
|
filter,
|
|
937
1219
|
sortBy,
|
|
938
1220
|
sortDir,
|
|
@@ -1014,8 +1296,11 @@ function ColorTable({ filter, caption, sortBy = "path", sortDir = "asc", searcha
|
|
|
1014
1296
|
children: "CSS var"
|
|
1015
1297
|
}),
|
|
1016
1298
|
/* @__PURE__ */ jsx("th", {
|
|
1017
|
-
className: "sb-color-table__th",
|
|
1018
|
-
children: "
|
|
1299
|
+
className: "sb-color-table__th sb-color-table__th--refs",
|
|
1300
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
1301
|
+
className: "sb-color-table__sr-only",
|
|
1302
|
+
children: "References and status"
|
|
1303
|
+
})
|
|
1019
1304
|
}),
|
|
1020
1305
|
/* @__PURE__ */ jsx("th", {
|
|
1021
1306
|
className: "sb-color-table__th sb-color-table__th--expand",
|
|
@@ -1039,6 +1324,8 @@ function ColorTable({ filter, caption, sortBy = "path", sortDir = "asc", searcha
|
|
|
1039
1324
|
expanded: expandedByBase.has(group.base),
|
|
1040
1325
|
onToggleExpand: toggleExpand,
|
|
1041
1326
|
onSelectVariant: selectVariant,
|
|
1327
|
+
enabled: enabledIndicators,
|
|
1328
|
+
colorFormat,
|
|
1042
1329
|
...onSelect !== void 0 && { onSelect }
|
|
1043
1330
|
}, group.base))] })
|
|
1044
1331
|
]
|
|
@@ -1046,10 +1333,12 @@ function ColorTable({ filter, caption, sortBy = "path", sortDir = "asc", searcha
|
|
|
1046
1333
|
})]
|
|
1047
1334
|
});
|
|
1048
1335
|
}
|
|
1049
|
-
const GroupRow = memo(function GroupRow({ group, selectedLabel, expanded, onToggleExpand, onSelectVariant, onSelect }) {
|
|
1336
|
+
const GroupRow = memo(function GroupRow({ group, selectedLabel, expanded, onToggleExpand, onSelectVariant, onSelect, enabled, colorFormat }) {
|
|
1050
1337
|
const multi = group.variants.length > 1;
|
|
1051
1338
|
const active = group.variants.find((v) => v.label === selectedLabel) ?? group.variants[0];
|
|
1052
1339
|
const nameText = multi ? group.base : active.path;
|
|
1340
|
+
const dep = active.token.$deprecated;
|
|
1341
|
+
const isDeprecated = dep === true || typeof dep === "string" && dep.length > 0;
|
|
1053
1342
|
const handleRowActivate = () => {
|
|
1054
1343
|
if (onSelect) onSelect(active.path);
|
|
1055
1344
|
else onToggleExpand(group.base);
|
|
@@ -1080,6 +1369,7 @@ const GroupRow = memo(function GroupRow({ group, selectedLabel, expanded, onTogg
|
|
|
1080
1369
|
}),
|
|
1081
1370
|
/* @__PURE__ */ jsxs("td", {
|
|
1082
1371
|
className: cx("sb-color-table__td", "sb-color-table__path"),
|
|
1372
|
+
"data-deprecated": enabled.deprecation && isDeprecated ? "true" : void 0,
|
|
1083
1373
|
children: [/* @__PURE__ */ jsx("span", {
|
|
1084
1374
|
className: "sb-color-table__path-text",
|
|
1085
1375
|
children: nameText
|
|
@@ -1114,14 +1404,16 @@ const GroupRow = memo(function GroupRow({ group, selectedLabel, expanded, onTogg
|
|
|
1114
1404
|
label: `Copy CSS var ${active.cssVar}`
|
|
1115
1405
|
}),
|
|
1116
1406
|
/* @__PURE__ */ jsx("td", {
|
|
1117
|
-
className: "sb-color-table__td sb-color-
|
|
1118
|
-
children:
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1407
|
+
className: "sb-color-table__td sb-color-table__refs",
|
|
1408
|
+
children: /* @__PURE__ */ jsx(RowIndicators, {
|
|
1409
|
+
path: active.path,
|
|
1410
|
+
token: active.token,
|
|
1411
|
+
root: void 0,
|
|
1412
|
+
variance: active.variance,
|
|
1413
|
+
colorFormat,
|
|
1414
|
+
canReference: () => false,
|
|
1415
|
+
onReferenceClick: NOOP_REFERENCE,
|
|
1416
|
+
enabled
|
|
1125
1417
|
})
|
|
1126
1418
|
}),
|
|
1127
1419
|
/* @__PURE__ */ jsx("td", {
|
|
@@ -3640,234 +3932,6 @@ function isInView(path, ctx) {
|
|
|
3640
3932
|
return true;
|
|
3641
3933
|
}
|
|
3642
3934
|
//#endregion
|
|
3643
|
-
//#region src/indicators/resolve.ts
|
|
3644
|
-
/** Established-on set; `description` is opt-in. */
|
|
3645
|
-
const DEFAULT_INDICATORS = {
|
|
3646
|
-
alias: true,
|
|
3647
|
-
variance: true,
|
|
3648
|
-
gamut: true,
|
|
3649
|
-
deprecation: true,
|
|
3650
|
-
description: false
|
|
3651
|
-
};
|
|
3652
|
-
/** Normalize an `IndicatorsProp` into a full enabled-map by layering over the defaults. */
|
|
3653
|
-
function resolveIndicators(prop) {
|
|
3654
|
-
if (prop === void 0) return { ...DEFAULT_INDICATORS };
|
|
3655
|
-
if (prop === true) return {
|
|
3656
|
-
alias: true,
|
|
3657
|
-
variance: true,
|
|
3658
|
-
gamut: true,
|
|
3659
|
-
deprecation: true,
|
|
3660
|
-
description: true
|
|
3661
|
-
};
|
|
3662
|
-
if (prop === false) return {
|
|
3663
|
-
alias: false,
|
|
3664
|
-
variance: false,
|
|
3665
|
-
gamut: false,
|
|
3666
|
-
deprecation: false,
|
|
3667
|
-
description: false
|
|
3668
|
-
};
|
|
3669
|
-
return {
|
|
3670
|
-
...DEFAULT_INDICATORS,
|
|
3671
|
-
...prop
|
|
3672
|
-
};
|
|
3673
|
-
}
|
|
3674
|
-
//#endregion
|
|
3675
|
-
//#region src/indicators/RowIndicators.tsx
|
|
3676
|
-
function relativeLabel(path, root) {
|
|
3677
|
-
if (root && path.startsWith(`${root}.`)) return path.slice(root.length + 1);
|
|
3678
|
-
return path;
|
|
3679
|
-
}
|
|
3680
|
-
/**
|
|
3681
|
-
* The forward alias chain for one row. Full chain in `aria-label`; visually
|
|
3682
|
-
* capped to first … last beyond two hops (no width measurement). Each shown
|
|
3683
|
-
* node navigates when in view, else renders as plain text.
|
|
3684
|
-
*/
|
|
3685
|
-
function ForwardChain({ chain, root, canReference, onReferenceClick }) {
|
|
3686
|
-
const full = chain.map((p) => relativeLabel(p, root)).join(" → ");
|
|
3687
|
-
const capped = chain.length > 2;
|
|
3688
|
-
const shown = capped ? [chain[0], chain[chain.length - 1]] : [...chain];
|
|
3689
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
3690
|
-
className: "sb-indicator__alias-forward",
|
|
3691
|
-
"data-testid": "row-indicator-alias-forward",
|
|
3692
|
-
"aria-label": `aliases ${full}`,
|
|
3693
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3694
|
-
className: "sb-indicator__alias-arrow",
|
|
3695
|
-
"aria-hidden": true,
|
|
3696
|
-
children: "→"
|
|
3697
|
-
}), shown.map((target, i) => {
|
|
3698
|
-
const label = relativeLabel(target, root);
|
|
3699
|
-
return /* @__PURE__ */ jsxs("span", { children: [canReference(target) ? /* @__PURE__ */ jsx("button", {
|
|
3700
|
-
type: "button",
|
|
3701
|
-
className: "sb-indicator__alias-node",
|
|
3702
|
-
"data-testid": "alias-node",
|
|
3703
|
-
"aria-label": target,
|
|
3704
|
-
onClick: (e) => {
|
|
3705
|
-
e.stopPropagation();
|
|
3706
|
-
onReferenceClick(target);
|
|
3707
|
-
},
|
|
3708
|
-
children: label
|
|
3709
|
-
}) : /* @__PURE__ */ jsx("span", {
|
|
3710
|
-
className: "sb-indicator__alias-node sb-indicator__alias-node--offview",
|
|
3711
|
-
"data-testid": "alias-node",
|
|
3712
|
-
title: "outside current view",
|
|
3713
|
-
children: label
|
|
3714
|
-
}), capped && i === 0 ? /* @__PURE__ */ jsxs("span", {
|
|
3715
|
-
className: "sb-indicator__alias-arrow",
|
|
3716
|
-
"aria-hidden": true,
|
|
3717
|
-
children: [
|
|
3718
|
-
" ",
|
|
3719
|
-
"→ … →",
|
|
3720
|
-
" "
|
|
3721
|
-
]
|
|
3722
|
-
}) : i < shown.length - 1 ? /* @__PURE__ */ jsxs("span", {
|
|
3723
|
-
className: "sb-indicator__alias-arrow",
|
|
3724
|
-
"aria-hidden": true,
|
|
3725
|
-
children: [
|
|
3726
|
-
" ",
|
|
3727
|
-
"→",
|
|
3728
|
-
" "
|
|
3729
|
-
]
|
|
3730
|
-
}) : null] }, target);
|
|
3731
|
-
})]
|
|
3732
|
-
});
|
|
3733
|
-
}
|
|
3734
|
-
function DeprecatedBadge({ deprecated }) {
|
|
3735
|
-
const label = typeof deprecated === "string" ? `deprecated: ${deprecated}` : "deprecated";
|
|
3736
|
-
return /* @__PURE__ */ jsx("span", {
|
|
3737
|
-
className: "sb-indicator__deprecated",
|
|
3738
|
-
"data-testid": "row-indicator-deprecated",
|
|
3739
|
-
title: label,
|
|
3740
|
-
"aria-label": label,
|
|
3741
|
-
children: "deprecated"
|
|
3742
|
-
});
|
|
3743
|
-
}
|
|
3744
|
-
function VarianceBadge({ variance }) {
|
|
3745
|
-
if (variance.kind === "constant") return null;
|
|
3746
|
-
const axes = variance.varyingAxes;
|
|
3747
|
-
const label = variance.kind === "single" ? variance.axis : `${axes.length} axes`;
|
|
3748
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
3749
|
-
className: "sb-indicator__variance",
|
|
3750
|
-
"data-testid": "row-indicator-variance",
|
|
3751
|
-
"aria-label": `varies by ${axes.join(", ")}`,
|
|
3752
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3753
|
-
className: "sb-indicator__variance-glyph",
|
|
3754
|
-
"aria-hidden": true,
|
|
3755
|
-
children: "⊹"
|
|
3756
|
-
}), label]
|
|
3757
|
-
});
|
|
3758
|
-
}
|
|
3759
|
-
function ReverseCount({ referents, canReference, onReferenceClick }) {
|
|
3760
|
-
const [open, setOpen] = useState(false);
|
|
3761
|
-
const wrapRef = useRef(null);
|
|
3762
|
-
const count = referents.length;
|
|
3763
|
-
const single = count === 1;
|
|
3764
|
-
useEffect(() => {
|
|
3765
|
-
if (single || !open) return;
|
|
3766
|
-
(wrapRef.current?.querySelector("button[role=\"menuitem\"]:not(:disabled)"))?.focus();
|
|
3767
|
-
const handlePointerDown = (e) => {
|
|
3768
|
-
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
3769
|
-
};
|
|
3770
|
-
document.addEventListener("pointerdown", handlePointerDown);
|
|
3771
|
-
return () => {
|
|
3772
|
-
document.removeEventListener("pointerdown", handlePointerDown);
|
|
3773
|
-
};
|
|
3774
|
-
}, [open, single]);
|
|
3775
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
3776
|
-
ref: wrapRef,
|
|
3777
|
-
className: "sb-indicator__reverse-wrap",
|
|
3778
|
-
onKeyDown: (e) => {
|
|
3779
|
-
if (e.key === "Escape") setOpen(false);
|
|
3780
|
-
},
|
|
3781
|
-
children: [/* @__PURE__ */ jsxs("button", {
|
|
3782
|
-
type: "button",
|
|
3783
|
-
className: "sb-indicator__alias-reverse",
|
|
3784
|
-
"data-testid": "row-indicator-alias-reverse",
|
|
3785
|
-
"aria-label": `referenced by ${count} ${count === 1 ? "token" : "tokens"}`,
|
|
3786
|
-
"aria-haspopup": single ? void 0 : "menu",
|
|
3787
|
-
"aria-expanded": single ? void 0 : open,
|
|
3788
|
-
onClick: (e) => {
|
|
3789
|
-
e.stopPropagation();
|
|
3790
|
-
if (single) onReferenceClick(referents[0]);
|
|
3791
|
-
else setOpen((v) => !v);
|
|
3792
|
-
},
|
|
3793
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3794
|
-
className: "sb-indicator__alias-arrow",
|
|
3795
|
-
"aria-hidden": true,
|
|
3796
|
-
children: "←"
|
|
3797
|
-
}), count]
|
|
3798
|
-
}), !single && open && /* @__PURE__ */ jsx("ul", {
|
|
3799
|
-
className: "sb-indicator__reverse-menu",
|
|
3800
|
-
role: "menu",
|
|
3801
|
-
children: referents.map((ref) => /* @__PURE__ */ jsx("li", {
|
|
3802
|
-
role: "none",
|
|
3803
|
-
children: /* @__PURE__ */ jsx("button", {
|
|
3804
|
-
type: "button",
|
|
3805
|
-
role: "menuitem",
|
|
3806
|
-
className: "sb-indicator__reverse-item",
|
|
3807
|
-
disabled: !canReference(ref),
|
|
3808
|
-
title: canReference(ref) ? void 0 : "outside current view",
|
|
3809
|
-
onClick: (e) => {
|
|
3810
|
-
e.stopPropagation();
|
|
3811
|
-
setOpen(false);
|
|
3812
|
-
onReferenceClick(ref);
|
|
3813
|
-
},
|
|
3814
|
-
children: ref
|
|
3815
|
-
})
|
|
3816
|
-
}, ref))
|
|
3817
|
-
})]
|
|
3818
|
-
});
|
|
3819
|
-
}
|
|
3820
|
-
/** Per-row indicator strip: alias references, variance, gamut, deprecation. */
|
|
3821
|
-
function RowIndicators(props) {
|
|
3822
|
-
const { token, root, variance, colorFormat, canReference, onReferenceClick } = props;
|
|
3823
|
-
const en = props.enabled ?? resolveIndicators(void 0);
|
|
3824
|
-
const aliasChain = Array.isArray(token.aliasChain) && token.aliasChain.length > 0 ? token.aliasChain : void 0;
|
|
3825
|
-
const reverseCount = Array.isArray(token.aliasedBy) && token.aliasedBy.length > 0 ? token.aliasedBy.length : 0;
|
|
3826
|
-
const isVarying = variance !== void 0 && variance.kind !== "constant";
|
|
3827
|
-
const outOfGamut = token.$type === "color" && (formatColor(token.$value, colorFormat)?.outOfGamut ?? false);
|
|
3828
|
-
const deprecated = token.$deprecated;
|
|
3829
|
-
const isDeprecated = deprecated === true || typeof deprecated === "string" && deprecated.length > 0;
|
|
3830
|
-
const description = typeof token.$description === "string" && token.$description.length > 0 ? token.$description : void 0;
|
|
3831
|
-
const showDeprecated = en.deprecation && isDeprecated;
|
|
3832
|
-
const showForward = en.alias && aliasChain !== void 0;
|
|
3833
|
-
const showReverse = en.alias && reverseCount > 0;
|
|
3834
|
-
const showVariance = en.variance && isVarying;
|
|
3835
|
-
const showGamut = en.gamut && outOfGamut;
|
|
3836
|
-
const showDescription = en.description && description !== void 0;
|
|
3837
|
-
if (!showDeprecated && !showForward && !showReverse && !showVariance && !showGamut && !showDescription) return null;
|
|
3838
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
3839
|
-
className: "sb-indicator__indicators",
|
|
3840
|
-
children: [
|
|
3841
|
-
showDeprecated && deprecated !== void 0 && /* @__PURE__ */ jsx(DeprecatedBadge, { deprecated }),
|
|
3842
|
-
showForward && aliasChain && /* @__PURE__ */ jsx(ForwardChain, {
|
|
3843
|
-
chain: aliasChain,
|
|
3844
|
-
root,
|
|
3845
|
-
canReference,
|
|
3846
|
-
onReferenceClick
|
|
3847
|
-
}),
|
|
3848
|
-
showReverse && token.aliasedBy && /* @__PURE__ */ jsx(ReverseCount, {
|
|
3849
|
-
referents: token.aliasedBy,
|
|
3850
|
-
canReference,
|
|
3851
|
-
onReferenceClick
|
|
3852
|
-
}),
|
|
3853
|
-
showVariance && variance && /* @__PURE__ */ jsx(VarianceBadge, { variance }),
|
|
3854
|
-
showGamut && /* @__PURE__ */ jsx("span", {
|
|
3855
|
-
className: "sb-indicator__gamut",
|
|
3856
|
-
title: "Out of sRGB gamut for this format",
|
|
3857
|
-
"aria-label": "out of gamut",
|
|
3858
|
-
children: "⚠"
|
|
3859
|
-
}),
|
|
3860
|
-
showDescription && description !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
3861
|
-
className: "sb-indicator__description",
|
|
3862
|
-
"data-testid": "row-indicator-description",
|
|
3863
|
-
title: description,
|
|
3864
|
-
"aria-label": `description: ${description}`,
|
|
3865
|
-
children: "ⓘ"
|
|
3866
|
-
})
|
|
3867
|
-
]
|
|
3868
|
-
});
|
|
3869
|
-
}
|
|
3870
|
-
//#endregion
|
|
3871
3935
|
//#region src/TokenNavigator.tsx
|
|
3872
3936
|
function buildTree(resolved, root, typeFilter) {
|
|
3873
3937
|
const rootPrefix = root && root.length > 0 ? `${root}.` : "";
|
|
@@ -3972,7 +4036,7 @@ function pruneTreeForMatches(nodes, matches, expandOut) {
|
|
|
3972
4036
|
return out;
|
|
3973
4037
|
}
|
|
3974
4038
|
function TokenNavigator({ root, type, initiallyExpanded = 1, searchable = true, onSelect, id, indicators }) {
|
|
3975
|
-
const { resolved, activeTheme, activeAxes, cssVarPrefix } = useProject();
|
|
4039
|
+
const { resolved, activeTheme, activeAxes, cssVarPrefix, indicators: indicatorBaseline } = useProject();
|
|
3976
4040
|
const blockKey = useBlockKey("TokenNavigator", [
|
|
3977
4041
|
root,
|
|
3978
4042
|
type === void 0 ? "" : typeof type === "string" ? type : type.join(","),
|
|
@@ -3982,7 +4046,7 @@ function TokenNavigator({ root, type, initiallyExpanded = 1, searchable = true,
|
|
|
3982
4046
|
if (type === void 0) return void 0;
|
|
3983
4047
|
return new Set(Array.isArray(type) ? type : [type]);
|
|
3984
4048
|
}, [type]);
|
|
3985
|
-
const enabledIndicators = useMemo(() => resolveIndicators(indicators), [indicators]);
|
|
4049
|
+
const enabledIndicators = useMemo(() => resolveIndicators(indicators, indicatorBaseline), [indicators, indicatorBaseline]);
|
|
3986
4050
|
const tree = useMemo(() => buildTree(resolved, root, typeFilter), [
|
|
3987
4051
|
resolved,
|
|
3988
4052
|
root,
|
|
@@ -4457,7 +4521,7 @@ const LeafPreview = memo(function LeafPreview({ path, token }) {
|
|
|
4457
4521
|
//#endregion
|
|
4458
4522
|
//#region src/TokenTable.tsx
|
|
4459
4523
|
function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", searchable = true, onSelect, id, indicators }) {
|
|
4460
|
-
const { resolved, activeTheme, activeAxes, cssVarPrefix, listing, varianceByPath } = useProject();
|
|
4524
|
+
const { resolved, activeTheme, activeAxes, cssVarPrefix, listing, varianceByPath, indicators: indicatorBaseline } = useProject();
|
|
4461
4525
|
const colorFormat = useColorFormat();
|
|
4462
4526
|
const blockKey = useBlockKey("TokenTable", [
|
|
4463
4527
|
filter,
|
|
@@ -4465,7 +4529,7 @@ function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", s
|
|
|
4465
4529
|
caption,
|
|
4466
4530
|
id
|
|
4467
4531
|
]);
|
|
4468
|
-
const enabledIndicators = useMemo(() => resolveIndicators(indicators), [indicators]);
|
|
4532
|
+
const enabledIndicators = useMemo(() => resolveIndicators(indicators, indicatorBaseline), [indicators, indicatorBaseline]);
|
|
4469
4533
|
const [selectedPath, setSelectedPath] = usePersistedState(`${blockKey}::selected`, null);
|
|
4470
4534
|
const [query, setQuery] = usePersistedState(`${blockKey}::query`, "");
|
|
4471
4535
|
const deferredQuery = useDeferredValue(query);
|