@unpunnyfuns/swatchbook-blocks 0.67.0 → 0.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.mjs +28 -153
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +330 -198
- package/package.json +35 -33
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ React MDX doc blocks for [swatchbook](https://github.com/unpunnyfuns/swatchbook)
|
|
|
4
4
|
|
|
5
5
|
Render your DTCG tokens in `.mdx` stories: swatch grids, type-specific previews, per-token inspectors. The blocks react to the toolbar's axis flips without any wiring in your story code.
|
|
6
6
|
|
|
7
|
-
Most consumers pick this up transitively via [`@unpunnyfuns/swatchbook-addon`](../addon); `import { TokenTable } from '@unpunnyfuns/swatchbook-addon'` works out of the box. Install this package directly when you want blocks
|
|
7
|
+
Most consumers pick this up transitively via [`@unpunnyfuns/swatchbook-addon`](../addon); `import { TokenTable } from '@unpunnyfuns/swatchbook-addon'` works out of the box. Install this package directly when you want blocks _without_ the Storybook addon, such as unit tests or a standalone React app wrapping tokens in a custom surface.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -32,7 +32,7 @@ import snapshot from './tokens-snapshot.json';
|
|
|
32
32
|
|
|
33
33
|
<SwatchbookProvider value={snapshot}>
|
|
34
34
|
<TokenTable filter="color.**" />
|
|
35
|
-
</SwatchbookProvider
|
|
35
|
+
</SwatchbookProvider>;
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
Block catalogue, props, and composition patterns live in the [blocks reference](https://unpunnyfuns.github.io/swatchbook/reference/blocks) and the [authoring guide](https://unpunnyfuns.github.io/swatchbook/guides/authoring-doc-stories).
|
package/dist/index.mjs
CHANGED
|
@@ -2,41 +2,16 @@ import './style.css';
|
|
|
2
2
|
import { COLOR_FORMATS } from "@unpunnyfuns/swatchbook-core/color-formats";
|
|
3
3
|
import { formatColor, parseColor } from "@unpunnyfuns/swatchbook-core/format-color";
|
|
4
4
|
import { createContext, memo, useCallback, useContext, useDeferredValue, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
5
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
5
|
import { getVariance, listPaths, resolveAllWithProvenanceAt } from "@unpunnyfuns/swatchbook-core/graph";
|
|
7
6
|
import { makeCssVar } from "@unpunnyfuns/swatchbook-core/css-var";
|
|
8
7
|
import { SWATCHBOOK_STYLE_ELEMENT_ID, ensureStyleElement } from "@unpunnyfuns/swatchbook-core/style-element";
|
|
9
8
|
import { tupleToName } from "@unpunnyfuns/swatchbook-core/themes";
|
|
10
9
|
import { addons } from "storybook/preview-api";
|
|
10
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
import { dataAttr } from "@unpunnyfuns/swatchbook-core/data-attr";
|
|
12
12
|
import { matchPath } from "@unpunnyfuns/swatchbook-core/match-path";
|
|
13
13
|
import { fuzzyFilter } from "@unpunnyfuns/swatchbook-core/fuzzy";
|
|
14
14
|
import cx from "clsx";
|
|
15
|
-
//#region src/internal/styles.tsx
|
|
16
|
-
/**
|
|
17
|
-
* Chrome-style primitives shared across every block. Kept as JS exports
|
|
18
|
-
* for the inline-style sites that still compose them into per-block style
|
|
19
|
-
* objects (e.g. TokenNavigator's `typePill` that builds on the shared
|
|
20
|
-
* pill base). The pure direct-reference chrome — surface wrapper, caption,
|
|
21
|
-
* empty-state — lives in `styles.css` and is applied via class names.
|
|
22
|
-
*/
|
|
23
|
-
const TEXT_MUTED = "var(--swatchbook-text-muted, CanvasText)";
|
|
24
|
-
const SURFACE_RAISED = "var(--swatchbook-surface-raised, Canvas)";
|
|
25
|
-
const SURFACE_MUTED = "var(--swatchbook-surface-muted, rgba(128,128,128,0.15))";
|
|
26
|
-
const BORDER_FAINT = `1px solid var(--swatchbook-border-default, rgba(128,128,128,0.15))`;
|
|
27
|
-
const BORDER_STRONG = `1px solid var(--swatchbook-border-default, rgba(128,128,128,0.3))`;
|
|
28
|
-
/**
|
|
29
|
-
* Inner content for a block's "nothing to render" state. Call sites wrap
|
|
30
|
-
* it in their own block wrapper (which already carries `blockWrapperAttrs`), so
|
|
31
|
-
* the message itself just needs the muted type.
|
|
32
|
-
*/
|
|
33
|
-
function EmptyState({ children }) {
|
|
34
|
-
return /* @__PURE__ */ jsx("div", {
|
|
35
|
-
className: "sb-block__empty",
|
|
36
|
-
children
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
//#endregion
|
|
40
15
|
//#region src/internal/channel-globals.ts
|
|
41
16
|
const AXES_GLOBAL_KEY = "swatchbookAxes";
|
|
42
17
|
const COLOR_FORMAT_GLOBAL_KEY = "swatchbookColorFormat";
|
|
@@ -388,19 +363,10 @@ function resolveColorValue(path, raw, colorFormat, project) {
|
|
|
388
363
|
}
|
|
389
364
|
//#endregion
|
|
390
365
|
//#region src/border-preview/BorderSample.tsx
|
|
391
|
-
const sampleStyle$1 = {
|
|
392
|
-
width: 120,
|
|
393
|
-
height: 56,
|
|
394
|
-
background: SURFACE_RAISED,
|
|
395
|
-
borderRadius: 6
|
|
396
|
-
};
|
|
397
366
|
function BorderSample({ path }) {
|
|
398
|
-
const cssVar = resolveCssVar(path, useProject());
|
|
399
367
|
return /* @__PURE__ */ jsx("div", {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
border: cssVar
|
|
403
|
-
},
|
|
368
|
+
className: "sb-border-sample",
|
|
369
|
+
style: { border: resolveCssVar(path, useProject()) },
|
|
404
370
|
"aria-hidden": true
|
|
405
371
|
});
|
|
406
372
|
}
|
|
@@ -1057,12 +1023,9 @@ function CopyButton$1({ value, label, variant = "icon", className }) {
|
|
|
1057
1023
|
timerRef.current = setTimeout(() => setCopied(false), 1500);
|
|
1058
1024
|
}, [value]);
|
|
1059
1025
|
const ariaLabel = label ?? `Copy ${value}`;
|
|
1060
|
-
const classes = ["sb-copy-button", `sb-copy-button--${variant}`];
|
|
1061
|
-
if (copied) classes.push("sb-copy-button--copied");
|
|
1062
|
-
if (className) classes.push(className);
|
|
1063
1026
|
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
|
|
1064
1027
|
type: "button",
|
|
1065
|
-
className:
|
|
1028
|
+
className: cx("sb-copy-button", `sb-copy-button--${variant}`, copied && "sb-copy-button--copied", className),
|
|
1066
1029
|
onClick: handleClick,
|
|
1067
1030
|
"aria-label": ariaLabel,
|
|
1068
1031
|
title: ariaLabel,
|
|
@@ -1746,44 +1709,9 @@ function useRootFontSize() {
|
|
|
1746
1709
|
}
|
|
1747
1710
|
//#endregion
|
|
1748
1711
|
//#region src/dimension-scale/DimensionBar.tsx
|
|
1749
|
-
const styles$1 = {
|
|
1750
|
-
cappedWrap: {
|
|
1751
|
-
display: "inline-flex",
|
|
1752
|
-
alignItems: "center",
|
|
1753
|
-
gap: "var(--swatchbook-space-3xs)",
|
|
1754
|
-
maxWidth: "100%",
|
|
1755
|
-
minWidth: 0
|
|
1756
|
-
},
|
|
1757
|
-
cap: {
|
|
1758
|
-
color: "var(--swatchbook-text-muted)",
|
|
1759
|
-
fontSize: 11,
|
|
1760
|
-
lineHeight: 1,
|
|
1761
|
-
userSelect: "none"
|
|
1762
|
-
},
|
|
1763
|
-
bar: {
|
|
1764
|
-
height: 14,
|
|
1765
|
-
background: "var(--swatchbook-accent-bg, #3b82f6)",
|
|
1766
|
-
borderRadius: 2,
|
|
1767
|
-
minWidth: 1,
|
|
1768
|
-
maxWidth: "100%"
|
|
1769
|
-
},
|
|
1770
|
-
radiusSample: {
|
|
1771
|
-
width: 56,
|
|
1772
|
-
height: 56,
|
|
1773
|
-
background: "var(--swatchbook-accent-bg, #3b82f6)",
|
|
1774
|
-
border: BORDER_STRONG
|
|
1775
|
-
},
|
|
1776
|
-
sizeSample: {
|
|
1777
|
-
background: "var(--swatchbook-accent-bg, #3b82f6)",
|
|
1778
|
-
border: BORDER_STRONG,
|
|
1779
|
-
minWidth: 1,
|
|
1780
|
-
minHeight: 1
|
|
1781
|
-
}
|
|
1782
|
-
};
|
|
1783
1712
|
function withCap(visual) {
|
|
1784
1713
|
return /* @__PURE__ */ jsxs("span", {
|
|
1785
1714
|
className: "sb-dimension-bar sb-dimension-bar--capped",
|
|
1786
|
-
style: styles$1.cappedWrap,
|
|
1787
1715
|
title: `capped at 480px`,
|
|
1788
1716
|
children: [visual, /* @__PURE__ */ jsx("span", {
|
|
1789
1717
|
className: "sb-dimension-bar__cap",
|
|
@@ -1803,16 +1731,14 @@ function DimensionBar({ path, visual = "length" }) {
|
|
|
1803
1731
|
const cappedValue = capped ? `480px` : cssVar;
|
|
1804
1732
|
switch (visual) {
|
|
1805
1733
|
case "radius": return /* @__PURE__ */ jsx("div", {
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
borderRadius: cssVar
|
|
1809
|
-
},
|
|
1734
|
+
className: "sb-dimension-bar__radius-sample",
|
|
1735
|
+
style: { borderRadius: cssVar },
|
|
1810
1736
|
"aria-hidden": true
|
|
1811
1737
|
});
|
|
1812
1738
|
case "size": {
|
|
1813
1739
|
const sample = /* @__PURE__ */ jsx("div", {
|
|
1740
|
+
className: "sb-dimension-bar__size-sample",
|
|
1814
1741
|
style: {
|
|
1815
|
-
...styles$1.sizeSample,
|
|
1816
1742
|
width: cappedValue,
|
|
1817
1743
|
height: cappedValue
|
|
1818
1744
|
},
|
|
@@ -1822,10 +1748,8 @@ function DimensionBar({ path, visual = "length" }) {
|
|
|
1822
1748
|
}
|
|
1823
1749
|
default: {
|
|
1824
1750
|
const bar = /* @__PURE__ */ jsx("div", {
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
width: cappedValue
|
|
1828
|
-
},
|
|
1751
|
+
className: "sb-dimension-bar__bar",
|
|
1752
|
+
style: { width: cappedValue },
|
|
1829
1753
|
"aria-hidden": true
|
|
1830
1754
|
});
|
|
1831
1755
|
return capped ? withCap(bar) : bar;
|
|
@@ -2287,29 +2211,6 @@ function usePrefersReducedMotion() {
|
|
|
2287
2211
|
//#region src/motion-preview/MotionSample.tsx
|
|
2288
2212
|
const DEFAULT_DURATION_MS = 300;
|
|
2289
2213
|
const DEFAULT_EASING = "cubic-bezier(0.2, 0, 0, 1)";
|
|
2290
|
-
const styles = {
|
|
2291
|
-
track: {
|
|
2292
|
-
position: "relative",
|
|
2293
|
-
height: 36,
|
|
2294
|
-
background: SURFACE_MUTED,
|
|
2295
|
-
borderRadius: 18,
|
|
2296
|
-
overflow: "hidden"
|
|
2297
|
-
},
|
|
2298
|
-
ball: {
|
|
2299
|
-
position: "absolute",
|
|
2300
|
-
top: "50%",
|
|
2301
|
-
width: 28,
|
|
2302
|
-
height: 28,
|
|
2303
|
-
marginTop: -14,
|
|
2304
|
-
borderRadius: "50%",
|
|
2305
|
-
background: "var(--swatchbook-accent-bg, #3b82f6)"
|
|
2306
|
-
},
|
|
2307
|
-
reducedMotion: {
|
|
2308
|
-
fontSize: 11,
|
|
2309
|
-
color: TEXT_MUTED,
|
|
2310
|
-
fontStyle: "italic"
|
|
2311
|
-
}
|
|
2312
|
-
};
|
|
2313
2214
|
function extractDurationMs(raw) {
|
|
2314
2215
|
if (raw == null) return NaN;
|
|
2315
2216
|
if (typeof raw === "object") {
|
|
@@ -2404,7 +2305,7 @@ function MotionSample({ path, speed = 1, runKey = 0 }) {
|
|
|
2404
2305
|
reducedMotion
|
|
2405
2306
|
]);
|
|
2406
2307
|
if (reducedMotion) return /* @__PURE__ */ jsxs("div", {
|
|
2407
|
-
|
|
2308
|
+
className: "sb-motion-sample__reduced-motion",
|
|
2408
2309
|
children: [
|
|
2409
2310
|
"Animation suppressed by ",
|
|
2410
2311
|
/* @__PURE__ */ jsx("code", { children: "prefers-reduced-motion: reduce" }),
|
|
@@ -2412,13 +2313,10 @@ function MotionSample({ path, speed = 1, runKey = 0 }) {
|
|
|
2412
2313
|
]
|
|
2413
2314
|
});
|
|
2414
2315
|
return /* @__PURE__ */ jsx("div", {
|
|
2415
|
-
|
|
2316
|
+
className: "sb-motion-sample__track",
|
|
2416
2317
|
children: /* @__PURE__ */ jsx("div", {
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
left: phase === 1 ? "calc(100% - 32px)" : "4px",
|
|
2420
|
-
transition: `left ${scaledDuration}ms ${easing}`
|
|
2421
|
-
},
|
|
2318
|
+
className: cx("sb-motion-sample__ball", phase === 1 ? "sb-motion-sample__ball--end" : "sb-motion-sample__ball--start"),
|
|
2319
|
+
style: { transition: `left ${scaledDuration}ms ${easing}` },
|
|
2422
2320
|
"aria-hidden": true
|
|
2423
2321
|
})
|
|
2424
2322
|
});
|
|
@@ -2660,20 +2558,10 @@ function useSwatchbookData() {
|
|
|
2660
2558
|
}
|
|
2661
2559
|
//#endregion
|
|
2662
2560
|
//#region src/shadow-preview/ShadowSample.tsx
|
|
2663
|
-
const sampleStyle = {
|
|
2664
|
-
width: 120,
|
|
2665
|
-
height: 56,
|
|
2666
|
-
background: SURFACE_RAISED,
|
|
2667
|
-
border: BORDER_FAINT,
|
|
2668
|
-
borderRadius: 6
|
|
2669
|
-
};
|
|
2670
2561
|
function ShadowSample({ path }) {
|
|
2671
|
-
const cssVar = resolveCssVar(path, useProject());
|
|
2672
2562
|
return /* @__PURE__ */ jsx("div", {
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
boxShadow: cssVar
|
|
2676
|
-
},
|
|
2563
|
+
className: "sb-shadow-sample",
|
|
2564
|
+
style: { boxShadow: resolveCssVar(path, useProject()) },
|
|
2677
2565
|
"aria-hidden": true
|
|
2678
2566
|
});
|
|
2679
2567
|
}
|
|
@@ -3048,10 +2936,7 @@ function AxisVariance({ path }) {
|
|
|
3048
2936
|
}),
|
|
3049
2937
|
value,
|
|
3050
2938
|
/* @__PURE__ */ jsx("span", {
|
|
3051
|
-
|
|
3052
|
-
opacity: .6,
|
|
3053
|
-
marginLeft: 8
|
|
3054
|
-
},
|
|
2939
|
+
className: "sb-token-detail__constant-label-note",
|
|
3055
2940
|
children: "same across every axis"
|
|
3056
2941
|
})
|
|
3057
2942
|
]
|
|
@@ -3085,8 +2970,7 @@ function AxisVariance({ path }) {
|
|
|
3085
2970
|
"data-axis": axisName,
|
|
3086
2971
|
"data-context": row.ctx,
|
|
3087
2972
|
children: [/* @__PURE__ */ jsx("td", {
|
|
3088
|
-
className: "sb-token-detail__theme-cell",
|
|
3089
|
-
style: { width: "30%" },
|
|
2973
|
+
className: "sb-token-detail__theme-cell sb-token-detail__theme-cell--label",
|
|
3090
2974
|
children: row.ctx
|
|
3091
2975
|
}), /* @__PURE__ */ jsxs("td", {
|
|
3092
2976
|
className: "sb-token-detail__theme-cell",
|
|
@@ -3113,22 +2997,14 @@ function AxisVariance({ path }) {
|
|
|
3113
2997
|
children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", {
|
|
3114
2998
|
className: "sb-token-detail__theme-row",
|
|
3115
2999
|
children: [/* @__PURE__ */ jsxs("th", {
|
|
3116
|
-
className: "sb-token-detail__theme-cell",
|
|
3117
|
-
style: {
|
|
3118
|
-
textAlign: "left",
|
|
3119
|
-
opacity: .7
|
|
3120
|
-
},
|
|
3000
|
+
className: "sb-token-detail__theme-cell sb-token-detail__theme-cell--header",
|
|
3121
3001
|
children: [
|
|
3122
3002
|
rowAxis.name,
|
|
3123
3003
|
" \\ ",
|
|
3124
3004
|
colAxis.name
|
|
3125
3005
|
]
|
|
3126
3006
|
}), colAxis.contexts.map((col) => /* @__PURE__ */ jsx("th", {
|
|
3127
|
-
className: "sb-token-detail__theme-cell",
|
|
3128
|
-
style: {
|
|
3129
|
-
textAlign: "left",
|
|
3130
|
-
opacity: .7
|
|
3131
|
-
},
|
|
3007
|
+
className: "sb-token-detail__theme-cell sb-token-detail__theme-cell--header",
|
|
3132
3008
|
children: col
|
|
3133
3009
|
}, col))]
|
|
3134
3010
|
}) }), /* @__PURE__ */ jsx("tbody", { children: rowAxis.contexts.map((row) => /* @__PURE__ */ jsxs("tr", {
|
|
@@ -3158,8 +3034,7 @@ function AxisVariance({ path }) {
|
|
|
3158
3034
|
}, row)) })]
|
|
3159
3035
|
}),
|
|
3160
3036
|
extra.length > 0 && /* @__PURE__ */ jsxs("div", {
|
|
3161
|
-
className: "sb-token-detail__aliased-by-truncated",
|
|
3162
|
-
style: { marginTop: 6 },
|
|
3037
|
+
className: "sb-token-detail__aliased-by-truncated sb-token-detail__aliased-by-truncated--axis-note",
|
|
3163
3038
|
children: [
|
|
3164
3039
|
"Values also vary with ",
|
|
3165
3040
|
extra.map((a) => a.name).join(", "),
|
|
@@ -3270,7 +3145,7 @@ function CompositeBreakdownContent({ type, rawValue, partialAliasOf, resolved, c
|
|
|
3270
3145
|
children: layers.map((layer, i) => {
|
|
3271
3146
|
const v = layer;
|
|
3272
3147
|
return /* @__PURE__ */ jsxs("div", {
|
|
3273
|
-
|
|
3148
|
+
className: "sb-token-detail__shadow-layer",
|
|
3274
3149
|
children: [
|
|
3275
3150
|
multi && /* @__PURE__ */ jsxs("div", {
|
|
3276
3151
|
className: "sb-token-detail__breakdown-layer-header",
|
|
@@ -3612,11 +3487,8 @@ function TransitionSample({ transition, durationMs }) {
|
|
|
3612
3487
|
return /* @__PURE__ */ jsx("div", {
|
|
3613
3488
|
className: "sb-token-detail__motion-track",
|
|
3614
3489
|
children: /* @__PURE__ */ jsx("div", {
|
|
3615
|
-
className: "sb-token-detail__motion-ball",
|
|
3616
|
-
style: {
|
|
3617
|
-
left: phase === 1 ? "calc(100% - 28px)" : "4px",
|
|
3618
|
-
transition
|
|
3619
|
-
},
|
|
3490
|
+
className: cx("sb-token-detail__motion-ball", phase === 1 ? "sb-token-detail__motion-ball--end" : "sb-token-detail__motion-ball--start"),
|
|
3491
|
+
style: { transition },
|
|
3620
3492
|
"aria-hidden": true
|
|
3621
3493
|
})
|
|
3622
3494
|
});
|
|
@@ -3840,7 +3712,7 @@ function TokenDetail({ path, heading }) {
|
|
|
3840
3712
|
outOfGamut && /* @__PURE__ */ jsx("span", {
|
|
3841
3713
|
title: "Out of sRGB gamut for this format",
|
|
3842
3714
|
"aria-label": "out of gamut",
|
|
3843
|
-
|
|
3715
|
+
className: "sb-token-detail__out-of-gamut-icon",
|
|
3844
3716
|
children: "⚠"
|
|
3845
3717
|
}),
|
|
3846
3718
|
/* @__PURE__ */ jsx(CopyButton$1, {
|
|
@@ -4314,7 +4186,10 @@ function TokenNavigator({ root, type, initiallyExpanded = 1, searchable = true,
|
|
|
4314
4186
|
}, [visibleTree, searchExpanded]);
|
|
4315
4187
|
if (tree.length === 0) return /* @__PURE__ */ jsx("div", {
|
|
4316
4188
|
...blockWrapperAttrs(cssVarPrefix, activeAxes),
|
|
4317
|
-
children: /* @__PURE__ */ jsx(
|
|
4189
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
4190
|
+
className: "sb-block__empty",
|
|
4191
|
+
children: root ? `No tokens under "${root}"${typeFilter ? ` matching ${typeLabel.slice(3)}` : ""}.` : typeFilter ? `No tokens matching ${typeLabel.slice(3)} in the active theme.` : "No tokens in the active theme."
|
|
4192
|
+
})
|
|
4318
4193
|
});
|
|
4319
4194
|
return /* @__PURE__ */ jsxs("div", {
|
|
4320
4195
|
...blockWrapperAttrs(cssVarPrefix, activeAxes),
|