@razorwind/storybook 0.0.59 → 0.0.61

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.cjs CHANGED
@@ -1,5 +1,11 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});let e=require("@razorwind/core/plugin"),t=require("@razorwind/core/lib/fonts"),n=require("@razorwind/core/utils"),r=require("@stryke/path/join");function i(e,t={}){let r=t.cssVarPrefix??`rw`;return(0,n.flattenTokens)(e,{includeTypes:t.includeTypes,enrichToken:e=>({...e,cssVar:(0,n.toCssVar)(e.path,r)})})}function a(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`).replaceAll(`
2
- `,`\\n`).replaceAll(`\r`,`\\r`)}function o(e){return typeof e==`string`?`"${a(e)}"`:typeof e==`number`||typeof e==`boolean`?String(e):e==null?`undefined`:JSON.stringify(e)}function s(e){let t=e.titlePrefix??`Design Tokens`,n=e.themeFiles?.[0],r=e.themeNames??[],i=n?r.length>1?`
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});let e=require("@razorwind/core/plugin"),t=require("@razorwind/core/lib/fonts"),n=require("@razorwind/core/utils"),r=require("@stryke/path/join");function i(e){return e===!0||e===`true`||e===1}function a(e,t){return e?`${e}:${t}`:t}function o(e){let t=e.theme??e.$theme;return typeof t==`string`&&t.length>0?t:void 0}function s(e,t){return e===`palette`||e===`$palette`?typeof t==`boolean`||typeof t==`number`||typeof t==`string`:(e===`theme`||e===`$theme`)&&typeof t==`string`}function c(e){let t=new Map;function r(e,c,l,u,d){if(!(0,n.isObject)(e))return;let f=u||i(e.palette)||i(e.$palette),p=o(e)??d;if((0,n.isTokenLeaf)(e)){(f||p)&&t.set(a(l,c.join(`.`)),{...f&&{palette:!0},...p&&{childTheme:p}});return}for(let[t,n]of Object.entries(e))t.startsWith(`$`)&&t!==`$palette`&&t!==`$theme`||s(t,n)||r(n,[...c,t],l,f,p)}for(let t of(0,n.resolveTokenSets)(e)){let e=t.id==="default"?void 0:t.id;r(t.tokens,[],e,!1,void 0)}return t}function l(e,t={}){let r=t.cssVarPrefix??`rw`,i=c(e);return(0,n.flattenTokens)(e,{includeTypes:t.includeTypes,shouldIncludeToken:e=>e.skipDocs!==!0,enrichToken:e=>{let t=i.get(a(e.theme,e.path));return{...e,cssVar:(0,n.toCssVar)(e.path,r),...e.type===`color`&&t}}})}function u(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`).replaceAll(`
2
+ `,`\\n`).replaceAll(`\r`,`\\r`)}function d(e){return typeof e==`string`?`"${u(e)}"`:typeof e==`number`||typeof e==`boolean`?String(e):e==null?`undefined`:JSON.stringify(e)}function f(e){let t=e.titlePrefix??`Design Tokens`,n=e.themeFiles?.[0],r=e.themeNames??[],i=e.tokenThemeNames??[],a=i.length>1?`
3
+ ## Token-doc variants
4
+
5
+ Generated token blocks follow Storybook's \`theme\` global when it matches one
6
+ of these token-set names: ${i.map(e=>`\`${e}\``).join(`, `)}.
7
+ Pass \`theme\` directly to a block to override that selection.
8
+ `:``,o=n?r.length>1?`
3
9
  ## Storybook UI theme
4
10
 
5
11
  Generated theme module:
@@ -40,7 +46,7 @@ Generated by \`@razorwind/storybook\`.
40
46
  - \`${e.outputPath}/Tokens.mdx\` — token overview (${t})
41
47
  - \`${e.outputPath}/blocks/\` — React doc blocks (ColorPalette, Typeset, …)
42
48
  - \`${e.outputPath}/tokens.json\` — flattened token manifest
43
- ${i}
49
+ ${o}${a}
44
50
  ## Setup
45
51
 
46
52
  1. Add the generated MDX pages to Storybook (paths depend on your \`stories\` config):
@@ -65,46 +71,106 @@ import { ColorPaletteBlock } from "./blocks";
65
71
  ## Regenerate
66
72
 
67
73
  Re-run Razorwind generate when tokens change to refresh docs under \`${e.outputPath}/\`.
68
- `}function c(e,t){let n=new Map;for(let r of e){let e=r.path.split(`.`).slice(0,Math.max(t,1)).join(`.`)||r.path,i=n.get(e)??[];i.push(r),n.set(e,i)}return n}function l(e,t){return e===t?e.split(`.`).at(-1)??e:e.startsWith(`${t}.`)?e.slice(t.length+1):e.split(`.`).at(-1)??e}function u(e,t={}){return`import { ColorPalette, ColorItem } from "@storybook/addon-docs/blocks";
74
+ `}const p=new Set([`fontFamily`,`fontWeight`,`typography`]),m=/font|typography|type|text|line[-_.]?height|letter[-_.]?spacing/i;function h(e){return p.has(e.type??``)?!0:(e.type===`dimension`||e.type===`number`)&&m.test(e.path)}function g(e,t){return e.some(e=>t.some(t=>e.path===t||e.path.startsWith(`${t}.`)))}const _=/^\{([^{}]+)\}$/,v=/^var\((--[^),\s]+)(?:\s*,[^)]*)?\)$/;function y(e){if(typeof e==`string`)return _.exec(e.trim())?.[1]?.trim()}function b(e){if(typeof e==`string`)return v.exec(e.trim())?.[1]}function x(e){let t=new Map(e.map(e=>[e.path,e])),r=new Map(e.map(e=>[(0,n.toThemeCssVar)(e.path),e])),i=e=>{let n=e,i=new Set;for(let a=0;a<8;a++){if(i.has(n.path))return e.cssValue;i.add(n.path);let a=t.get(y(n.value)??``)??r.get(b(n.value)??b(n.cssValue)??``);if(!a||a.path===n.path)return n.cssValue;n=a}return e.cssValue};return e.map(e=>e.type===`color`?{...e,cssValue:i(e)}:e)}function S(e){return Object.keys(e).length>1}function ee(){return`import { useGlobals } from "storybook/preview-api";
69
75
 
70
76
  /**
71
- * Color tokens rendered with Storybook's ColorPalette doc block.
72
- *
73
- * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-colorpalette
77
+ * Select a generated token variant. By default this follows Storybook's
78
+ * \`theme\` global; callers may pass \`theme\` to override it.
74
79
  */
75
- export function ColorPaletteBlock() {
76
- return (
77
- <ColorPalette>
78
- ${[...c(e.filter(e=>e.type===`color`),t.colorGroupBy??2).entries()].toSorted(([e],[t])=>e.localeCompare(t)).map(([e,t])=>{let n=t.map(t=>` ${o(l(t.path,e))}: ${o(t.cssValue)}`).join(`,
79
- `),r=t.find(e=>e.description)?.description??`${t.length} token${t.length===1?``:`s`}`;return` <ColorItem
80
- title={${o(e)}}
81
- subtitle={${o(r)}}
80
+ export function useThemeVariant<T extends Record<string, unknown>>(
81
+ variants: T,
82
+ fallback: keyof T & string,
83
+ theme?: string
84
+ ): keyof T & string {
85
+ const [globals] = useGlobals();
86
+ const candidate = theme ?? globals.theme;
87
+
88
+ return typeof candidate === "string" && candidate in variants
89
+ ? (candidate as keyof T & string)
90
+ : fallback;
91
+ }
92
+ `}function C(e,t){let r=(0,n.resolveTokenSets)(e),i=r.filter(e=>!(0,n.isSharedThemeId)(e.id));return i.length<=1?{default:x(l(e,t))}:Object.fromEntries(i.map(e=>[e.id,x(l(B(r,e),t))]))}function w(e,t){let n=new Map;for(let r of e){let e=r.path.split(`.`).slice(0,Math.max(t,1)).join(`.`)||r.path,i=n.get(e)??[];i.push(r),n.set(e,i)}return n}function T(e,t){return e===t?e.split(`.`).at(-1)??e:e.startsWith(`${t}.`)?e.slice(t.length+1):e.split(`.`).at(-1)??e}function E(e,t={}){let n=t.colorGroupBy??2,r=Object.entries(e),i=r[0]?.[0]??`default`,a=S(e),o=(e,t=` `)=>[...w(e,n).entries()].toSorted(([e],[t])=>e.localeCompare(t)).map(([e,n])=>{let r=n.map(n=>`${t} ${d(T(n.path,e))}: ${d(n.cssValue)}`).join(`,
93
+ `),i=n.find(e=>e.description)?.description??`${n.length} token${n.length===1?``:`s`}`;return`${t}<ColorItem
94
+ title={${d(e)}}
95
+ subtitle={${d(i)}}
82
96
  colors={{
83
- ${n}
97
+ ${r}
84
98
  }}
85
99
  />`}).join(`
86
- `)||` {/* No color tokens */}`}
87
- </ColorPalette>
88
- );
100
+ `),s=e=>{let t=e.filter(e=>e.type===`color`),n=t.filter(e=>e.palette),r=t.filter(e=>!e.palette&&e.childTheme),i=t.filter(e=>!e.palette&&!e.childTheme),a=n.length>0||r.length>0,s=o(t),c=[[`Color palettes`,n],[`Semantic colors`,r],[`Colors`,i]].filter(e=>!!e[1]?.length).map(([e,t])=>` <section>
101
+ <h2>${e}</h2>
102
+ <ColorPalette>
103
+ ${o(t,` `)}
104
+ </ColorPalette>
105
+ </section>`).join(`
106
+ `);return a?`<>\n${c}\n </>`:`<ColorPalette>\n${s||` {/* No color tokens */}`}\n </ColorPalette>`},c=r.map(([e,t])=>` ${d(e)}: (\n ${s(t)}\n )`).join(`,
107
+ `);return`import { ColorPalette, ColorItem } from "@storybook/addon-docs/blocks";
108
+ ${a?`import { useThemeVariant } from "./ThemeVariant";
109
+ `:``}
110
+
111
+ /**
112
+ * Color tokens rendered with Storybook's ColorPalette doc block.
113
+ *
114
+ * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-colorpalette
115
+ */
116
+ const COLOR_VARIANTS = {
117
+ ${c}
118
+ };
119
+
120
+ export interface ColorPaletteBlockProps {
121
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
122
+ theme?: string;
89
123
  }
90
- `}function d(e,n={}){let r=n.sampleText??`The quick brown fox jumps over the lazy dog`,i=e.filter(e=>e.type===`dimension`&&/(?:font|type|text).*size|size.*(?:font|type|text)/i.test(e.path)).map(e=>{let t=/^(\d+(?:\.\d+)?)/.exec(e.cssValue);return t?Number(t[1]):e.cssValue}),a=[...new Set(i)],s=(0,t.pickFontByRole)(n.fonts,t.SANS_ROLES),c=(s?(0,t.cssFontFamily)(s):void 0)??e.find(e=>e.type===`fontFamily`)?.cssValue??`system-ui, sans-serif`,l=e.find(e=>e.type===`fontWeight`),u=l&&Number.parseFloat(l.cssValue)||400,d=a.length>0?`[${a.map(e=>o(e)).join(`, `)}]`:`[12, 14, 16, 20, 24, 32]`;return`import { Typeset } from "@storybook/addon-docs/blocks";
124
+
125
+ export function ColorPaletteBlock({ theme }: ColorPaletteBlockProps = {}) {
126
+ const activeTheme = ${a?`useThemeVariant(COLOR_VARIANTS, ${d(i)}, theme)`:d(i)};
127
+
128
+ return COLOR_VARIANTS[activeTheme];
129
+ }
130
+ `}function D(e,n={}){let r=n.sampleText??`The quick brown fox jumps over the lazy dog`,i=S(e),a=Object.entries(e),o=a[0]?.[0]??`default`,s=e=>{let i=e.filter(e=>e.type===`dimension`&&/(?:font|type|text).*size|size.*(?:font|type|text)/i.test(e.path)).map(e=>{let t=/^(\d+(?:\.\d+)?)/.exec(e.cssValue);return t?Number(t[1]):e.cssValue}),a=[...new Set(i)],o=(0,t.pickFontByRole)(n.fonts,t.SANS_ROLES),s=(o?(0,t.cssFontFamily)(o):void 0)??e.find(e=>e.type===`fontFamily`)?.cssValue??`system-ui, sans-serif`,c=e.find(e=>e.type===`fontWeight`),l=c&&Number.parseFloat(c.cssValue)||400,u=a.length>0?`[${a.map(e=>d(e)).join(`, `)}]`:`[12, 14, 16, 20, 24, 32]`;return`<Typeset
131
+ fontFamily={${d(s)}}
132
+ fontSizes={${u}}
133
+ fontWeight={${d(l)}}
134
+ sampleText={${d(r)}}
135
+ />`},c=a.map(([e,t])=>` ${d(e)}: (${s(t)})`).join(`,
136
+ `);return`import { Typeset } from "@storybook/addon-docs/blocks";
137
+ ${i?`import { useThemeVariant } from "./ThemeVariant";
138
+ `:``}
91
139
 
92
140
  /**
93
141
  * Typography tokens rendered with Storybook's Typeset doc block.
94
142
  *
95
143
  * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-typeset
96
144
  */
97
- export function TypesetBlock() {
98
- return (
99
- <Typeset
100
- fontFamily={${o(c)}}
101
- fontSizes={${d}}
102
- fontWeight={${o(u)}}
103
- sampleText={${o(r)}}
104
- />
105
- );
145
+ const TYPESET_VARIANTS = {
146
+ ${c}
147
+ };
148
+
149
+ export interface TypesetBlockProps {
150
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
151
+ theme?: string;
106
152
  }
107
- `}function f(e){return`import type { CSSProperties, ReactElement } from "react";
153
+
154
+ export function TypesetBlock({ theme }: TypesetBlockProps = {}) {
155
+ const activeTheme = ${i?`useThemeVariant(TYPESET_VARIANTS, ${d(o)}, theme)`:d(o)};
156
+
157
+ return TYPESET_VARIANTS[activeTheme];
158
+ }
159
+ `}function O(e){let t=S(e),n=Object.entries(e),r=n[0]?.[0]??`default`,i=e=>e.map(e=>{let t=e.theme?d(e.theme):`undefined`;return` {
160
+ path: ${d(e.path)},
161
+ type: ${e.type?d(e.type):`undefined`},
162
+ value: ${d(e.cssValue)},
163
+ cssVar: ${d(e.cssVar)},
164
+ description: ${e.description?d(e.description):`undefined`},
165
+ theme: ${t},
166
+ typography: ${h(e)}
167
+ }`}).join(`,
168
+ `),a=n.map(([e,t])=>` ${d(e)}: [
169
+ ${i(t)}
170
+ ]`).join(`,
171
+ `);return`import type { CSSProperties, ReactElement } from "react";
172
+ ${t?`import { useThemeVariant } from "./ThemeVariant";
173
+ `:``}
108
174
 
109
175
  export interface TokenTableRow {
110
176
  path: string;
@@ -113,19 +179,12 @@ export interface TokenTableRow {
113
179
  cssVar: string;
114
180
  description?: string;
115
181
  theme?: string;
182
+ typography: boolean;
116
183
  }
117
184
 
118
- const TOKENS: TokenTableRow[] = [
119
- ${e.map(e=>{let t=e.theme?o(e.theme):`undefined`;return` {
120
- path: ${o(e.path)},
121
- type: ${e.type?o(e.type):`undefined`},
122
- value: ${o(e.cssValue)},
123
- cssVar: ${o(e.cssVar)},
124
- description: ${e.description?o(e.description):`undefined`},
125
- theme: ${t}
126
- }`}).join(`,
127
- `)||``}
128
- ];
185
+ const TOKEN_VARIANTS: Record<string, TokenTableRow[]> = {
186
+ ${a}
187
+ };
129
188
 
130
189
  const tableStyle: CSSProperties = {
131
190
  width: "100%",
@@ -152,10 +211,14 @@ const swatchStyle = (value: string): CSSProperties => ({
152
211
  });
153
212
 
154
213
  export interface TokenTableBlockProps {
155
- /** Optional path prefix filter (e.g. \`color\`). */
156
- filter?: string;
214
+ /** Optional path prefix filter or filters (e.g. \`color\`). */
215
+ filter?: string | string[];
157
216
  /** Optional DTCG \`$type\` filter. */
158
217
  type?: string;
218
+ /** Restrict rows to tokens used to define typography. */
219
+ typography?: boolean;
220
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
221
+ theme?: string;
159
222
  }
160
223
 
161
224
  /**
@@ -163,15 +226,27 @@ export interface TokenTableBlockProps {
163
226
  */
164
227
  export function TokenTableBlock({
165
228
  filter,
166
- type
229
+ type,
230
+ typography,
231
+ theme
167
232
  }: TokenTableBlockProps = {}): ReactElement {
168
- const rows = TOKENS.filter(token => {
169
- if (filter && !token.path.startsWith(filter)) {
233
+ const activeTheme = ${t?`useThemeVariant(TOKEN_VARIANTS, ${d(r)}, theme)`:d(r)};
234
+ const rows = TOKEN_VARIANTS[activeTheme].filter(token => {
235
+ const filters = typeof filter === "string" ? [filter] : filter;
236
+ if (
237
+ filters &&
238
+ !filters.some(prefix =>
239
+ token.path === prefix || token.path.startsWith(\`\${prefix}.\`)
240
+ )
241
+ ) {
170
242
  return false;
171
243
  }
172
244
  if (type && token.type !== type) {
173
245
  return false;
174
246
  }
247
+ if (typography && !token.typography) {
248
+ return false;
249
+ }
175
250
  return true;
176
251
  });
177
252
 
@@ -208,7 +283,7 @@ export function TokenTableBlock({
208
283
  </table>
209
284
  );
210
285
  }
211
- `}function p(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
286
+ `}function k(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
212
287
  ## Colors
213
288
 
214
289
  <ColorPaletteBlock />
@@ -216,37 +291,53 @@ export function TokenTableBlock({
216
291
  ## Typography
217
292
 
218
293
  <TypesetBlock />
294
+ `:``,i=e.hasSizes?`
295
+ ## Size
296
+
297
+ <TokenTableBlock filter="size" />
298
+ `:``,a=e.hasSpaces?`
299
+ ## Space
300
+
301
+ <TokenTableBlock filter={[
302
+ "space",
303
+ "spacing"
304
+ ]} />
219
305
  `:``;return`import { Meta } from "@storybook/addon-docs/blocks";
220
306
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
221
307
  import { TokenTableBlock } from "./blocks/TokenTable";
222
308
  import { TypesetBlock } from "./blocks/Typeset";
223
309
 
224
- <Meta title="${a(t)}/Overview" />
310
+ <Meta title="${u(t)}/Overview" />
225
311
 
226
312
  # ${t}
227
313
 
228
314
  Design tokens generated by \`@razorwind/storybook\` for Storybook MDX docs.
229
- ${n}${r}
315
+ ${n}${r}${i}${a}
230
316
  ## All tokens
231
317
 
232
318
  <TokenTableBlock />
233
- `}function m(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
319
+ `}function A(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
234
320
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
235
321
 
236
- <Meta title="${a(e.titlePrefix??`Design Tokens`)}/Colors" />
322
+ <Meta title="${u(e.titlePrefix??`Design Tokens`)}/Colors" />
237
323
 
238
324
  # Colors
239
325
 
240
326
  <ColorPaletteBlock />
241
- `}function h(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
327
+ `}function j(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
242
328
  import { TypesetBlock } from "./blocks/Typeset";
329
+ import { TokenTableBlock } from "./blocks/TokenTable";
243
330
 
244
- <Meta title="${a(e.titlePrefix??`Design Tokens`)}/Typography" />
331
+ <Meta title="${u(e.titlePrefix??`Design Tokens`)}/Typography" />
245
332
 
246
333
  # Typography
247
334
 
248
335
  <TypesetBlock />
249
- `}function g(e,t){let n=e[t];return typeof n==`string`?n:void 0}function _(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function v(e){return`import { IconGallery, IconItem } from "@storybook/addon-docs/blocks";
336
+
337
+ ## Typography tokens
338
+
339
+ <TokenTableBlock typography />
340
+ `}function M(e,t){let n=e[t];return typeof n==`string`?n:void 0}function N(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function te(e){return`import { IconGallery, IconItem } from "@storybook/addon-docs/blocks";
250
341
 
251
342
  /**
252
343
  * Icons rendered with Storybook's IconGallery doc block.
@@ -256,39 +347,42 @@ import { TypesetBlock } from "./blocks/Typeset";
256
347
  export function IconGalleryBlock() {
257
348
  return (
258
349
  <IconGallery>
259
- ${(_(e)?Object.values(e).filter(_).toSorted((e,t)=>(g(e,`name`)??``).localeCompare(g(t,`name`)??``)):[]).map(e=>{let t=g(e,`name`)??`unknown`,n=(Array.isArray(e.files)?e.files:[]).find(e=>_(e)&&g(e,`type`)===`svg`&&typeof e.content==`string`),r=_(n)&&typeof n.content==`string`?`<span
350
+ ${(N(e)?Object.values(e).filter(N).toSorted((e,t)=>(M(e,`name`)??``).localeCompare(M(t,`name`)??``)):[]).map(e=>{let t=M(e,`name`)??`unknown`,n=(Array.isArray(e.files)?e.files:[]).find(e=>N(e)&&M(e,`type`)===`svg`&&typeof e.content==`string`),r=N(n)&&typeof n.content==`string`?`<span
260
351
  style={{ display: "inline-flex", width: 24, height: 24 }}
261
- dangerouslySetInnerHTML={{ __html: ${o(n.content)} }}
262
- />`:`<code>${a(t)}</code>`;return` <IconItem name={${o(t)}}>
352
+ dangerouslySetInnerHTML={{ __html: ${d(n.content)} }}
353
+ />`:`<code>${u(t)}</code>`;return` <IconItem name={${d(t)}}>
263
354
  ${r}
264
355
  </IconItem>`}).join(`
265
356
  `)||` {/* No icons */}`}
266
357
  </IconGallery>
267
358
  );
268
359
  }
269
- `}function y(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
360
+ `}function ne(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
270
361
  import { IconGalleryBlock } from "./blocks/IconGallery";
271
362
 
272
- <Meta title="${a(e.titlePrefix??`Design Tokens`)}/Icons" />
363
+ <Meta title="${u(e.titlePrefix??`Design Tokens`)}/Icons" />
273
364
 
274
365
  # Icons
275
366
 
276
367
  <IconGalleryBlock />
277
- `}function b(){return`export { ColorPaletteBlock } from "./ColorPalette";
278
- export { IconGalleryBlock } from "./IconGallery";
368
+ `}function re(e=!0){return`export { ColorPaletteBlock } from "./ColorPalette";
369
+ export type { ColorPaletteBlockProps } from "./ColorPalette";
370
+ ${e?`export { IconGalleryBlock } from "./IconGallery";
371
+ `:``}
279
372
  export { TokenTableBlock } from "./TokenTable";
280
373
  export type { TokenTableBlockProps, TokenTableRow } from "./TokenTable";
281
374
  export { TypesetBlock } from "./Typeset";
282
- `}const x=new Set(`base.colorPrimary.colorSecondary.appBg.appContentBg.appHoverBg.appPreviewBg.appBorderColor.appBorderRadius.fontBase.fontCode.textColor.textInverseColor.textMutedColor.barTextColor.barHoverColor.barSelectedColor.barBg.buttonBg.buttonBorder.booleanBg.booleanSelectedBg.inputBg.inputBorder.inputTextColor.inputBorderRadius.brandTitle.brandUrl.brandImage.brandTarget.gridCellSize`.split(`.`));function S(e){return _(e)?e.base===`light`||e.base===`dark`:!1}function C(e){return _(e)?S(e)?!0:Object.keys(e).some(e=>x.has(e)):!1}function w(e){if(!_(e)||C(e))return!1;let t=Object.values(e);return t.length>0&&t.every(C)}function T(e,t,n){return t.base===`light`||t.base===`dark`?t.base:`${e} ${n??``}`.toLowerCase().includes(`light`)?`light`:`dark`}function E(e){return/^[a-z_$][\w$]*$/i.test(e)?e:o(e)}function D(e,t){let r=e.find(e=>e.id===n.SHARED_THEME_ID);return!r||(0,n.isSharedThemeId)(t.id)?t.tokens:(0,n.mergeTokenTrees)(t.tokens,r.tokens)}const O=/^\{([^{}]+)\}$/;function k(e){if(typeof e==`string`)return O.exec(e.trim())?.[1]?.trim()}function A(e){return _(e)&&`$value`in e&&!(`colorSpace`in e)&&!(`hex`in e)?e.$value:e}function j(e,t){let n=A(e),r=new Set;for(let e=0;e<8;e++){let e=k(n);if(!e||r.has(e))break;r.add(e);let i=t.get(e);if(!i)break;n=i.value}return n}function M(e){return e==null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?e:(0,n.formatTokenValue)(e)}function N(e,t){let r=(0,n.resolveTokenSets)(e),a=r.find(e=>e.id===t)??(r.length===1?r[0]:void 0),o=a?D(r,a):e,s=new Map;for(let e of i(o))(!s.get(e.path)||e.theme===t)&&s.set(e.path,e);return s}function P(e,t){let n={...e};for(let[r,i]of Object.entries(e))r!==`base`&&i!==void 0&&(n[r]=M(j(i,t)));return n}function F(e,t,n,r,i){let a=P(t,N(i.tokens,e));return I(T(e,a,i.theme),a,n,r)}function I(e,n,r,i){let a=(0,t.pickFontByRole)(i,t.SANS_ROLES),o=(0,t.pickFontByRole)(i,t.MONO_ROLES);return{brandTarget:`_blank`,base:e||`light`,...n,brandTitle:n.brandTitle??r.title,brandUrl:n.brandUrl??r.homepage,brandImage:n.brandImage??r.logo,fontBase:n.fontBase??(a?(0,t.cssFontFamily)(a):void 0),fontCode:n.fontCode??(o?(0,t.cssFontFamily)(o):void 0)}}function L(e,t=``){return`create({\n${Object.entries(e).filter(([,e])=>e!==void 0).map(([e,n])=>`${t} ${e}: ${o(n)}`).join(`,
283
- `)}\n${t}})`}function R(e){return`import { create } from "storybook/theming";
375
+ export type { TypesetBlockProps } from "./Typeset";
376
+ `}const P=new Set(`base.colorPrimary.colorSecondary.appBg.appContentBg.appHoverBg.appPreviewBg.appBorderColor.appBorderRadius.fontBase.fontCode.textColor.textInverseColor.textMutedColor.barTextColor.barHoverColor.barSelectedColor.barBg.buttonBg.buttonBorder.booleanBg.booleanSelectedBg.inputBg.inputBorder.inputTextColor.inputBorderRadius.brandTitle.brandUrl.brandImage.brandTarget.gridCellSize`.split(`.`));function F(e){return N(e)?e.base===`light`||e.base===`dark`:!1}function I(e){return N(e)?F(e)?!0:Object.keys(e).some(e=>P.has(e)):!1}function L(e){if(!N(e)||I(e))return!1;let t=Object.values(e);return t.length>0&&t.every(I)}function R(e,t,n){return t.base===`light`||t.base===`dark`?t.base:`${e} ${n??``}`.toLowerCase().includes(`light`)?`light`:`dark`}function z(e){return/^[a-z_$][\w$]*$/i.test(e)?e:d(e)}function B(e,t){let r=e.find(e=>e.id===n.SHARED_THEME_ID);return!r||(0,n.isSharedThemeId)(t.id)?t.tokens:(0,n.mergeTokenTrees)(t.tokens,r.tokens)}function V(e){return N(e)&&`$value`in e&&!(`colorSpace`in e)&&!(`hex`in e)?e.$value:e}function H(e,t){let n=V(e),r=new Set;for(let e=0;e<8;e++){let e=y(n);if(!e||r.has(e))break;r.add(e);let i=t.get(e);if(!i)break;n=i.value}return n}function U(e){return e==null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?e:(0,n.formatTokenValue)(e)}function W(e,t){let r=(0,n.resolveTokenSets)(e),i=r.find(e=>e.id===t)??(r.length===1?r[0]:void 0),a=i?B(r,i):e,o=new Map;for(let e of l(a))(!o.get(e.path)||e.theme===t)&&o.set(e.path,e);return o}function G(e,t){let n={...e};for(let[r,i]of Object.entries(e))r!==`base`&&i!==void 0&&(n[r]=U(H(i,t)));return n}function K(e,t,n,r,i){let a=G(t,W(i.tokens,e));return q(R(e,a,i.theme),a,n,r)}function q(e,n,r,i){let a=(0,t.pickFontByRole)(i,t.SANS_ROLES),o=(0,t.pickFontByRole)(i,t.MONO_ROLES);return{brandTarget:`_blank`,base:e||`light`,...n,brandTitle:n.brandTitle??r.title,brandUrl:n.brandUrl??r.homepage,brandImage:n.brandImage??r.logo,fontBase:n.fontBase??(a?(0,t.cssFontFamily)(a):void 0),fontCode:n.fontCode??(o?(0,t.cssFontFamily)(o):void 0)}}function J(e,t=``){return`create({\n${Object.entries(e).filter(([,e])=>e!==void 0).map(([e,n])=>`${t} ${e}: ${d(n)}`).join(`,
377
+ `)}\n${t}})`}function Y(e){return`import { create } from "storybook/theming";
284
378
 
285
379
  /**
286
380
  * Storybook UI theme generated by \`@razorwind/storybook\`.
287
381
  *
288
382
  * @see https://storybook.js.org/docs/configure/user-interface/theming
289
383
  */
290
- export default ${L(e)};
291
- `}function z(e){return`import { create } from "storybook/theming";
384
+ export default ${J(e)};
385
+ `}function X(e){return`import { create } from "storybook/theming";
292
386
 
293
387
  /**
294
388
  * Storybook UI themes generated by \`@razorwind/storybook\`.
@@ -296,7 +390,7 @@ export default ${L(e)};
296
390
  * @see https://storybook.js.org/docs/configure/user-interface/theming
297
391
  */
298
392
  export default {
299
- ${Object.entries(e).map(([e,t])=>` ${E(e)}: ${L(t,` `)}`).join(`,
393
+ ${Object.entries(e).map(([e,t])=>` ${z(e)}: ${J(t,` `)}`).join(`,
300
394
  `)}
301
395
  };
302
- `}function B(e){if(S(e))return R(e);let t=Object.entries(e);if(t.length!==1)return z(e);let[,n]=t[0]??[];return n?R(n):z(e)}function V(e,t,r,i){let a=(e,n)=>F(e,n,r,t.fonts,t);if(w(e))return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,a(e,t)]));let o=(0,n.resolveTokenSets)(t.tokens),s=o.filter(e=>!(0,n.isSharedThemeId)(e.id));if(s.length>1){let e={};for(let t of s){let n=i(D(o,t));if(w(n)){let r=n[t.id];if(r){e[t.id]=a(t.id,r);continue}for(let[t,r]of Object.entries(n))e[t]=a(t,r);continue}C(n)&&(e[t.id]=a(t.id,n))}return e}if(C(e)){let n=s[0]&&s[0].id!=="default"?s[0].id:t.theme??`default`;return{[n]:a(n,e)}}return{}}const H=e=>(t,i,a)=>(0,n.createDocument)((0,r.joinPaths)(e,t),i,{name:`razorwind-storybook`},!1,a);function U(e,t={}){let a=t.outputPath??`storybook/tokens`,o=(0,n.resolveSchemaIdentity)(e),c=t.titlePrefix??o.title??`Design Tokens`,l={...t,titlePrefix:c},g=i(e.tokens,t),x=g.some(e=>e.type===`color`),S=e.fonts&&Object.keys(e.fonts).length>0||g.some(e=>e.type===`fontFamily`||e.type===`fontWeight`||e.type===`typography`||e.type===`dimension`&&/(?:font|type|text).*size|size.*(?:font|type|text)/i.test(e.path)),C=!t.skipIcons&&_(e.icons)&&Object.keys(e.icons).length>0,w=H(a),T={[(0,r.joinPaths)(a,`blocks/ColorPalette.tsx`)]:w(`blocks/ColorPalette.tsx`,u(g,l),`tsx`),[(0,r.joinPaths)(a,`blocks/Typeset.tsx`)]:w(`blocks/Typeset.tsx`,d(g,{...l,fonts:e.fonts}),`tsx`),[(0,r.joinPaths)(a,`blocks/TokenTable.tsx`)]:w(`blocks/TokenTable.tsx`,f(g),`tsx`),[(0,r.joinPaths)(a,`blocks/IconGallery.tsx`)]:w(`blocks/IconGallery.tsx`,v(t.skipIcons?{}:e.icons),`tsx`),[(0,r.joinPaths)(a,`blocks/index.ts`)]:w(`blocks/index.ts`,b(),`typescript`),[(0,r.joinPaths)(a,`Tokens.mdx`)]:w(`Tokens.mdx`,p({titlePrefix:c,hasColors:x,hasTypography:S}),`mdx`)};x&&(T[(0,r.joinPaths)(a,`Colors.mdx`)]=w(`Colors.mdx`,m(l),`mdx`)),S&&(T[(0,r.joinPaths)(a,`Typography.mdx`)]=w(`Typography.mdx`,h(l),`mdx`)),C&&(T[(0,r.joinPaths)(a,`Icons.mdx`)]=w(`Icons.mdx`,y(l),`mdx`)),T[(0,r.joinPaths)(a,`tokens.json`)]=w(`tokens.json`,`${JSON.stringify(g,null,2)}\n`,`json`);let E;if(t.mapTheme){let n=V(t.mapTheme(e.tokens),e,o,t.mapTheme);Object.keys(n).length>0&&(E=Object.keys(n),T[(0,r.joinPaths)(a,`theme.ts`)]=w(`theme.ts`,B(n),`typescript`))}let D=`INSTALL.md`;return T[(0,r.joinPaths)(a,D)]=w(D,t.installGuide??s({outputPath:a,titlePrefix:c,themeFiles:E?[`theme.ts`]:void 0,themeNames:E}),`markdown`),T}var W=(0,e.definePlugin)(e=>({name:`storybook`,themeGeneration:`combined`,generate:async t=>U(t,e??{})}));exports.applyBrandDefaults=I,exports.default=W,exports.flattenTokens=i,Object.defineProperty(exports,"formatTokenValue",{enumerable:!0,get:function(){return n.formatTokenValue}}),exports.generateTokenDocs=U,exports.normalizeThemes=V,exports.renderInstallMd=s,exports.renderThemeFile=B,exports.resolveTokenSets=n.resolveTokenSets,Object.defineProperty(exports,"toCssVar",{enumerable:!0,get:function(){return n.toCssVar}});
396
+ `}function Z(e){if(F(e))return Y(e);let t=Object.entries(e);if(t.length!==1)return X(e);let[,n]=t[0]??[];return n?Y(n):X(e)}function Q(e,t,r,i){let a=(e,n)=>K(e,n,r,t.fonts,t);if(L(e))return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,a(e,t)]));let o=(0,n.resolveTokenSets)(t.tokens),s=o.filter(e=>!(0,n.isSharedThemeId)(e.id));if(s.length>1){let e={};for(let t of s){let n=i(B(o,t));if(L(n)){let r=n[t.id];if(r){e[t.id]=a(t.id,r);continue}for(let[t,r]of Object.entries(n))e[t]=a(t,r);continue}I(n)&&(e[t.id]=a(t.id,n))}return e}if(I(e)){let n=s[0]&&s[0].id!=="default"?s[0].id:t.theme??`default`;return{[n]:a(n,e)}}return{}}const ie=e=>(t,i,a)=>(0,n.createDocument)((0,r.joinPaths)(e,t),i,{name:`razorwind-storybook`},!1,a);function $(e,t={}){let i=t.outputPath??`storybook/tokens`,a=(0,n.resolveSchemaIdentity)(e),o=t.titlePrefix??a.title??`Design Tokens`,s={...t,titlePrefix:o},c=l(e.tokens,t),u=C(e.tokens,t),d=c.some(e=>e.type===`color`),p=e.fonts&&Object.keys(e.fonts).length>0||c.some(h),m=g(c,[`size`]),_=g(c,[`space`,`spacing`]),v=!t.skipIcons&&N(e.icons)&&Object.keys(e.icons).length>0,y=ie(i),b={[(0,r.joinPaths)(i,`blocks/ColorPalette.tsx`)]:y(`blocks/ColorPalette.tsx`,E(u,s),`tsx`),[(0,r.joinPaths)(i,`blocks/Typeset.tsx`)]:y(`blocks/Typeset.tsx`,D(u,{...s,fonts:e.fonts}),`tsx`),[(0,r.joinPaths)(i,`blocks/TokenTable.tsx`)]:y(`blocks/TokenTable.tsx`,O(u),`tsx`),[(0,r.joinPaths)(i,`blocks/index.ts`)]:y(`blocks/index.ts`,re(v),`typescript`),[(0,r.joinPaths)(i,`Tokens.mdx`)]:y(`Tokens.mdx`,k({titlePrefix:o,hasColors:d,hasTypography:p,hasSizes:m,hasSpaces:_}),`mdx`)};v&&(b[(0,r.joinPaths)(i,`blocks/IconGallery.tsx`)]=y(`blocks/IconGallery.tsx`,te(e.icons),`tsx`)),S(u)&&(b[(0,r.joinPaths)(i,`blocks/ThemeVariant.ts`)]=y(`blocks/ThemeVariant.ts`,ee(),`typescript`)),d&&(b[(0,r.joinPaths)(i,`Colors.mdx`)]=y(`Colors.mdx`,A(s),`mdx`)),p&&(b[(0,r.joinPaths)(i,`Typography.mdx`)]=y(`Typography.mdx`,j(s),`mdx`)),v&&(b[(0,r.joinPaths)(i,`Icons.mdx`)]=y(`Icons.mdx`,ne(s),`mdx`)),b[(0,r.joinPaths)(i,`tokens.json`)]=y(`tokens.json`,`${JSON.stringify(c,null,2)}\n`,`json`);let x;if(t.mapTheme){let n=Q(t.mapTheme(e.tokens),e,a,t.mapTheme);Object.keys(n).length>0&&(x=Object.keys(n),b[(0,r.joinPaths)(i,`theme.ts`)]=y(`theme.ts`,Z(n),`typescript`))}let w=`INSTALL.md`;return b[(0,r.joinPaths)(i,w)]=y(w,t.installGuide??f({outputPath:i,titlePrefix:o,themeFiles:x?[`theme.ts`]:void 0,themeNames:x,tokenThemeNames:Object.keys(u)}),`markdown`),b}var ae=(0,e.definePlugin)(e=>({name:`storybook`,themeGeneration:`combined`,generate:async t=>$(t,e??{})}));exports.applyBrandDefaults=q,exports.default=ae,exports.flattenTokens=l,Object.defineProperty(exports,"formatTokenValue",{enumerable:!0,get:function(){return n.formatTokenValue}}),exports.generateTokenDocs=$,exports.normalizeThemes=Q,exports.renderInstallMd=f,exports.renderThemeFile=Z,exports.resolveTokenSets=n.resolveTokenSets,Object.defineProperty(exports,"toCssVar",{enumerable:!0,get:function(){return n.toCssVar}});
package/dist/index.d.cts CHANGED
@@ -22,6 +22,10 @@ interface FlatToken {
22
22
  description?: string;
23
23
  /** Theme / set id when tokens are a `Record<string, Tokens>`. */
24
24
  theme?: string;
25
+ /** True when this color belongs to an ancestor group marked `palette: true`. */
26
+ palette?: boolean;
27
+ /** Semantic child-theme name from a token or ancestor `theme` property. */
28
+ childTheme?: string;
25
29
  }
26
30
  /**
27
31
  * Storybook theme variables passed to `create()` from `storybook/theming`.
@@ -153,6 +157,7 @@ declare function renderInstallMd(options: {
153
157
  titlePrefix?: string;
154
158
  themeFiles?: string[];
155
159
  themeNames?: string[];
160
+ tokenThemeNames?: string[];
156
161
  }): string;
157
162
  //#endregion
158
163
  //#region src/generate.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/flatten.ts","../src/install.ts","../src/generate.ts","../src/index.ts"],"mappings":";;;;;;;;;UAwBiB;;EAEf;;EAEA,OAAO;;EAEP;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;UAQe;;EAEf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU,wBAAwB,YAAY;KAEpC,uBACV,wBAAwB,eAAe;;;;;;KAO7B,0BACV,QAAQ,SAAS,eAAe,YAC7B;;;;UAKY;;;;;;EAMf;;;;;;EAOA;;;;;;EAOA;;;;;;EAOA;;;;;EAMA,eAAe;;;;;;EAOf;;;;;;;;;;;;;;EAeA,WAAW;;;;;;EAOX;;;;;EAMA;;;;;;;iBCrIc,cACd,QAAQ,WAAS,eAAe,WAChC,UAAS,KAAK,2DACb;;;;;;;;iBCba,gBAAgB;EAC9B;EACA;EACA;EACA;;;;;;;iBCorBc,mBACd,wBACA,OAAO,YAAY,yBACnB;EAAY;EAAgB;EAAmB;GAC/C,QAAQ,QACP;;;;;;;;;iBAkEa,gBACd,OAAO,iBAAiB,eAAe;;;;;;iBAwBzB,gBACd,iBACA,MAAM,KAAK,uCACX;EAAY;EAAgB;EAAmB;GAC/C,UAAU,YAAY,sCACrB,eAAe;;;;iBAwEF,kBACd,MAAM,QACN,UAAS,yBACR,wBAAwB,QAAQ"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/flatten.ts","../src/install.ts","../src/generate.ts","../src/index.ts"],"mappings":";;;;;;;;;UAwBiB;;EAEf;;EAEA,OAAO;;EAEP;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;UAQe;;EAEf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU,wBAAwB,YAAY;KAEpC,uBACV,wBAAwB,eAAe;;;;;;KAO7B,0BACV,QAAQ,SAAS,eAAe,YAC7B;;;;UAKY;;;;;;EAMf;;;;;;EAOA;;;;;;EAOA;;;;;;EAOA;;;;;EAMA,eAAe;;;;;;EAOf;;;;;;;;;;;;;;EAeA,WAAW;;;;;;EAOX;;;;;EAMA;;;;;;;iBC3Dc,cACd,QAAQ,WAAS,eAAe,WAChC,UAAS,KAAK,2DACb;;;;;;;;iBC3Fa,gBAAgB;EAC9B;EACA;EACA;EACA;EACA;;;;;;;iBC86Bc,mBACd,wBACA,OAAO,YAAY,yBACnB;EAAY;EAAgB;EAAmB;GAC/C,QAAQ,QACP;;;;;;;;;iBAkEa,gBACd,OAAO,iBAAiB,eAAe;;;;;;iBAwBzB,gBACd,iBACA,MAAM,KAAK,uCACX;EAAY;EAAgB;EAAmB;GAC/C,UAAU,YAAY,sCACrB,eAAe;;;;iBAwEF,kBACd,MAAM,QACN,UAAS,yBACR,wBAAwB,QAAQ"}
package/dist/index.d.mts CHANGED
@@ -22,6 +22,10 @@ interface FlatToken {
22
22
  description?: string;
23
23
  /** Theme / set id when tokens are a `Record<string, Tokens>`. */
24
24
  theme?: string;
25
+ /** True when this color belongs to an ancestor group marked `palette: true`. */
26
+ palette?: boolean;
27
+ /** Semantic child-theme name from a token or ancestor `theme` property. */
28
+ childTheme?: string;
25
29
  }
26
30
  /**
27
31
  * Storybook theme variables passed to `create()` from `storybook/theming`.
@@ -153,6 +157,7 @@ declare function renderInstallMd(options: {
153
157
  titlePrefix?: string;
154
158
  themeFiles?: string[];
155
159
  themeNames?: string[];
160
+ tokenThemeNames?: string[];
156
161
  }): string;
157
162
  //#endregion
158
163
  //#region src/generate.d.ts
package/dist/index.mjs CHANGED
@@ -1,5 +1,11 @@
1
- import{definePlugin as e}from"@razorwind/core/plugin";import{MONO_ROLES as t,SANS_ROLES as n,cssFontFamily as r,pickFontByRole as i}from"@razorwind/core/lib/fonts";import{SHARED_THEME_ID as a,createDocument as o,flattenTokens as s,formatTokenValue as c,isSharedThemeId as l,mergeTokenTrees as u,resolveSchemaIdentity as d,resolveTokenSets as f,toCssVar as p,toCssVar as m}from"@razorwind/core/utils";import{joinPaths as h}from"@stryke/path/join";function g(e,t={}){let n=t.cssVarPrefix??`rw`;return s(e,{includeTypes:t.includeTypes,enrichToken:e=>({...e,cssVar:m(e.path,n)})})}function _(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`).replaceAll(`
2
- `,`\\n`).replaceAll(`\r`,`\\r`)}function v(e){return typeof e==`string`?`"${_(e)}"`:typeof e==`number`||typeof e==`boolean`?String(e):e==null?`undefined`:JSON.stringify(e)}function y(e){let t=e.titlePrefix??`Design Tokens`,n=e.themeFiles?.[0],r=e.themeNames??[],i=n?r.length>1?`
1
+ import{definePlugin as e}from"@razorwind/core/plugin";import{MONO_ROLES as t,SANS_ROLES as n,cssFontFamily as r,pickFontByRole as i}from"@razorwind/core/lib/fonts";import{SHARED_THEME_ID as a,createDocument as o,flattenTokens as s,formatTokenValue as c,isObject as l,isSharedThemeId as u,isTokenLeaf as d,mergeTokenTrees as f,resolveSchemaIdentity as ee,resolveTokenSets as p,toCssVar as m,toCssVar as h,toThemeCssVar as g}from"@razorwind/core/utils";import{joinPaths as _}from"@stryke/path/join";function v(e){return e===!0||e===`true`||e===1}function y(e,t){return e?`${e}:${t}`:t}function te(e){let t=e.theme??e.$theme;return typeof t==`string`&&t.length>0?t:void 0}function b(e,t){return e===`palette`||e===`$palette`?typeof t==`boolean`||typeof t==`number`||typeof t==`string`:(e===`theme`||e===`$theme`)&&typeof t==`string`}function x(e){let t=new Map;function n(e,r,i,a,o){if(!l(e))return;let s=a||v(e.palette)||v(e.$palette),c=te(e)??o;if(d(e)){(s||c)&&t.set(y(i,r.join(`.`)),{...s&&{palette:!0},...c&&{childTheme:c}});return}for(let[t,a]of Object.entries(e))t.startsWith(`$`)&&t!==`$palette`&&t!==`$theme`||b(t,a)||n(a,[...r,t],i,s,c)}for(let t of p(e)){let e=t.id==="default"?void 0:t.id;n(t.tokens,[],e,!1,void 0)}return t}function S(e,t={}){let n=t.cssVarPrefix??`rw`,r=x(e);return s(e,{includeTypes:t.includeTypes,shouldIncludeToken:e=>e.skipDocs!==!0,enrichToken:e=>{let t=r.get(y(e.theme,e.path));return{...e,cssVar:h(e.path,n),...e.type===`color`&&t}}})}function C(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`).replaceAll(`
2
+ `,`\\n`).replaceAll(`\r`,`\\r`)}function w(e){return typeof e==`string`?`"${C(e)}"`:typeof e==`number`||typeof e==`boolean`?String(e):e==null?`undefined`:JSON.stringify(e)}function T(e){let t=e.titlePrefix??`Design Tokens`,n=e.themeFiles?.[0],r=e.themeNames??[],i=e.tokenThemeNames??[],a=i.length>1?`
3
+ ## Token-doc variants
4
+
5
+ Generated token blocks follow Storybook's \`theme\` global when it matches one
6
+ of these token-set names: ${i.map(e=>`\`${e}\``).join(`, `)}.
7
+ Pass \`theme\` directly to a block to override that selection.
8
+ `:``,o=n?r.length>1?`
3
9
  ## Storybook UI theme
4
10
 
5
11
  Generated theme module:
@@ -40,7 +46,7 @@ Generated by \`@razorwind/storybook\`.
40
46
  - \`${e.outputPath}/Tokens.mdx\` — token overview (${t})
41
47
  - \`${e.outputPath}/blocks/\` — React doc blocks (ColorPalette, Typeset, …)
42
48
  - \`${e.outputPath}/tokens.json\` — flattened token manifest
43
- ${i}
49
+ ${o}${a}
44
50
  ## Setup
45
51
 
46
52
  1. Add the generated MDX pages to Storybook (paths depend on your \`stories\` config):
@@ -65,46 +71,106 @@ import { ColorPaletteBlock } from "./blocks";
65
71
  ## Regenerate
66
72
 
67
73
  Re-run Razorwind generate when tokens change to refresh docs under \`${e.outputPath}/\`.
68
- `}function b(e,t){let n=new Map;for(let r of e){let e=r.path.split(`.`).slice(0,Math.max(t,1)).join(`.`)||r.path,i=n.get(e)??[];i.push(r),n.set(e,i)}return n}function x(e,t){return e===t?e.split(`.`).at(-1)??e:e.startsWith(`${t}.`)?e.slice(t.length+1):e.split(`.`).at(-1)??e}function S(e,t={}){return`import { ColorPalette, ColorItem } from "@storybook/addon-docs/blocks";
74
+ `}const E=new Set([`fontFamily`,`fontWeight`,`typography`]),ne=/font|typography|type|text|line[-_.]?height|letter[-_.]?spacing/i;function D(e){return E.has(e.type??``)?!0:(e.type===`dimension`||e.type===`number`)&&ne.test(e.path)}function O(e,t){return e.some(e=>t.some(t=>e.path===t||e.path.startsWith(`${t}.`)))}const re=/^\{([^{}]+)\}$/,ie=/^var\((--[^),\s]+)(?:\s*,[^)]*)?\)$/;function k(e){if(typeof e==`string`)return re.exec(e.trim())?.[1]?.trim()}function A(e){if(typeof e==`string`)return ie.exec(e.trim())?.[1]}function j(e){let t=new Map(e.map(e=>[e.path,e])),n=new Map(e.map(e=>[g(e.path),e])),r=e=>{let r=e,i=new Set;for(let a=0;a<8;a++){if(i.has(r.path))return e.cssValue;i.add(r.path);let a=t.get(k(r.value)??``)??n.get(A(r.value)??A(r.cssValue)??``);if(!a||a.path===r.path)return r.cssValue;r=a}return e.cssValue};return e.map(e=>e.type===`color`?{...e,cssValue:r(e)}:e)}function M(e){return Object.keys(e).length>1}function ae(){return`import { useGlobals } from "storybook/preview-api";
69
75
 
70
76
  /**
71
- * Color tokens rendered with Storybook's ColorPalette doc block.
72
- *
73
- * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-colorpalette
77
+ * Select a generated token variant. By default this follows Storybook's
78
+ * \`theme\` global; callers may pass \`theme\` to override it.
74
79
  */
75
- export function ColorPaletteBlock() {
76
- return (
77
- <ColorPalette>
78
- ${[...b(e.filter(e=>e.type===`color`),t.colorGroupBy??2).entries()].toSorted(([e],[t])=>e.localeCompare(t)).map(([e,t])=>{let n=t.map(t=>` ${v(x(t.path,e))}: ${v(t.cssValue)}`).join(`,
79
- `),r=t.find(e=>e.description)?.description??`${t.length} token${t.length===1?``:`s`}`;return` <ColorItem
80
- title={${v(e)}}
81
- subtitle={${v(r)}}
80
+ export function useThemeVariant<T extends Record<string, unknown>>(
81
+ variants: T,
82
+ fallback: keyof T & string,
83
+ theme?: string
84
+ ): keyof T & string {
85
+ const [globals] = useGlobals();
86
+ const candidate = theme ?? globals.theme;
87
+
88
+ return typeof candidate === "string" && candidate in variants
89
+ ? (candidate as keyof T & string)
90
+ : fallback;
91
+ }
92
+ `}function oe(e,t){let n=p(e),r=n.filter(e=>!u(e.id));return r.length<=1?{default:j(S(e,t))}:Object.fromEntries(r.map(e=>[e.id,j(S(K(n,e),t))]))}function se(e,t){let n=new Map;for(let r of e){let e=r.path.split(`.`).slice(0,Math.max(t,1)).join(`.`)||r.path,i=n.get(e)??[];i.push(r),n.set(e,i)}return n}function ce(e,t){return e===t?e.split(`.`).at(-1)??e:e.startsWith(`${t}.`)?e.slice(t.length+1):e.split(`.`).at(-1)??e}function le(e,t={}){let n=t.colorGroupBy??2,r=Object.entries(e),i=r[0]?.[0]??`default`,a=M(e),o=(e,t=` `)=>[...se(e,n).entries()].toSorted(([e],[t])=>e.localeCompare(t)).map(([e,n])=>{let r=n.map(n=>`${t} ${w(ce(n.path,e))}: ${w(n.cssValue)}`).join(`,
93
+ `),i=n.find(e=>e.description)?.description??`${n.length} token${n.length===1?``:`s`}`;return`${t}<ColorItem
94
+ title={${w(e)}}
95
+ subtitle={${w(i)}}
82
96
  colors={{
83
- ${n}
97
+ ${r}
84
98
  }}
85
99
  />`}).join(`
86
- `)||` {/* No color tokens */}`}
87
- </ColorPalette>
88
- );
100
+ `),s=e=>{let t=e.filter(e=>e.type===`color`),n=t.filter(e=>e.palette),r=t.filter(e=>!e.palette&&e.childTheme),i=t.filter(e=>!e.palette&&!e.childTheme),a=n.length>0||r.length>0,s=o(t),c=[[`Color palettes`,n],[`Semantic colors`,r],[`Colors`,i]].filter(e=>!!e[1]?.length).map(([e,t])=>` <section>
101
+ <h2>${e}</h2>
102
+ <ColorPalette>
103
+ ${o(t,` `)}
104
+ </ColorPalette>
105
+ </section>`).join(`
106
+ `);return a?`<>\n${c}\n </>`:`<ColorPalette>\n${s||` {/* No color tokens */}`}\n </ColorPalette>`},c=r.map(([e,t])=>` ${w(e)}: (\n ${s(t)}\n )`).join(`,
107
+ `);return`import { ColorPalette, ColorItem } from "@storybook/addon-docs/blocks";
108
+ ${a?`import { useThemeVariant } from "./ThemeVariant";
109
+ `:``}
110
+
111
+ /**
112
+ * Color tokens rendered with Storybook's ColorPalette doc block.
113
+ *
114
+ * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-colorpalette
115
+ */
116
+ const COLOR_VARIANTS = {
117
+ ${c}
118
+ };
119
+
120
+ export interface ColorPaletteBlockProps {
121
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
122
+ theme?: string;
89
123
  }
90
- `}function C(e,t={}){let a=t.sampleText??`The quick brown fox jumps over the lazy dog`,o=e.filter(e=>e.type===`dimension`&&/(?:font|type|text).*size|size.*(?:font|type|text)/i.test(e.path)).map(e=>{let t=/^(\d+(?:\.\d+)?)/.exec(e.cssValue);return t?Number(t[1]):e.cssValue}),s=[...new Set(o)],c=i(t.fonts,n),l=(c?r(c):void 0)??e.find(e=>e.type===`fontFamily`)?.cssValue??`system-ui, sans-serif`,u=e.find(e=>e.type===`fontWeight`),d=u&&Number.parseFloat(u.cssValue)||400,f=s.length>0?`[${s.map(e=>v(e)).join(`, `)}]`:`[12, 14, 16, 20, 24, 32]`;return`import { Typeset } from "@storybook/addon-docs/blocks";
124
+
125
+ export function ColorPaletteBlock({ theme }: ColorPaletteBlockProps = {}) {
126
+ const activeTheme = ${a?`useThemeVariant(COLOR_VARIANTS, ${w(i)}, theme)`:w(i)};
127
+
128
+ return COLOR_VARIANTS[activeTheme];
129
+ }
130
+ `}function ue(e,t={}){let a=t.sampleText??`The quick brown fox jumps over the lazy dog`,o=M(e),s=Object.entries(e),c=s[0]?.[0]??`default`,l=e=>{let o=e.filter(e=>e.type===`dimension`&&/(?:font|type|text).*size|size.*(?:font|type|text)/i.test(e.path)).map(e=>{let t=/^(\d+(?:\.\d+)?)/.exec(e.cssValue);return t?Number(t[1]):e.cssValue}),s=[...new Set(o)],c=i(t.fonts,n),l=(c?r(c):void 0)??e.find(e=>e.type===`fontFamily`)?.cssValue??`system-ui, sans-serif`,u=e.find(e=>e.type===`fontWeight`),d=u&&Number.parseFloat(u.cssValue)||400,f=s.length>0?`[${s.map(e=>w(e)).join(`, `)}]`:`[12, 14, 16, 20, 24, 32]`;return`<Typeset
131
+ fontFamily={${w(l)}}
132
+ fontSizes={${f}}
133
+ fontWeight={${w(d)}}
134
+ sampleText={${w(a)}}
135
+ />`},u=s.map(([e,t])=>` ${w(e)}: (${l(t)})`).join(`,
136
+ `);return`import { Typeset } from "@storybook/addon-docs/blocks";
137
+ ${o?`import { useThemeVariant } from "./ThemeVariant";
138
+ `:``}
91
139
 
92
140
  /**
93
141
  * Typography tokens rendered with Storybook's Typeset doc block.
94
142
  *
95
143
  * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-typeset
96
144
  */
97
- export function TypesetBlock() {
98
- return (
99
- <Typeset
100
- fontFamily={${v(l)}}
101
- fontSizes={${f}}
102
- fontWeight={${v(d)}}
103
- sampleText={${v(a)}}
104
- />
105
- );
145
+ const TYPESET_VARIANTS = {
146
+ ${u}
147
+ };
148
+
149
+ export interface TypesetBlockProps {
150
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
151
+ theme?: string;
106
152
  }
107
- `}function w(e){return`import type { CSSProperties, ReactElement } from "react";
153
+
154
+ export function TypesetBlock({ theme }: TypesetBlockProps = {}) {
155
+ const activeTheme = ${o?`useThemeVariant(TYPESET_VARIANTS, ${w(c)}, theme)`:w(c)};
156
+
157
+ return TYPESET_VARIANTS[activeTheme];
158
+ }
159
+ `}function N(e){let t=M(e),n=Object.entries(e),r=n[0]?.[0]??`default`,i=e=>e.map(e=>{let t=e.theme?w(e.theme):`undefined`;return` {
160
+ path: ${w(e.path)},
161
+ type: ${e.type?w(e.type):`undefined`},
162
+ value: ${w(e.cssValue)},
163
+ cssVar: ${w(e.cssVar)},
164
+ description: ${e.description?w(e.description):`undefined`},
165
+ theme: ${t},
166
+ typography: ${D(e)}
167
+ }`}).join(`,
168
+ `),a=n.map(([e,t])=>` ${w(e)}: [
169
+ ${i(t)}
170
+ ]`).join(`,
171
+ `);return`import type { CSSProperties, ReactElement } from "react";
172
+ ${t?`import { useThemeVariant } from "./ThemeVariant";
173
+ `:``}
108
174
 
109
175
  export interface TokenTableRow {
110
176
  path: string;
@@ -113,19 +179,12 @@ export interface TokenTableRow {
113
179
  cssVar: string;
114
180
  description?: string;
115
181
  theme?: string;
182
+ typography: boolean;
116
183
  }
117
184
 
118
- const TOKENS: TokenTableRow[] = [
119
- ${e.map(e=>{let t=e.theme?v(e.theme):`undefined`;return` {
120
- path: ${v(e.path)},
121
- type: ${e.type?v(e.type):`undefined`},
122
- value: ${v(e.cssValue)},
123
- cssVar: ${v(e.cssVar)},
124
- description: ${e.description?v(e.description):`undefined`},
125
- theme: ${t}
126
- }`}).join(`,
127
- `)||``}
128
- ];
185
+ const TOKEN_VARIANTS: Record<string, TokenTableRow[]> = {
186
+ ${a}
187
+ };
129
188
 
130
189
  const tableStyle: CSSProperties = {
131
190
  width: "100%",
@@ -152,10 +211,14 @@ const swatchStyle = (value: string): CSSProperties => ({
152
211
  });
153
212
 
154
213
  export interface TokenTableBlockProps {
155
- /** Optional path prefix filter (e.g. \`color\`). */
156
- filter?: string;
214
+ /** Optional path prefix filter or filters (e.g. \`color\`). */
215
+ filter?: string | string[];
157
216
  /** Optional DTCG \`$type\` filter. */
158
217
  type?: string;
218
+ /** Restrict rows to tokens used to define typography. */
219
+ typography?: boolean;
220
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
221
+ theme?: string;
159
222
  }
160
223
 
161
224
  /**
@@ -163,15 +226,27 @@ export interface TokenTableBlockProps {
163
226
  */
164
227
  export function TokenTableBlock({
165
228
  filter,
166
- type
229
+ type,
230
+ typography,
231
+ theme
167
232
  }: TokenTableBlockProps = {}): ReactElement {
168
- const rows = TOKENS.filter(token => {
169
- if (filter && !token.path.startsWith(filter)) {
233
+ const activeTheme = ${t?`useThemeVariant(TOKEN_VARIANTS, ${w(r)}, theme)`:w(r)};
234
+ const rows = TOKEN_VARIANTS[activeTheme].filter(token => {
235
+ const filters = typeof filter === "string" ? [filter] : filter;
236
+ if (
237
+ filters &&
238
+ !filters.some(prefix =>
239
+ token.path === prefix || token.path.startsWith(\`\${prefix}.\`)
240
+ )
241
+ ) {
170
242
  return false;
171
243
  }
172
244
  if (type && token.type !== type) {
173
245
  return false;
174
246
  }
247
+ if (typography && !token.typography) {
248
+ return false;
249
+ }
175
250
  return true;
176
251
  });
177
252
 
@@ -208,7 +283,7 @@ export function TokenTableBlock({
208
283
  </table>
209
284
  );
210
285
  }
211
- `}function T(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
286
+ `}function P(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
212
287
  ## Colors
213
288
 
214
289
  <ColorPaletteBlock />
@@ -216,37 +291,53 @@ export function TokenTableBlock({
216
291
  ## Typography
217
292
 
218
293
  <TypesetBlock />
294
+ `:``,i=e.hasSizes?`
295
+ ## Size
296
+
297
+ <TokenTableBlock filter="size" />
298
+ `:``,a=e.hasSpaces?`
299
+ ## Space
300
+
301
+ <TokenTableBlock filter={[
302
+ "space",
303
+ "spacing"
304
+ ]} />
219
305
  `:``;return`import { Meta } from "@storybook/addon-docs/blocks";
220
306
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
221
307
  import { TokenTableBlock } from "./blocks/TokenTable";
222
308
  import { TypesetBlock } from "./blocks/Typeset";
223
309
 
224
- <Meta title="${_(t)}/Overview" />
310
+ <Meta title="${C(t)}/Overview" />
225
311
 
226
312
  # ${t}
227
313
 
228
314
  Design tokens generated by \`@razorwind/storybook\` for Storybook MDX docs.
229
- ${n}${r}
315
+ ${n}${r}${i}${a}
230
316
  ## All tokens
231
317
 
232
318
  <TokenTableBlock />
233
- `}function ee(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
319
+ `}function F(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
234
320
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
235
321
 
236
- <Meta title="${_(e.titlePrefix??`Design Tokens`)}/Colors" />
322
+ <Meta title="${C(e.titlePrefix??`Design Tokens`)}/Colors" />
237
323
 
238
324
  # Colors
239
325
 
240
326
  <ColorPaletteBlock />
241
- `}function E(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
327
+ `}function I(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
242
328
  import { TypesetBlock } from "./blocks/Typeset";
329
+ import { TokenTableBlock } from "./blocks/TokenTable";
243
330
 
244
- <Meta title="${_(e.titlePrefix??`Design Tokens`)}/Typography" />
331
+ <Meta title="${C(e.titlePrefix??`Design Tokens`)}/Typography" />
245
332
 
246
333
  # Typography
247
334
 
248
335
  <TypesetBlock />
249
- `}function D(e,t){let n=e[t];return typeof n==`string`?n:void 0}function O(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function k(e){return`import { IconGallery, IconItem } from "@storybook/addon-docs/blocks";
336
+
337
+ ## Typography tokens
338
+
339
+ <TokenTableBlock typography />
340
+ `}function L(e,t){let n=e[t];return typeof n==`string`?n:void 0}function R(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function z(e){return`import { IconGallery, IconItem } from "@storybook/addon-docs/blocks";
250
341
 
251
342
  /**
252
343
  * Icons rendered with Storybook's IconGallery doc block.
@@ -256,30 +347,33 @@ import { TypesetBlock } from "./blocks/Typeset";
256
347
  export function IconGalleryBlock() {
257
348
  return (
258
349
  <IconGallery>
259
- ${(O(e)?Object.values(e).filter(O).toSorted((e,t)=>(D(e,`name`)??``).localeCompare(D(t,`name`)??``)):[]).map(e=>{let t=D(e,`name`)??`unknown`,n=(Array.isArray(e.files)?e.files:[]).find(e=>O(e)&&D(e,`type`)===`svg`&&typeof e.content==`string`),r=O(n)&&typeof n.content==`string`?`<span
350
+ ${(R(e)?Object.values(e).filter(R).toSorted((e,t)=>(L(e,`name`)??``).localeCompare(L(t,`name`)??``)):[]).map(e=>{let t=L(e,`name`)??`unknown`,n=(Array.isArray(e.files)?e.files:[]).find(e=>R(e)&&L(e,`type`)===`svg`&&typeof e.content==`string`),r=R(n)&&typeof n.content==`string`?`<span
260
351
  style={{ display: "inline-flex", width: 24, height: 24 }}
261
- dangerouslySetInnerHTML={{ __html: ${v(n.content)} }}
262
- />`:`<code>${_(t)}</code>`;return` <IconItem name={${v(t)}}>
352
+ dangerouslySetInnerHTML={{ __html: ${w(n.content)} }}
353
+ />`:`<code>${C(t)}</code>`;return` <IconItem name={${w(t)}}>
263
354
  ${r}
264
355
  </IconItem>`}).join(`
265
356
  `)||` {/* No icons */}`}
266
357
  </IconGallery>
267
358
  );
268
359
  }
269
- `}function A(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
360
+ `}function B(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
270
361
  import { IconGalleryBlock } from "./blocks/IconGallery";
271
362
 
272
- <Meta title="${_(e.titlePrefix??`Design Tokens`)}/Icons" />
363
+ <Meta title="${C(e.titlePrefix??`Design Tokens`)}/Icons" />
273
364
 
274
365
  # Icons
275
366
 
276
367
  <IconGalleryBlock />
277
- `}function j(){return`export { ColorPaletteBlock } from "./ColorPalette";
278
- export { IconGalleryBlock } from "./IconGallery";
368
+ `}function V(e=!0){return`export { ColorPaletteBlock } from "./ColorPalette";
369
+ export type { ColorPaletteBlockProps } from "./ColorPalette";
370
+ ${e?`export { IconGalleryBlock } from "./IconGallery";
371
+ `:``}
279
372
  export { TokenTableBlock } from "./TokenTable";
280
373
  export type { TokenTableBlockProps, TokenTableRow } from "./TokenTable";
281
374
  export { TypesetBlock } from "./Typeset";
282
- `}const M=new Set(`base.colorPrimary.colorSecondary.appBg.appContentBg.appHoverBg.appPreviewBg.appBorderColor.appBorderRadius.fontBase.fontCode.textColor.textInverseColor.textMutedColor.barTextColor.barHoverColor.barSelectedColor.barBg.buttonBg.buttonBorder.booleanBg.booleanSelectedBg.inputBg.inputBorder.inputTextColor.inputBorderRadius.brandTitle.brandUrl.brandImage.brandTarget.gridCellSize`.split(`.`));function N(e){return O(e)?e.base===`light`||e.base===`dark`:!1}function P(e){return O(e)?N(e)?!0:Object.keys(e).some(e=>M.has(e)):!1}function F(e){if(!O(e)||P(e))return!1;let t=Object.values(e);return t.length>0&&t.every(P)}function I(e,t,n){return t.base===`light`||t.base===`dark`?t.base:`${e} ${n??``}`.toLowerCase().includes(`light`)?`light`:`dark`}function L(e){return/^[a-z_$][\w$]*$/i.test(e)?e:v(e)}function R(e,t){let n=e.find(e=>e.id===a);return!n||l(t.id)?t.tokens:u(t.tokens,n.tokens)}const z=/^\{([^{}]+)\}$/;function B(e){if(typeof e==`string`)return z.exec(e.trim())?.[1]?.trim()}function V(e){return O(e)&&`$value`in e&&!(`colorSpace`in e)&&!(`hex`in e)?e.$value:e}function H(e,t){let n=V(e),r=new Set;for(let e=0;e<8;e++){let e=B(n);if(!e||r.has(e))break;r.add(e);let i=t.get(e);if(!i)break;n=i.value}return n}function U(e){return e==null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?e:c(e)}function W(e,t){let n=f(e),r=n.find(e=>e.id===t)??(n.length===1?n[0]:void 0),i=r?R(n,r):e,a=new Map;for(let e of g(i))(!a.get(e.path)||e.theme===t)&&a.set(e.path,e);return a}function G(e,t){let n={...e};for(let[r,i]of Object.entries(e))r!==`base`&&i!==void 0&&(n[r]=U(H(i,t)));return n}function K(e,t,n,r,i){let a=G(t,W(i.tokens,e));return q(I(e,a,i.theme),a,n,r)}function q(e,a,o,s){let c=i(s,n),l=i(s,t);return{brandTarget:`_blank`,base:e||`light`,...a,brandTitle:a.brandTitle??o.title,brandUrl:a.brandUrl??o.homepage,brandImage:a.brandImage??o.logo,fontBase:a.fontBase??(c?r(c):void 0),fontCode:a.fontCode??(l?r(l):void 0)}}function J(e,t=``){return`create({\n${Object.entries(e).filter(([,e])=>e!==void 0).map(([e,n])=>`${t} ${e}: ${v(n)}`).join(`,
375
+ export type { TypesetBlockProps } from "./Typeset";
376
+ `}const H=new Set(`base.colorPrimary.colorSecondary.appBg.appContentBg.appHoverBg.appPreviewBg.appBorderColor.appBorderRadius.fontBase.fontCode.textColor.textInverseColor.textMutedColor.barTextColor.barHoverColor.barSelectedColor.barBg.buttonBg.buttonBorder.booleanBg.booleanSelectedBg.inputBg.inputBorder.inputTextColor.inputBorderRadius.brandTitle.brandUrl.brandImage.brandTarget.gridCellSize`.split(`.`));function U(e){return R(e)?e.base===`light`||e.base===`dark`:!1}function W(e){return R(e)?U(e)?!0:Object.keys(e).some(e=>H.has(e)):!1}function G(e){if(!R(e)||W(e))return!1;let t=Object.values(e);return t.length>0&&t.every(W)}function de(e,t,n){return t.base===`light`||t.base===`dark`?t.base:`${e} ${n??``}`.toLowerCase().includes(`light`)?`light`:`dark`}function fe(e){return/^[a-z_$][\w$]*$/i.test(e)?e:w(e)}function K(e,t){let n=e.find(e=>e.id===a);return!n||u(t.id)?t.tokens:f(t.tokens,n.tokens)}function pe(e){return R(e)&&`$value`in e&&!(`colorSpace`in e)&&!(`hex`in e)?e.$value:e}function me(e,t){let n=pe(e),r=new Set;for(let e=0;e<8;e++){let e=k(n);if(!e||r.has(e))break;r.add(e);let i=t.get(e);if(!i)break;n=i.value}return n}function he(e){return e==null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?e:c(e)}function ge(e,t){let n=p(e),r=n.find(e=>e.id===t)??(n.length===1?n[0]:void 0),i=r?K(n,r):e,a=new Map;for(let e of S(i))(!a.get(e.path)||e.theme===t)&&a.set(e.path,e);return a}function _e(e,t){let n={...e};for(let[r,i]of Object.entries(e))r!==`base`&&i!==void 0&&(n[r]=he(me(i,t)));return n}function ve(e,t,n,r,i){let a=_e(t,ge(i.tokens,e));return q(de(e,a,i.theme),a,n,r)}function q(e,a,o,s){let c=i(s,n),l=i(s,t);return{brandTarget:`_blank`,base:e||`light`,...a,brandTitle:a.brandTitle??o.title,brandUrl:a.brandUrl??o.homepage,brandImage:a.brandImage??o.logo,fontBase:a.fontBase??(c?r(c):void 0),fontCode:a.fontCode??(l?r(l):void 0)}}function J(e,t=``){return`create({\n${Object.entries(e).filter(([,e])=>e!==void 0).map(([e,n])=>`${t} ${e}: ${w(n)}`).join(`,
283
377
  `)}\n${t}})`}function Y(e){return`import { create } from "storybook/theming";
284
378
 
285
379
  /**
@@ -296,8 +390,8 @@ export default ${J(e)};
296
390
  * @see https://storybook.js.org/docs/configure/user-interface/theming
297
391
  */
298
392
  export default {
299
- ${Object.entries(e).map(([e,t])=>` ${L(e)}: ${J(t,` `)}`).join(`,
393
+ ${Object.entries(e).map(([e,t])=>` ${fe(e)}: ${J(t,` `)}`).join(`,
300
394
  `)}
301
395
  };
302
- `}function Z(e){if(N(e))return Y(e);let t=Object.entries(e);if(t.length!==1)return X(e);let[,n]=t[0]??[];return n?Y(n):X(e)}function Q(e,t,n,r){let i=(e,r)=>K(e,r,n,t.fonts,t);if(F(e))return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,i(e,t)]));let a=f(t.tokens),o=a.filter(e=>!l(e.id));if(o.length>1){let e={};for(let t of o){let n=r(R(a,t));if(F(n)){let r=n[t.id];if(r){e[t.id]=i(t.id,r);continue}for(let[t,r]of Object.entries(n))e[t]=i(t,r);continue}P(n)&&(e[t.id]=i(t.id,n))}return e}if(P(e)){let n=o[0]&&o[0].id!=="default"?o[0].id:t.theme??`default`;return{[n]:i(n,e)}}return{}}const te=e=>(t,n,r)=>o(h(e,t),n,{name:`razorwind-storybook`},!1,r);function $(e,t={}){let n=t.outputPath??`storybook/tokens`,r=d(e),i=t.titlePrefix??r.title??`Design Tokens`,a={...t,titlePrefix:i},o=g(e.tokens,t),s=o.some(e=>e.type===`color`),c=e.fonts&&Object.keys(e.fonts).length>0||o.some(e=>e.type===`fontFamily`||e.type===`fontWeight`||e.type===`typography`||e.type===`dimension`&&/(?:font|type|text).*size|size.*(?:font|type|text)/i.test(e.path)),l=!t.skipIcons&&O(e.icons)&&Object.keys(e.icons).length>0,u=te(n),f={[h(n,`blocks/ColorPalette.tsx`)]:u(`blocks/ColorPalette.tsx`,S(o,a),`tsx`),[h(n,`blocks/Typeset.tsx`)]:u(`blocks/Typeset.tsx`,C(o,{...a,fonts:e.fonts}),`tsx`),[h(n,`blocks/TokenTable.tsx`)]:u(`blocks/TokenTable.tsx`,w(o),`tsx`),[h(n,`blocks/IconGallery.tsx`)]:u(`blocks/IconGallery.tsx`,k(t.skipIcons?{}:e.icons),`tsx`),[h(n,`blocks/index.ts`)]:u(`blocks/index.ts`,j(),`typescript`),[h(n,`Tokens.mdx`)]:u(`Tokens.mdx`,T({titlePrefix:i,hasColors:s,hasTypography:c}),`mdx`)};s&&(f[h(n,`Colors.mdx`)]=u(`Colors.mdx`,ee(a),`mdx`)),c&&(f[h(n,`Typography.mdx`)]=u(`Typography.mdx`,E(a),`mdx`)),l&&(f[h(n,`Icons.mdx`)]=u(`Icons.mdx`,A(a),`mdx`)),f[h(n,`tokens.json`)]=u(`tokens.json`,`${JSON.stringify(o,null,2)}\n`,`json`);let p;if(t.mapTheme){let i=Q(t.mapTheme(e.tokens),e,r,t.mapTheme);Object.keys(i).length>0&&(p=Object.keys(i),f[h(n,`theme.ts`)]=u(`theme.ts`,Z(i),`typescript`))}let m=`INSTALL.md`;return f[h(n,m)]=u(m,t.installGuide??y({outputPath:n,titlePrefix:i,themeFiles:p?[`theme.ts`]:void 0,themeNames:p}),`markdown`),f}var ne=e(e=>({name:`storybook`,themeGeneration:`combined`,generate:async t=>$(t,e??{})}));export{q as applyBrandDefaults,ne as default,g as flattenTokens,c as formatTokenValue,$ as generateTokenDocs,Q as normalizeThemes,y as renderInstallMd,Z as renderThemeFile,f as resolveTokenSets,p as toCssVar};
396
+ `}function Z(e){if(U(e))return Y(e);let t=Object.entries(e);if(t.length!==1)return X(e);let[,n]=t[0]??[];return n?Y(n):X(e)}function Q(e,t,n,r){let i=(e,r)=>ve(e,r,n,t.fonts,t);if(G(e))return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,i(e,t)]));let a=p(t.tokens),o=a.filter(e=>!u(e.id));if(o.length>1){let e={};for(let t of o){let n=r(K(a,t));if(G(n)){let r=n[t.id];if(r){e[t.id]=i(t.id,r);continue}for(let[t,r]of Object.entries(n))e[t]=i(t,r);continue}W(n)&&(e[t.id]=i(t.id,n))}return e}if(W(e)){let n=o[0]&&o[0].id!=="default"?o[0].id:t.theme??`default`;return{[n]:i(n,e)}}return{}}const ye=e=>(t,n,r)=>o(_(e,t),n,{name:`razorwind-storybook`},!1,r);function $(e,t={}){let n=t.outputPath??`storybook/tokens`,r=ee(e),i=t.titlePrefix??r.title??`Design Tokens`,a={...t,titlePrefix:i},o=S(e.tokens,t),s=oe(e.tokens,t),c=o.some(e=>e.type===`color`),l=e.fonts&&Object.keys(e.fonts).length>0||o.some(D),u=O(o,[`size`]),d=O(o,[`space`,`spacing`]),f=!t.skipIcons&&R(e.icons)&&Object.keys(e.icons).length>0,p=ye(n),m={[_(n,`blocks/ColorPalette.tsx`)]:p(`blocks/ColorPalette.tsx`,le(s,a),`tsx`),[_(n,`blocks/Typeset.tsx`)]:p(`blocks/Typeset.tsx`,ue(s,{...a,fonts:e.fonts}),`tsx`),[_(n,`blocks/TokenTable.tsx`)]:p(`blocks/TokenTable.tsx`,N(s),`tsx`),[_(n,`blocks/index.ts`)]:p(`blocks/index.ts`,V(f),`typescript`),[_(n,`Tokens.mdx`)]:p(`Tokens.mdx`,P({titlePrefix:i,hasColors:c,hasTypography:l,hasSizes:u,hasSpaces:d}),`mdx`)};f&&(m[_(n,`blocks/IconGallery.tsx`)]=p(`blocks/IconGallery.tsx`,z(e.icons),`tsx`)),M(s)&&(m[_(n,`blocks/ThemeVariant.ts`)]=p(`blocks/ThemeVariant.ts`,ae(),`typescript`)),c&&(m[_(n,`Colors.mdx`)]=p(`Colors.mdx`,F(a),`mdx`)),l&&(m[_(n,`Typography.mdx`)]=p(`Typography.mdx`,I(a),`mdx`)),f&&(m[_(n,`Icons.mdx`)]=p(`Icons.mdx`,B(a),`mdx`)),m[_(n,`tokens.json`)]=p(`tokens.json`,`${JSON.stringify(o,null,2)}\n`,`json`);let h;if(t.mapTheme){let i=Q(t.mapTheme(e.tokens),e,r,t.mapTheme);Object.keys(i).length>0&&(h=Object.keys(i),m[_(n,`theme.ts`)]=p(`theme.ts`,Z(i),`typescript`))}let g=`INSTALL.md`;return m[_(n,g)]=p(g,t.installGuide??T({outputPath:n,titlePrefix:i,themeFiles:h?[`theme.ts`]:void 0,themeNames:h,tokenThemeNames:Object.keys(s)}),`markdown`),m}var be=e(e=>({name:`storybook`,themeGeneration:`combined`,generate:async t=>$(t,e??{})}));export{q as applyBrandDefaults,be as default,S as flattenTokens,c as formatTokenValue,$ as generateTokenDocs,Q as normalizeThemes,T as renderInstallMd,Z as renderThemeFile,p as resolveTokenSets,m as toCssVar};
303
397
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@razorwind/storybook",
3
- "version": "0.0.59",
3
+ "version": "0.0.61",
4
4
  "type": "module",
5
5
  "description": "Razorwind plugin that creates Storybook MDX token doc blocks from Razorwind design tokens.",
6
6
  "repository": {
@@ -83,11 +83,11 @@
83
83
  "types": "./dist/index.d.cts",
84
84
  "typings": "dist/index.d.mts",
85
85
  "dependencies": {
86
- "@power-plant/core": "^0.0.91",
86
+ "@power-plant/core": "^0.0.92",
87
87
  "@power-plant/dtcg-schema": "^0.0.1",
88
- "@razorwind/core": "^0.0.62",
89
- "@stryke/path": "^0.29.39",
90
- "@stryke/type-checks": "^0.6.45"
88
+ "@razorwind/core": "^0.0.64",
89
+ "@stryke/path": "^0.29.41",
90
+ "@stryke/type-checks": "^0.6.47"
91
91
  },
92
92
  "peerDependencies": {
93
93
  "@storybook/addon-docs": ">=8",
@@ -100,11 +100,11 @@
100
100
  "storybook": { "optional": true }
101
101
  },
102
102
  "devDependencies": {
103
- "@powerlines/plugin-tsdown": "^0.1.612",
104
- "@stryke/types": "^0.12.40",
103
+ "@powerlines/plugin-tsdown": "^0.1.613",
104
+ "@stryke/types": "^0.12.42",
105
105
  "@types/node": "^25.9.5",
106
106
  "typescript": "^6.0.3"
107
107
  },
108
108
  "publishConfig": { "access": "public" },
109
- "gitHead": "a131e145ede6e508e751aa6c1a3bd95fc3e76245"
109
+ "gitHead": "49873beaca1bec96f7d6869f9dcd8c20efd2be41"
110
110
  }