@unpunnyfuns/swatchbook-blocks 0.64.0 → 0.66.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 +41 -8
- package/dist/index.mjs +322 -204
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +124 -121
- 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,187 +3932,6 @@ function isInView(path, ctx) {
|
|
|
3640
3932
|
return true;
|
|
3641
3933
|
}
|
|
3642
3934
|
//#endregion
|
|
3643
|
-
//#region src/indicators/RowIndicators.tsx
|
|
3644
|
-
function relativeLabel(path, root) {
|
|
3645
|
-
if (root && path.startsWith(`${root}.`)) return path.slice(root.length + 1);
|
|
3646
|
-
return path;
|
|
3647
|
-
}
|
|
3648
|
-
/**
|
|
3649
|
-
* The forward alias chain for one row. Full chain in `aria-label`; visually
|
|
3650
|
-
* capped to first … last beyond two hops (no width measurement). Each shown
|
|
3651
|
-
* node navigates when in view, else renders as plain text.
|
|
3652
|
-
*/
|
|
3653
|
-
function ForwardChain({ chain, root, canReference, onReferenceClick }) {
|
|
3654
|
-
const full = chain.map((p) => relativeLabel(p, root)).join(" → ");
|
|
3655
|
-
const capped = chain.length > 2;
|
|
3656
|
-
const shown = capped ? [chain[0], chain[chain.length - 1]] : [...chain];
|
|
3657
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
3658
|
-
className: "sb-indicator__alias-forward",
|
|
3659
|
-
"data-testid": "row-indicator-alias-forward",
|
|
3660
|
-
"aria-label": `aliases ${full}`,
|
|
3661
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3662
|
-
className: "sb-indicator__alias-arrow",
|
|
3663
|
-
"aria-hidden": true,
|
|
3664
|
-
children: "→"
|
|
3665
|
-
}), shown.map((target, i) => {
|
|
3666
|
-
const label = relativeLabel(target, root);
|
|
3667
|
-
return /* @__PURE__ */ jsxs("span", { children: [canReference(target) ? /* @__PURE__ */ jsx("button", {
|
|
3668
|
-
type: "button",
|
|
3669
|
-
className: "sb-indicator__alias-node",
|
|
3670
|
-
"data-testid": "alias-node",
|
|
3671
|
-
"aria-label": target,
|
|
3672
|
-
onClick: (e) => {
|
|
3673
|
-
e.stopPropagation();
|
|
3674
|
-
onReferenceClick(target);
|
|
3675
|
-
},
|
|
3676
|
-
children: label
|
|
3677
|
-
}) : /* @__PURE__ */ jsx("span", {
|
|
3678
|
-
className: "sb-indicator__alias-node sb-indicator__alias-node--offview",
|
|
3679
|
-
"data-testid": "alias-node",
|
|
3680
|
-
title: "outside current view",
|
|
3681
|
-
children: label
|
|
3682
|
-
}), capped && i === 0 ? /* @__PURE__ */ jsxs("span", {
|
|
3683
|
-
className: "sb-indicator__alias-arrow",
|
|
3684
|
-
"aria-hidden": true,
|
|
3685
|
-
children: [
|
|
3686
|
-
" ",
|
|
3687
|
-
"→ … →",
|
|
3688
|
-
" "
|
|
3689
|
-
]
|
|
3690
|
-
}) : i < shown.length - 1 ? /* @__PURE__ */ jsxs("span", {
|
|
3691
|
-
className: "sb-indicator__alias-arrow",
|
|
3692
|
-
"aria-hidden": true,
|
|
3693
|
-
children: [
|
|
3694
|
-
" ",
|
|
3695
|
-
"→",
|
|
3696
|
-
" "
|
|
3697
|
-
]
|
|
3698
|
-
}) : null] }, target);
|
|
3699
|
-
})]
|
|
3700
|
-
});
|
|
3701
|
-
}
|
|
3702
|
-
function DeprecatedBadge({ deprecated }) {
|
|
3703
|
-
const label = typeof deprecated === "string" ? `deprecated: ${deprecated}` : "deprecated";
|
|
3704
|
-
return /* @__PURE__ */ jsx("span", {
|
|
3705
|
-
className: "sb-indicator__deprecated",
|
|
3706
|
-
"data-testid": "row-indicator-deprecated",
|
|
3707
|
-
title: label,
|
|
3708
|
-
"aria-label": label,
|
|
3709
|
-
children: "deprecated"
|
|
3710
|
-
});
|
|
3711
|
-
}
|
|
3712
|
-
function VarianceBadge({ variance }) {
|
|
3713
|
-
if (variance.kind === "constant") return null;
|
|
3714
|
-
const axes = variance.varyingAxes;
|
|
3715
|
-
const label = variance.kind === "single" ? variance.axis : `${axes.length} axes`;
|
|
3716
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
3717
|
-
className: "sb-indicator__variance",
|
|
3718
|
-
"data-testid": "row-indicator-variance",
|
|
3719
|
-
"aria-label": `varies by ${axes.join(", ")}`,
|
|
3720
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3721
|
-
className: "sb-indicator__variance-glyph",
|
|
3722
|
-
"aria-hidden": true,
|
|
3723
|
-
children: "⊹"
|
|
3724
|
-
}), label]
|
|
3725
|
-
});
|
|
3726
|
-
}
|
|
3727
|
-
function ReverseCount({ referents, canReference, onReferenceClick }) {
|
|
3728
|
-
const [open, setOpen] = useState(false);
|
|
3729
|
-
const wrapRef = useRef(null);
|
|
3730
|
-
const count = referents.length;
|
|
3731
|
-
const single = count === 1;
|
|
3732
|
-
useEffect(() => {
|
|
3733
|
-
if (single || !open) return;
|
|
3734
|
-
(wrapRef.current?.querySelector("button[role=\"menuitem\"]:not(:disabled)"))?.focus();
|
|
3735
|
-
const handlePointerDown = (e) => {
|
|
3736
|
-
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
3737
|
-
};
|
|
3738
|
-
document.addEventListener("pointerdown", handlePointerDown);
|
|
3739
|
-
return () => {
|
|
3740
|
-
document.removeEventListener("pointerdown", handlePointerDown);
|
|
3741
|
-
};
|
|
3742
|
-
}, [open, single]);
|
|
3743
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
3744
|
-
ref: wrapRef,
|
|
3745
|
-
className: "sb-indicator__reverse-wrap",
|
|
3746
|
-
onKeyDown: (e) => {
|
|
3747
|
-
if (e.key === "Escape") setOpen(false);
|
|
3748
|
-
},
|
|
3749
|
-
children: [/* @__PURE__ */ jsxs("button", {
|
|
3750
|
-
type: "button",
|
|
3751
|
-
className: "sb-indicator__alias-reverse",
|
|
3752
|
-
"data-testid": "row-indicator-alias-reverse",
|
|
3753
|
-
"aria-label": `referenced by ${count} ${count === 1 ? "token" : "tokens"}`,
|
|
3754
|
-
"aria-haspopup": single ? void 0 : "menu",
|
|
3755
|
-
"aria-expanded": single ? void 0 : open,
|
|
3756
|
-
onClick: (e) => {
|
|
3757
|
-
e.stopPropagation();
|
|
3758
|
-
if (single) onReferenceClick(referents[0]);
|
|
3759
|
-
else setOpen((v) => !v);
|
|
3760
|
-
},
|
|
3761
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
3762
|
-
className: "sb-indicator__alias-arrow",
|
|
3763
|
-
"aria-hidden": true,
|
|
3764
|
-
children: "←"
|
|
3765
|
-
}), count]
|
|
3766
|
-
}), !single && open && /* @__PURE__ */ jsx("ul", {
|
|
3767
|
-
className: "sb-indicator__reverse-menu",
|
|
3768
|
-
role: "menu",
|
|
3769
|
-
children: referents.map((ref) => /* @__PURE__ */ jsx("li", {
|
|
3770
|
-
role: "none",
|
|
3771
|
-
children: /* @__PURE__ */ jsx("button", {
|
|
3772
|
-
type: "button",
|
|
3773
|
-
role: "menuitem",
|
|
3774
|
-
className: "sb-indicator__reverse-item",
|
|
3775
|
-
disabled: !canReference(ref),
|
|
3776
|
-
title: canReference(ref) ? void 0 : "outside current view",
|
|
3777
|
-
onClick: (e) => {
|
|
3778
|
-
e.stopPropagation();
|
|
3779
|
-
setOpen(false);
|
|
3780
|
-
onReferenceClick(ref);
|
|
3781
|
-
},
|
|
3782
|
-
children: ref
|
|
3783
|
-
})
|
|
3784
|
-
}, ref))
|
|
3785
|
-
})]
|
|
3786
|
-
});
|
|
3787
|
-
}
|
|
3788
|
-
/** Per-row indicator strip: alias references, variance, gamut, deprecation. */
|
|
3789
|
-
function RowIndicators(props) {
|
|
3790
|
-
const { token, root, variance, colorFormat, canReference, onReferenceClick } = props;
|
|
3791
|
-
const aliasChain = Array.isArray(token.aliasChain) && token.aliasChain.length > 0 ? token.aliasChain : void 0;
|
|
3792
|
-
const reverseCount = Array.isArray(token.aliasedBy) && token.aliasedBy.length > 0 ? token.aliasedBy.length : 0;
|
|
3793
|
-
const isVarying = variance !== void 0 && variance.kind !== "constant";
|
|
3794
|
-
const outOfGamut = token.$type === "color" && (formatColor(token.$value, colorFormat)?.outOfGamut ?? false);
|
|
3795
|
-
const deprecated = token.$deprecated;
|
|
3796
|
-
const isDeprecated = deprecated === true || typeof deprecated === "string" && deprecated.length > 0;
|
|
3797
|
-
if (!aliasChain && reverseCount === 0 && !isVarying && !outOfGamut && !isDeprecated) return null;
|
|
3798
|
-
return /* @__PURE__ */ jsxs("span", {
|
|
3799
|
-
className: "sb-indicator__indicators",
|
|
3800
|
-
children: [
|
|
3801
|
-
isDeprecated && deprecated !== void 0 && /* @__PURE__ */ jsx(DeprecatedBadge, { deprecated }),
|
|
3802
|
-
aliasChain && /* @__PURE__ */ jsx(ForwardChain, {
|
|
3803
|
-
chain: aliasChain,
|
|
3804
|
-
root,
|
|
3805
|
-
canReference,
|
|
3806
|
-
onReferenceClick
|
|
3807
|
-
}),
|
|
3808
|
-
reverseCount > 0 && token.aliasedBy && /* @__PURE__ */ jsx(ReverseCount, {
|
|
3809
|
-
referents: token.aliasedBy,
|
|
3810
|
-
canReference,
|
|
3811
|
-
onReferenceClick
|
|
3812
|
-
}),
|
|
3813
|
-
variance && /* @__PURE__ */ jsx(VarianceBadge, { variance }),
|
|
3814
|
-
outOfGamut && /* @__PURE__ */ jsx("span", {
|
|
3815
|
-
className: "sb-indicator__gamut",
|
|
3816
|
-
title: "Out of sRGB gamut for this format",
|
|
3817
|
-
"aria-label": "out of gamut",
|
|
3818
|
-
children: "⚠"
|
|
3819
|
-
})
|
|
3820
|
-
]
|
|
3821
|
-
});
|
|
3822
|
-
}
|
|
3823
|
-
//#endregion
|
|
3824
3935
|
//#region src/TokenNavigator.tsx
|
|
3825
3936
|
function buildTree(resolved, root, typeFilter) {
|
|
3826
3937
|
const rootPrefix = root && root.length > 0 ? `${root}.` : "";
|
|
@@ -3924,8 +4035,8 @@ function pruneTreeForMatches(nodes, matches, expandOut) {
|
|
|
3924
4035
|
}
|
|
3925
4036
|
return out;
|
|
3926
4037
|
}
|
|
3927
|
-
function TokenNavigator({ root, type, initiallyExpanded = 1, searchable = true, onSelect, id }) {
|
|
3928
|
-
const { resolved, activeTheme, activeAxes, cssVarPrefix } = useProject();
|
|
4038
|
+
function TokenNavigator({ root, type, initiallyExpanded = 1, searchable = true, onSelect, id, indicators }) {
|
|
4039
|
+
const { resolved, activeTheme, activeAxes, cssVarPrefix, indicators: indicatorBaseline } = useProject();
|
|
3929
4040
|
const blockKey = useBlockKey("TokenNavigator", [
|
|
3930
4041
|
root,
|
|
3931
4042
|
type === void 0 ? "" : typeof type === "string" ? type : type.join(","),
|
|
@@ -3935,6 +4046,7 @@ function TokenNavigator({ root, type, initiallyExpanded = 1, searchable = true,
|
|
|
3935
4046
|
if (type === void 0) return void 0;
|
|
3936
4047
|
return new Set(Array.isArray(type) ? type : [type]);
|
|
3937
4048
|
}, [type]);
|
|
4049
|
+
const enabledIndicators = useMemo(() => resolveIndicators(indicators, indicatorBaseline), [indicators, indicatorBaseline]);
|
|
3938
4050
|
const tree = useMemo(() => buildTree(resolved, root, typeFilter), [
|
|
3939
4051
|
resolved,
|
|
3940
4052
|
root,
|
|
@@ -4206,6 +4318,7 @@ function TokenNavigator({ root, type, initiallyExpanded = 1, searchable = true,
|
|
|
4206
4318
|
root,
|
|
4207
4319
|
resolveInView,
|
|
4208
4320
|
onNavigate: navigateTo,
|
|
4321
|
+
enabled: enabledIndicators,
|
|
4209
4322
|
level: 1,
|
|
4210
4323
|
setsize: visibleTree.length,
|
|
4211
4324
|
posinset: i + 1
|
|
@@ -4219,7 +4332,7 @@ function TokenNavigator({ root, type, initiallyExpanded = 1, searchable = true,
|
|
|
4219
4332
|
]
|
|
4220
4333
|
});
|
|
4221
4334
|
}
|
|
4222
|
-
function TreeNodeRow({ node, expanded, focusedPath, registerTreeItem, onToggle, onFocusPath, onLeafClick, root, resolveInView, onNavigate, level, setsize, posinset }) {
|
|
4335
|
+
function TreeNodeRow({ node, expanded, focusedPath, registerTreeItem, onToggle, onFocusPath, onLeafClick, root, resolveInView, onNavigate, enabled, level, setsize, posinset }) {
|
|
4223
4336
|
if (node.kind === "leaf") return /* @__PURE__ */ jsx(LeafRow, {
|
|
4224
4337
|
node,
|
|
4225
4338
|
isFocused: focusedPath === node.path,
|
|
@@ -4229,6 +4342,7 @@ function TreeNodeRow({ node, expanded, focusedPath, registerTreeItem, onToggle,
|
|
|
4229
4342
|
root,
|
|
4230
4343
|
resolveInView,
|
|
4231
4344
|
onNavigate,
|
|
4345
|
+
enabled,
|
|
4232
4346
|
level,
|
|
4233
4347
|
setsize,
|
|
4234
4348
|
posinset
|
|
@@ -4279,6 +4393,7 @@ function TreeNodeRow({ node, expanded, focusedPath, registerTreeItem, onToggle,
|
|
|
4279
4393
|
root,
|
|
4280
4394
|
resolveInView,
|
|
4281
4395
|
onNavigate,
|
|
4396
|
+
enabled,
|
|
4282
4397
|
level: level + 1,
|
|
4283
4398
|
setsize: node.children.length,
|
|
4284
4399
|
posinset: i + 1
|
|
@@ -4286,7 +4401,7 @@ function TreeNodeRow({ node, expanded, focusedPath, registerTreeItem, onToggle,
|
|
|
4286
4401
|
})]
|
|
4287
4402
|
});
|
|
4288
4403
|
}
|
|
4289
|
-
const LeafRow = memo(function LeafRow({ node, isFocused, registerTreeItem, onFocusPath, onLeafClick, root, resolveInView, onNavigate, level, setsize, posinset }) {
|
|
4404
|
+
const LeafRow = memo(function LeafRow({ node, isFocused, registerTreeItem, onFocusPath, onLeafClick, root, resolveInView, onNavigate, enabled, level, setsize, posinset }) {
|
|
4290
4405
|
const type = node.token.$type ?? "";
|
|
4291
4406
|
const project = useProject();
|
|
4292
4407
|
const colorFormat = useColorFormat();
|
|
@@ -4306,7 +4421,7 @@ const LeafRow = memo(function LeafRow({ node, isFocused, registerTreeItem, onFoc
|
|
|
4306
4421
|
children: /* @__PURE__ */ jsxs("div", {
|
|
4307
4422
|
className: "sb-token-navigator__leaf-row",
|
|
4308
4423
|
"data-testid": "token-navigator-leaf-row",
|
|
4309
|
-
"data-deprecated": isDeprecated ? "true" : void 0,
|
|
4424
|
+
"data-deprecated": enabled.deprecation && isDeprecated ? "true" : void 0,
|
|
4310
4425
|
onClick: () => {
|
|
4311
4426
|
onFocusPath(node.path);
|
|
4312
4427
|
onLeafClick(node.path);
|
|
@@ -4332,7 +4447,8 @@ const LeafRow = memo(function LeafRow({ node, isFocused, registerTreeItem, onFoc
|
|
|
4332
4447
|
variance,
|
|
4333
4448
|
colorFormat,
|
|
4334
4449
|
canReference: resolveInView,
|
|
4335
|
-
onReferenceClick: onNavigate
|
|
4450
|
+
onReferenceClick: onNavigate,
|
|
4451
|
+
enabled
|
|
4336
4452
|
}),
|
|
4337
4453
|
/* @__PURE__ */ jsx(LeafPreview, {
|
|
4338
4454
|
path: node.path,
|
|
@@ -4404,8 +4520,8 @@ const LeafPreview = memo(function LeafPreview({ path, token }) {
|
|
|
4404
4520
|
});
|
|
4405
4521
|
//#endregion
|
|
4406
4522
|
//#region src/TokenTable.tsx
|
|
4407
|
-
function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", searchable = true, onSelect, id }) {
|
|
4408
|
-
const { resolved, activeTheme, activeAxes, cssVarPrefix, listing, varianceByPath } = useProject();
|
|
4523
|
+
function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", searchable = true, onSelect, id, indicators }) {
|
|
4524
|
+
const { resolved, activeTheme, activeAxes, cssVarPrefix, listing, varianceByPath, indicators: indicatorBaseline } = useProject();
|
|
4409
4525
|
const colorFormat = useColorFormat();
|
|
4410
4526
|
const blockKey = useBlockKey("TokenTable", [
|
|
4411
4527
|
filter,
|
|
@@ -4413,6 +4529,7 @@ function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", s
|
|
|
4413
4529
|
caption,
|
|
4414
4530
|
id
|
|
4415
4531
|
]);
|
|
4532
|
+
const enabledIndicators = useMemo(() => resolveIndicators(indicators, indicatorBaseline), [indicators, indicatorBaseline]);
|
|
4416
4533
|
const [selectedPath, setSelectedPath] = usePersistedState(`${blockKey}::selected`, null);
|
|
4417
4534
|
const [query, setQuery] = usePersistedState(`${blockKey}::query`, "");
|
|
4418
4535
|
const deferredQuery = useDeferredValue(query);
|
|
@@ -4545,7 +4662,7 @@ function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", s
|
|
|
4545
4662
|
children: [
|
|
4546
4663
|
/* @__PURE__ */ jsx("td", {
|
|
4547
4664
|
className: cx("sb-token-table__td", "sb-token-table__path"),
|
|
4548
|
-
"data-deprecated": isDeprecated ? "true" : void 0,
|
|
4665
|
+
"data-deprecated": enabledIndicators.deprecation && isDeprecated ? "true" : void 0,
|
|
4549
4666
|
children: row.path
|
|
4550
4667
|
}),
|
|
4551
4668
|
/* @__PURE__ */ jsx("td", {
|
|
@@ -4597,7 +4714,8 @@ function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", s
|
|
|
4597
4714
|
variance: varianceByPath[row.path],
|
|
4598
4715
|
colorFormat,
|
|
4599
4716
|
canReference: (p) => p in resolved,
|
|
4600
|
-
onReferenceClick: (p) => setSelectedPath(p)
|
|
4717
|
+
onReferenceClick: (p) => setSelectedPath(p),
|
|
4718
|
+
enabled: enabledIndicators
|
|
4601
4719
|
})
|
|
4602
4720
|
})
|
|
4603
4721
|
]
|