@unpunnyfuns/swatchbook-blocks 1.1.0 → 1.2.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.mjs CHANGED
@@ -95,57 +95,6 @@ function useChannelGlobals() {
95
95
  return useSyncExternalStore(subscribe$2, getSnapshot$1, getServerSnapshot$1);
96
96
  }
97
97
  //#endregion
98
- //#region src/contexts.ts
99
- /**
100
- * Context carrying the full {@link ProjectSnapshot}. `null` sentinel lets
101
- * `useSwatchbookData()` tell "provider present" from "fall back to the
102
- * virtual module".
103
- */
104
- const SwatchbookContext = createContext(null);
105
- function useOptionalSwatchbookData() {
106
- return useContext(SwatchbookContext);
107
- }
108
- /**
109
- * Active swatchbook theme for the current story/docs render. Populated by
110
- * the addon's preview decorator and consumed by `useToken` + any future
111
- * consumer hooks.
112
- *
113
- * This runs through plain React context rather than Storybook's
114
- * `useGlobals` so the same hook works in autodocs / MDX renders where the
115
- * preview-hooks context isn't available.
116
- */
117
- const ThemeContext = createContext("");
118
- function useActiveTheme() {
119
- return useContext(ThemeContext);
120
- }
121
- /**
122
- * Active axis tuple for the current story/docs render — `Record<axisName,
123
- * contextName>`. Derived from the same input as {@link ThemeContext}; split
124
- * out so consumers needing per-axis info (toolbar, panel, tuple-aware
125
- * blocks) don't have to reparse the composed theme name.
126
- */
127
- const AxesContext = createContext({});
128
- function useActiveAxes() {
129
- return useContext(AxesContext);
130
- }
131
- /**
132
- * Active color-display format for the current story/docs render. Populated
133
- * by the addon's preview decorator from the `swatchbookColorFormat` global
134
- * (per-story `globals` or toolbar dropdown) and consumed by blocks that
135
- * render color-token values. Emitted CSS is unaffected.
136
- *
137
- * Runs through plain React context rather than Storybook's `useGlobals` so
138
- * per-story seeded globals flow through on first render and the same hook
139
- * is safe to call from MDX doc blocks (where the preview-hooks context
140
- * isn't available).
141
- */
142
- const ColorFormatContext = createContext(null);
143
- function useColorFormat() {
144
- const contextValue = useContext(ColorFormatContext);
145
- const channelGlobals = useChannelGlobals();
146
- return contextValue ?? channelGlobals.format ?? "hex";
147
- }
148
- //#endregion
149
98
  //#region src/internal/channel-tokens.ts
150
99
  /**
151
100
  * Host adapter API — same integration tier as {@link BlockChannel} /
@@ -184,6 +133,7 @@ let snapshot = {
184
133
  axisContexts: {}
185
134
  },
186
135
  defaultTuple: {},
136
+ defaultColorFormat: "hex",
187
137
  version: 0
188
138
  };
189
139
  const listeners = /* @__PURE__ */ new Set();
@@ -199,6 +149,7 @@ function applyPatch(patch) {
199
149
  listing: patch.listing ?? snapshot.listing,
200
150
  tokenGraph: patch.tokenGraph ?? snapshot.tokenGraph,
201
151
  defaultTuple: patch.defaultTuple ?? snapshot.defaultTuple,
152
+ defaultColorFormat: patch.defaultColorFormat ?? snapshot.defaultColorFormat,
202
153
  version: snapshot.version + 1
203
154
  };
204
155
  for (const cb of listeners) cb();
@@ -245,6 +196,73 @@ function useTokenSnapshot() {
245
196
  return useSyncExternalStore(subscribe$1, getSnapshot, getServerSnapshot);
246
197
  }
247
198
  //#endregion
199
+ //#region src/contexts.ts
200
+ /**
201
+ * Context carrying the full {@link ProjectSnapshot}. `null` sentinel lets
202
+ * `useSwatchbookData()` tell "provider present" from "fall back to the
203
+ * virtual module".
204
+ */
205
+ const SwatchbookContext = createContext(null);
206
+ function useOptionalSwatchbookData() {
207
+ return useContext(SwatchbookContext);
208
+ }
209
+ /**
210
+ * Active swatchbook theme for the current story/docs render. Populated by
211
+ * the addon's preview decorator and consumed by `useToken` + any future
212
+ * consumer hooks.
213
+ *
214
+ * This runs through plain React context rather than Storybook's
215
+ * `useGlobals` so the same hook works in autodocs / MDX renders where the
216
+ * preview-hooks context isn't available.
217
+ */
218
+ const ThemeContext = createContext("");
219
+ function useActiveTheme() {
220
+ return useContext(ThemeContext);
221
+ }
222
+ /**
223
+ * Active axis tuple for the current story/docs render — `Record<axisName,
224
+ * contextName>`. Derived from the same input as {@link ThemeContext}; split
225
+ * out so consumers needing per-axis info (toolbar, panel, tuple-aware
226
+ * blocks) don't have to reparse the composed theme name.
227
+ */
228
+ const AxesContext = createContext({});
229
+ function useActiveAxes() {
230
+ return useContext(AxesContext);
231
+ }
232
+ /**
233
+ * Active color-display format for the current story/docs render, consumed
234
+ * by blocks that render color-token values. Emitted CSS is unaffected.
235
+ *
236
+ * Sits in the middle of the precedence chain a block resolves via
237
+ * `colorFormat ?? useColorFormat()`: a block's own `colorFormat` prop wins
238
+ * over this context, which wins over the active snapshot's
239
+ * `defaultColorFormat` (from `Config.defaultColorFormat`). "Active
240
+ * snapshot" is whichever source is actually feeding the render:
241
+ * `SwatchbookProvider` when a story decorator mounted one, otherwise the
242
+ * channel-fed `TokenSnapshot` that MDX-embedded blocks (no `<Story/>`, no
243
+ * provider) read through `useProject()`'s fallback path.
244
+ *
245
+ * Runs through plain React context rather than Storybook's `useGlobals` so
246
+ * per-story seeded globals flow through on first render and the same hook
247
+ * is safe to call from MDX doc blocks (where the preview-hooks context
248
+ * isn't available).
249
+ */
250
+ const ColorFormatContext = createContext(null);
251
+ /**
252
+ * Resolves the color-display format from the context/snapshot/default
253
+ * chain: `ColorFormatContext` → active snapshot's `defaultColorFormat` →
254
+ * `'hex'`. Composing blocks read `colorFormat ?? useColorFormat()` to give
255
+ * their own `colorFormat` prop top precedence over this chain.
256
+ */
257
+ function useColorFormat() {
258
+ const contextValue = useContext(ColorFormatContext);
259
+ const channelGlobals = useChannelGlobals();
260
+ const snapshot = useContext(SwatchbookContext);
261
+ const tokenSnapshot = useTokenSnapshot();
262
+ const activeDefault = snapshot ? snapshot.defaultColorFormat : tokenSnapshot.defaultColorFormat;
263
+ return contextValue ?? channelGlobals.format ?? activeDefault ?? "hex";
264
+ }
265
+ //#endregion
248
266
  //#region src/internal/use-project.ts
249
267
  function computeVarianceByPath(graph) {
250
268
  if (!graph) return {};
@@ -687,23 +705,24 @@ function BorderPreviewView({ rows, activeTheme, cssVarPrefix, activeAxes, filter
687
705
  }, row.path))]
688
706
  });
689
707
  }
690
- function BorderPreview({ filter, caption, sortBy = "path", sortDir = "asc" }) {
708
+ function BorderPreview({ filter, caption, sortBy = "path", sortDir = "asc", colorFormat }) {
691
709
  const project = useProject();
692
710
  const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;
693
- const colorFormat = useColorFormat();
711
+ const contextColorFormat = useColorFormat();
712
+ const format = colorFormat ?? contextColorFormat;
694
713
  return /* @__PURE__ */ jsx(BorderPreviewView, {
695
714
  rows: useMemo(() => deriveBorderRows(resolved, project, {
696
715
  filter,
697
716
  sortBy,
698
717
  sortDir,
699
- colorFormat
718
+ colorFormat: format
700
719
  }), [
701
720
  resolved,
702
721
  project,
703
722
  filter,
704
723
  sortBy,
705
724
  sortDir,
706
- colorFormat
725
+ format
707
726
  ]),
708
727
  activeTheme,
709
728
  cssVarPrefix,
@@ -812,16 +831,17 @@ function ColorPaletteView({ groups, activeTheme, cssVarPrefix, activeAxes, filte
812
831
  }, group))]
813
832
  });
814
833
  }
815
- function ColorPalette({ filter, groupBy, caption, sortBy = "path", sortDir = "asc" }) {
834
+ function ColorPalette({ filter, groupBy, caption, sortBy = "path", sortDir = "asc", colorFormat }) {
816
835
  const { resolved, activeTheme, activeAxes, cssVarPrefix, listing } = useProject();
817
- const colorFormat = useColorFormat();
836
+ const contextColorFormat = useColorFormat();
837
+ const format = colorFormat ?? contextColorFormat;
818
838
  return /* @__PURE__ */ jsx(ColorPaletteView, {
819
839
  groups: useMemo(() => deriveColorPaletteGroups(resolved, listing, cssVarPrefix, {
820
840
  filter,
821
841
  groupBy,
822
842
  sortBy,
823
843
  sortDir,
824
- colorFormat
844
+ colorFormat: format
825
845
  }), [
826
846
  resolved,
827
847
  listing,
@@ -830,7 +850,7 @@ function ColorPalette({ filter, groupBy, caption, sortBy = "path", sortDir = "as
830
850
  groupBy,
831
851
  sortBy,
832
852
  sortDir,
833
- colorFormat
853
+ format
834
854
  ]),
835
855
  activeTheme,
836
856
  cssVarPrefix,
@@ -1402,9 +1422,10 @@ function ColorTableView({ groups, activeTheme, cssVarPrefix, activeAxes, colorFo
1402
1422
  * selector; clicking a row expands it in place to show the description,
1403
1423
  * alias chain, and (for grouped rows) every variant's hex/HSL/OKLCH values.
1404
1424
  */
1405
- function ColorTable({ filter, caption, sortBy = "path", sortDir = "asc", searchable = true, onSelect, variants, id, indicators }) {
1425
+ function ColorTable({ filter, caption, sortBy = "path", sortDir = "asc", searchable = true, onSelect, variants, id, indicators, colorFormat }) {
1406
1426
  const { resolved, activeTheme, activeAxes, cssVarPrefix, listing, varianceByPath } = useProject();
1407
- const colorFormat = useColorFormat();
1427
+ const contextColorFormat = useColorFormat();
1428
+ const format = colorFormat ?? contextColorFormat;
1408
1429
  const enabledIndicators = useMemo(() => ({
1409
1430
  ...resolveIndicators(indicators),
1410
1431
  gamut: false
@@ -1420,7 +1441,7 @@ function ColorTable({ filter, caption, sortBy = "path", sortDir = "asc", searcha
1420
1441
  variants,
1421
1442
  sortBy,
1422
1443
  sortDir,
1423
- colorFormat
1444
+ colorFormat: format
1424
1445
  }), [
1425
1446
  resolved,
1426
1447
  listing,
@@ -1430,12 +1451,12 @@ function ColorTable({ filter, caption, sortBy = "path", sortDir = "asc", searcha
1430
1451
  variants,
1431
1452
  sortBy,
1432
1453
  sortDir,
1433
- colorFormat
1454
+ format
1434
1455
  ]),
1435
1456
  activeTheme,
1436
1457
  cssVarPrefix,
1437
1458
  activeAxes,
1438
- colorFormat,
1459
+ colorFormat: format,
1439
1460
  enabledIndicators,
1440
1461
  blockKey,
1441
1462
  filter,
@@ -2425,15 +2446,16 @@ function GradientPaletteView({ rows, activeTheme, cssVarPrefix, activeAxes, filt
2425
2446
  }, row.path))]
2426
2447
  });
2427
2448
  }
2428
- function GradientPalette({ filter, caption, sortBy = "path", sortDir = "asc" }) {
2449
+ function GradientPalette({ filter, caption, sortBy = "path", sortDir = "asc", colorFormat }) {
2429
2450
  const { resolved, activeTheme, activeAxes, cssVarPrefix, listing } = useProject();
2430
- const colorFormat = useColorFormat();
2451
+ const contextColorFormat = useColorFormat();
2452
+ const format = colorFormat ?? contextColorFormat;
2431
2453
  return /* @__PURE__ */ jsx(GradientPaletteView, {
2432
2454
  rows: useMemo(() => deriveGradientRows(resolved, listing, cssVarPrefix, {
2433
2455
  filter,
2434
2456
  sortBy,
2435
2457
  sortDir,
2436
- colorFormat
2458
+ colorFormat: format
2437
2459
  }), [
2438
2460
  resolved,
2439
2461
  listing,
@@ -2441,7 +2463,7 @@ function GradientPalette({ filter, caption, sortBy = "path", sortDir = "asc" })
2441
2463
  filter,
2442
2464
  sortBy,
2443
2465
  sortDir,
2444
- colorFormat
2466
+ format
2445
2467
  ]),
2446
2468
  activeTheme,
2447
2469
  cssVarPrefix,
@@ -3017,23 +3039,24 @@ function Layer({ layer, index, total }) {
3017
3039
  })]
3018
3040
  });
3019
3041
  }
3020
- function ShadowPreview({ filter, caption, sortBy = "path", sortDir = "asc" }) {
3042
+ function ShadowPreview({ filter, caption, sortBy = "path", sortDir = "asc", colorFormat }) {
3021
3043
  const project = useProject();
3022
3044
  const { resolved, activeTheme, activeAxes, cssVarPrefix } = project;
3023
- const colorFormat = useColorFormat();
3045
+ const contextColorFormat = useColorFormat();
3046
+ const format = colorFormat ?? contextColorFormat;
3024
3047
  return /* @__PURE__ */ jsx(ShadowPreviewView, {
3025
3048
  rows: useMemo(() => deriveShadowRows(resolved, project, {
3026
3049
  filter,
3027
3050
  sortBy,
3028
3051
  sortDir,
3029
- colorFormat
3052
+ colorFormat: format
3030
3053
  }), [
3031
3054
  resolved,
3032
3055
  project,
3033
3056
  filter,
3034
3057
  sortBy,
3035
3058
  sortDir,
3036
- colorFormat
3059
+ format
3037
3060
  ]),
3038
3061
  activeTheme,
3039
3062
  cssVarPrefix,
@@ -3280,12 +3303,13 @@ function treeHasTruncation(nodes) {
3280
3303
  }
3281
3304
  //#endregion
3282
3305
  //#region src/token-detail/AxisVariance.tsx
3283
- function AxisVariance({ path }) {
3306
+ function AxisVariance({ path, colorFormat }) {
3284
3307
  const { token, cssVar, axes, activeAxes, cssVarPrefix, varianceByPath, resolveAt } = useTokenDetailData(path);
3285
- const colorFormat = useColorFormat();
3308
+ const contextColorFormat = useColorFormat();
3309
+ const format = colorFormat ?? contextColorFormat;
3286
3310
  const tokenType = token?.$type;
3287
3311
  const isColor = tokenType === "color";
3288
- const formatFn = (t) => valueFor(t, tokenType, colorFormat);
3312
+ const formatFn = (t) => valueFor(t, tokenType, format);
3289
3313
  const variance = useMemo(() => {
3290
3314
  const result = varianceByPath[path];
3291
3315
  if (!result) return { kind: "constant" };
@@ -3438,16 +3462,17 @@ function valueFor(token, $type, format) {
3438
3462
  }
3439
3463
  //#endregion
3440
3464
  //#region src/token-detail/CompositeBreakdown.tsx
3441
- function CompositeBreakdown({ path }) {
3465
+ function CompositeBreakdown({ path, colorFormat }) {
3442
3466
  const { token, resolved } = useTokenDetailData(path);
3443
- const colorFormat = useColorFormat();
3467
+ const contextColorFormat = useColorFormat();
3468
+ const format = colorFormat ?? contextColorFormat;
3444
3469
  if (!token) return null;
3445
3470
  return /* @__PURE__ */ jsx(CompositeBreakdownContent, {
3446
3471
  type: token.$type,
3447
3472
  rawValue: token.$value,
3448
3473
  partialAliasOf: token.partialAliasOf,
3449
3474
  resolved,
3450
- colorFormat
3475
+ colorFormat: format
3451
3476
  });
3452
3477
  }
3453
3478
  function CompositeBreakdownContent({ type, rawValue, partialAliasOf, resolved, colorFormat }) {
@@ -4166,12 +4191,13 @@ function TokenDetailView({ path, heading, token, cssVar, activeTheme, activeAxes
4166
4191
  ]
4167
4192
  });
4168
4193
  }
4169
- function TokenDetail({ path, heading }) {
4194
+ function TokenDetail({ path, heading, colorFormat }) {
4170
4195
  const { token, cssVar, activeTheme, activeAxes, cssVarPrefix } = useTokenDetailData(path);
4171
- const colorFormat = useColorFormat();
4196
+ const contextColorFormat = useColorFormat();
4197
+ const format = colorFormat ?? contextColorFormat;
4172
4198
  const { listing } = useProject();
4173
- const derived = deriveTokenDetail(path, token, listing, colorFormat);
4174
- return /* @__PURE__ */ jsx(TokenDetailView, {
4199
+ const derived = deriveTokenDetail(path, token, listing, format);
4200
+ const view = /* @__PURE__ */ jsx(TokenDetailView, {
4175
4201
  path,
4176
4202
  ...heading !== void 0 && { heading },
4177
4203
  token,
@@ -4181,6 +4207,10 @@ function TokenDetail({ path, heading }) {
4181
4207
  cssVarPrefix,
4182
4208
  ...derived
4183
4209
  });
4210
+ return colorFormat !== void 0 ? /* @__PURE__ */ jsx(ColorFormatContext.Provider, {
4211
+ value: colorFormat,
4212
+ children: view
4213
+ }) : view;
4184
4214
  }
4185
4215
  //#endregion
4186
4216
  //#region src/internal/DetailOverlay.tsx
@@ -4730,14 +4760,14 @@ function TokenNavigatorView({ resolved, root, enabledIndicators, cssVarPrefix, a
4730
4760
  * navigation. Click a leaf to inspect it in a slide-over (unless `onSelect`
4731
4761
  * is provided, which hands the follow-up to the consumer).
4732
4762
  */
4733
- function TokenNavigator({ root, type, initiallyExpanded = 1, searchable = true, onSelect, id, indicators }) {
4763
+ function TokenNavigator({ root, type, initiallyExpanded = 1, searchable = true, onSelect, id, indicators, colorFormat }) {
4734
4764
  const { resolved, activeTheme, activeAxes, cssVarPrefix, indicators: indicatorBaseline } = useProject();
4735
4765
  const blockKey = useBlockKey("TokenNavigator", [
4736
4766
  root,
4737
4767
  type === void 0 ? "" : typeof type === "string" ? type : type.join(","),
4738
4768
  id
4739
4769
  ]);
4740
- return /* @__PURE__ */ jsx(TokenNavigatorView, {
4770
+ const view = /* @__PURE__ */ jsx(TokenNavigatorView, {
4741
4771
  resolved,
4742
4772
  root,
4743
4773
  enabledIndicators: useMemo(() => resolveIndicators(indicators, indicatorBaseline), [indicators, indicatorBaseline]),
@@ -4750,6 +4780,10 @@ function TokenNavigator({ root, type, initiallyExpanded = 1, searchable = true,
4750
4780
  searchable,
4751
4781
  onSelect
4752
4782
  });
4783
+ return colorFormat !== void 0 ? /* @__PURE__ */ jsx(ColorFormatContext.Provider, {
4784
+ value: colorFormat,
4785
+ children: view
4786
+ }) : view;
4753
4787
  }
4754
4788
  function TreeNodeRow({ node, expanded, focusedPath, registerTreeItem, onToggle, onFocusPath, onLeafClick, root, resolveInView, onNavigate, enabled, level, setsize, posinset }) {
4755
4789
  if (node.kind === "leaf") return /* @__PURE__ */ jsx(LeafRow, {
@@ -5207,9 +5241,10 @@ function TokenTableView({ rows, activeTheme, cssVarPrefix, activeAxes, colorForm
5207
5241
  * slide-over (unless `onSelect` is provided, which hands the follow-up to the
5208
5242
  * consumer).
5209
5243
  */
5210
- function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", searchable = true, onSelect, id, indicators }) {
5244
+ function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", searchable = true, onSelect, id, indicators, colorFormat }) {
5211
5245
  const { resolved, activeTheme, activeAxes, cssVarPrefix, listing, varianceByPath, indicators: indicatorBaseline } = useProject();
5212
- const colorFormat = useColorFormat();
5246
+ const contextColorFormat = useColorFormat();
5247
+ const format = colorFormat ?? contextColorFormat;
5213
5248
  const rootFontSize = useRootFontSize();
5214
5249
  const blockKey = useBlockKey("TokenTable", [
5215
5250
  filter,
@@ -5218,13 +5253,13 @@ function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", s
5218
5253
  id
5219
5254
  ]);
5220
5255
  const enabledIndicators = useMemo(() => resolveIndicators(indicators, indicatorBaseline), [indicators, indicatorBaseline]);
5221
- return /* @__PURE__ */ jsx(TokenTableView, {
5256
+ const view = /* @__PURE__ */ jsx(TokenTableView, {
5222
5257
  rows: useMemo(() => deriveTokenRows(resolved, listing, cssVarPrefix, varianceByPath, {
5223
5258
  filter,
5224
5259
  type,
5225
5260
  sortBy,
5226
5261
  sortDir,
5227
- colorFormat,
5262
+ colorFormat: format,
5228
5263
  rootFontSizePx: rootFontSize
5229
5264
  }), [
5230
5265
  resolved,
@@ -5235,13 +5270,13 @@ function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", s
5235
5270
  type,
5236
5271
  sortBy,
5237
5272
  sortDir,
5238
- colorFormat,
5273
+ format,
5239
5274
  rootFontSize
5240
5275
  ]),
5241
5276
  activeTheme,
5242
5277
  cssVarPrefix,
5243
5278
  activeAxes,
5244
- colorFormat,
5279
+ colorFormat: format,
5245
5280
  enabledIndicators,
5246
5281
  validPaths: useMemo(() => new Set(Object.keys(resolved)), [resolved]),
5247
5282
  blockKey,
@@ -5251,6 +5286,10 @@ function TokenTable({ filter, type, caption, sortBy = "path", sortDir = "asc", s
5251
5286
  searchable,
5252
5287
  onSelect
5253
5288
  });
5289
+ return colorFormat !== void 0 ? /* @__PURE__ */ jsx(ColorFormatContext.Provider, {
5290
+ value: colorFormat,
5291
+ children: view
5292
+ }) : view;
5254
5293
  }
5255
5294
  //#endregion
5256
5295
  //#region src/TypographyScale.tsx