@razorwind/storybook 0.0.60 → 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){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,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=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,7 +71,25 @@ 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 p(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 m(e,t){return e===t?e.split(`.`).at(-1)??e:e.startsWith(`${t}.`)?e.slice(t.length+1):e.split(`.`).at(-1)??e}function h(e,t={}){let n=e.filter(e=>e.type===`color`),r=t.colorGroupBy??2,i=(e,t=` `)=>[...p(e,r).entries()].toSorted(([e],[t])=>e.localeCompare(t)).map(([e,n])=>{let r=n.map(n=>`${t} ${d(m(n.path,e))}: ${d(n.cssValue)}`).join(`,
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";
75
+
76
+ /**
77
+ * Select a generated token variant. By default this follows Storybook's
78
+ * \`theme\` global; callers may pass \`theme\` to override it.
79
+ */
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(`,
69
93
  `),i=n.find(e=>e.description)?.description??`${n.length} token${n.length===1?``:`s`}`;return`${t}<ColorItem
70
94
  title={${d(e)}}
71
95
  subtitle={${d(i)}}
@@ -73,46 +97,80 @@ Re-run Razorwind generate when tokens change to refresh docs under \`${e.outputP
73
97
  ${r}
74
98
  }}
75
99
  />`}).join(`
76
- `),a=n.filter(e=>e.palette),o=n.filter(e=>!e.palette&&e.childTheme),s=n.filter(e=>!e.palette&&!e.childTheme),c=a.length>0||o.length>0,l=i(n),u=[[`Color palettes`,a],[`Semantic colors`,o],[`Colors`,s]].filter(e=>!!e[1]&&e[1].length>0).map(([e,t])=>` <section>
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>
77
101
  <h2>${e}</h2>
78
102
  <ColorPalette>
79
- ${i(t,` `)}
103
+ ${o(t,` `)}
80
104
  </ColorPalette>
81
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(`,
82
107
  `);return`import { ColorPalette, ColorItem } from "@storybook/addon-docs/blocks";
108
+ ${a?`import { useThemeVariant } from "./ThemeVariant";
109
+ `:``}
83
110
 
84
111
  /**
85
112
  * Color tokens rendered with Storybook's ColorPalette doc block.
86
113
  *
87
114
  * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-colorpalette
88
115
  */
89
- export function ColorPaletteBlock() {
90
- return (
91
- ${c?` <>
92
- ${u}
93
- </>`:` <ColorPalette>
94
- ${l||` {/* No color tokens */}`}
95
- </ColorPalette>`}
96
- );
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;
97
123
  }
98
- `}function g(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)],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`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
+ `:``}
99
139
 
100
140
  /**
101
141
  * Typography tokens rendered with Storybook's Typeset doc block.
102
142
  *
103
143
  * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-typeset
104
144
  */
105
- export function TypesetBlock() {
106
- return (
107
- <Typeset
108
- fontFamily={${d(s)}}
109
- fontSizes={${u}}
110
- fontWeight={${d(l)}}
111
- sampleText={${d(r)}}
112
- />
113
- );
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;
114
152
  }
115
- `}function _(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
+ `:``}
116
174
 
117
175
  export interface TokenTableRow {
118
176
  path: string;
@@ -121,19 +179,12 @@ export interface TokenTableRow {
121
179
  cssVar: string;
122
180
  description?: string;
123
181
  theme?: string;
182
+ typography: boolean;
124
183
  }
125
184
 
126
- const TOKENS: TokenTableRow[] = [
127
- ${e.map(e=>{let t=e.theme?d(e.theme):`undefined`;return` {
128
- path: ${d(e.path)},
129
- type: ${e.type?d(e.type):`undefined`},
130
- value: ${d(e.cssValue)},
131
- cssVar: ${d(e.cssVar)},
132
- description: ${e.description?d(e.description):`undefined`},
133
- theme: ${t}
134
- }`}).join(`,
135
- `)||``}
136
- ];
185
+ const TOKEN_VARIANTS: Record<string, TokenTableRow[]> = {
186
+ ${a}
187
+ };
137
188
 
138
189
  const tableStyle: CSSProperties = {
139
190
  width: "100%",
@@ -160,10 +211,14 @@ const swatchStyle = (value: string): CSSProperties => ({
160
211
  });
161
212
 
162
213
  export interface TokenTableBlockProps {
163
- /** Optional path prefix filter (e.g. \`color\`). */
164
- filter?: string;
214
+ /** Optional path prefix filter or filters (e.g. \`color\`). */
215
+ filter?: string | string[];
165
216
  /** Optional DTCG \`$type\` filter. */
166
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;
167
222
  }
168
223
 
169
224
  /**
@@ -171,15 +226,27 @@ export interface TokenTableBlockProps {
171
226
  */
172
227
  export function TokenTableBlock({
173
228
  filter,
174
- type
229
+ type,
230
+ typography,
231
+ theme
175
232
  }: TokenTableBlockProps = {}): ReactElement {
176
- const rows = TOKENS.filter(token => {
177
- 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
+ ) {
178
242
  return false;
179
243
  }
180
244
  if (type && token.type !== type) {
181
245
  return false;
182
246
  }
247
+ if (typography && !token.typography) {
248
+ return false;
249
+ }
183
250
  return true;
184
251
  });
185
252
 
@@ -216,7 +283,7 @@ export function TokenTableBlock({
216
283
  </table>
217
284
  );
218
285
  }
219
- `}function v(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
286
+ `}function k(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
220
287
  ## Colors
221
288
 
222
289
  <ColorPaletteBlock />
@@ -224,6 +291,17 @@ export function TokenTableBlock({
224
291
  ## Typography
225
292
 
226
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
+ ]} />
227
305
  `:``;return`import { Meta } from "@storybook/addon-docs/blocks";
228
306
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
229
307
  import { TokenTableBlock } from "./blocks/TokenTable";
@@ -234,11 +312,11 @@ import { TypesetBlock } from "./blocks/Typeset";
234
312
  # ${t}
235
313
 
236
314
  Design tokens generated by \`@razorwind/storybook\` for Storybook MDX docs.
237
- ${n}${r}
315
+ ${n}${r}${i}${a}
238
316
  ## All tokens
239
317
 
240
318
  <TokenTableBlock />
241
- `}function y(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
319
+ `}function A(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
242
320
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
243
321
 
244
322
  <Meta title="${u(e.titlePrefix??`Design Tokens`)}/Colors" />
@@ -246,15 +324,20 @@ import { ColorPaletteBlock } from "./blocks/ColorPalette";
246
324
  # Colors
247
325
 
248
326
  <ColorPaletteBlock />
249
- `}function b(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
327
+ `}function j(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
250
328
  import { TypesetBlock } from "./blocks/Typeset";
329
+ import { TokenTableBlock } from "./blocks/TokenTable";
251
330
 
252
331
  <Meta title="${u(e.titlePrefix??`Design Tokens`)}/Typography" />
253
332
 
254
333
  # Typography
255
334
 
256
335
  <TypesetBlock />
257
- `}function x(e,t){let n=e[t];return typeof n==`string`?n:void 0}function S(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function C(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";
258
341
 
259
342
  /**
260
343
  * Icons rendered with Storybook's IconGallery doc block.
@@ -264,7 +347,7 @@ import { TypesetBlock } from "./blocks/Typeset";
264
347
  export function IconGalleryBlock() {
265
348
  return (
266
349
  <IconGallery>
267
- ${(S(e)?Object.values(e).filter(S).toSorted((e,t)=>(x(e,`name`)??``).localeCompare(x(t,`name`)??``)):[]).map(e=>{let t=x(e,`name`)??`unknown`,n=(Array.isArray(e.files)?e.files:[]).find(e=>S(e)&&x(e,`type`)===`svg`&&typeof e.content==`string`),r=S(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
268
351
  style={{ display: "inline-flex", width: 24, height: 24 }}
269
352
  dangerouslySetInnerHTML={{ __html: ${d(n.content)} }}
270
353
  />`:`<code>${u(t)}</code>`;return` <IconItem name={${d(t)}}>
@@ -274,7 +357,7 @@ ${(S(e)?Object.values(e).filter(S).toSorted((e,t)=>(x(e,`name`)??``).localeCompa
274
357
  </IconGallery>
275
358
  );
276
359
  }
277
- `}function w(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
360
+ `}function ne(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
278
361
  import { IconGalleryBlock } from "./blocks/IconGallery";
279
362
 
280
363
  <Meta title="${u(e.titlePrefix??`Design Tokens`)}/Icons" />
@@ -282,21 +365,24 @@ import { IconGalleryBlock } from "./blocks/IconGallery";
282
365
  # Icons
283
366
 
284
367
  <IconGalleryBlock />
285
- `}function T(){return`export { ColorPaletteBlock } from "./ColorPalette";
286
- 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
+ `:``}
287
372
  export { TokenTableBlock } from "./TokenTable";
288
373
  export type { TokenTableBlockProps, TokenTableRow } from "./TokenTable";
289
374
  export { TypesetBlock } from "./Typeset";
290
- `}const E=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 D(e){return S(e)?e.base===`light`||e.base===`dark`:!1}function O(e){return S(e)?D(e)?!0:Object.keys(e).some(e=>E.has(e)):!1}function k(e){if(!S(e)||O(e))return!1;let t=Object.values(e);return t.length>0&&t.every(O)}function A(e,t,n){return t.base===`light`||t.base===`dark`?t.base:`${e} ${n??``}`.toLowerCase().includes(`light`)?`light`:`dark`}function j(e){return/^[a-z_$][\w$]*$/i.test(e)?e:d(e)}function M(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 N=/^\{([^{}]+)\}$/;function P(e){if(typeof e==`string`)return N.exec(e.trim())?.[1]?.trim()}function F(e){return S(e)&&`$value`in e&&!(`colorSpace`in e)&&!(`hex`in e)?e.$value:e}function I(e,t){let n=F(e),r=new Set;for(let e=0;e<8;e++){let e=P(n);if(!e||r.has(e))break;r.add(e);let i=t.get(e);if(!i)break;n=i.value}return n}function L(e){return e==null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?e:(0,n.formatTokenValue)(e)}function R(e,t){let r=(0,n.resolveTokenSets)(e),i=r.find(e=>e.id===t)??(r.length===1?r[0]:void 0),a=i?M(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 z(e,t){let n={...e};for(let[r,i]of Object.entries(e))r!==`base`&&i!==void 0&&(n[r]=L(I(i,t)));return n}function B(e,t,n,r,i){let a=z(t,R(i.tokens,e));return V(A(e,a,i.theme),a,n,r)}function V(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 H(e,t=``){return`create({\n${Object.entries(e).filter(([,e])=>e!==void 0).map(([e,n])=>`${t} ${e}: ${d(n)}`).join(`,
291
- `)}\n${t}})`}function U(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";
292
378
 
293
379
  /**
294
380
  * Storybook UI theme generated by \`@razorwind/storybook\`.
295
381
  *
296
382
  * @see https://storybook.js.org/docs/configure/user-interface/theming
297
383
  */
298
- export default ${H(e)};
299
- `}function W(e){return`import { create } from "storybook/theming";
384
+ export default ${J(e)};
385
+ `}function X(e){return`import { create } from "storybook/theming";
300
386
 
301
387
  /**
302
388
  * Storybook UI themes generated by \`@razorwind/storybook\`.
@@ -304,7 +390,7 @@ export default ${H(e)};
304
390
  * @see https://storybook.js.org/docs/configure/user-interface/theming
305
391
  */
306
392
  export default {
307
- ${Object.entries(e).map(([e,t])=>` ${j(e)}: ${H(t,` `)}`).join(`,
393
+ ${Object.entries(e).map(([e,t])=>` ${z(e)}: ${J(t,` `)}`).join(`,
308
394
  `)}
309
395
  };
310
- `}function G(e){if(D(e))return U(e);let t=Object.entries(e);if(t.length!==1)return W(e);let[,n]=t[0]??[];return n?U(n):W(e)}function K(e,t,r,i){let a=(e,n)=>B(e,n,r,t.fonts,t);if(k(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(M(o,t));if(k(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}O(n)&&(e[t.id]=a(t.id,n))}return e}if(O(e)){let n=s[0]&&s[0].id!=="default"?s[0].id:t.theme??`default`;return{[n]:a(n,e)}}return{}}const q=e=>(t,i,a)=>(0,n.createDocument)((0,r.joinPaths)(e,t),i,{name:`razorwind-storybook`},!1,a);function J(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.some(e=>e.type===`color`),d=e.fonts&&Object.keys(e.fonts).length>0||c.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)),p=!t.skipIcons&&S(e.icons)&&Object.keys(e.icons).length>0,m=q(i),x={[(0,r.joinPaths)(i,`blocks/ColorPalette.tsx`)]:m(`blocks/ColorPalette.tsx`,h(c,s),`tsx`),[(0,r.joinPaths)(i,`blocks/Typeset.tsx`)]:m(`blocks/Typeset.tsx`,g(c,{...s,fonts:e.fonts}),`tsx`),[(0,r.joinPaths)(i,`blocks/TokenTable.tsx`)]:m(`blocks/TokenTable.tsx`,_(c),`tsx`),[(0,r.joinPaths)(i,`blocks/IconGallery.tsx`)]:m(`blocks/IconGallery.tsx`,C(t.skipIcons?{}:e.icons),`tsx`),[(0,r.joinPaths)(i,`blocks/index.ts`)]:m(`blocks/index.ts`,T(),`typescript`),[(0,r.joinPaths)(i,`Tokens.mdx`)]:m(`Tokens.mdx`,v({titlePrefix:o,hasColors:u,hasTypography:d}),`mdx`)};u&&(x[(0,r.joinPaths)(i,`Colors.mdx`)]=m(`Colors.mdx`,y(s),`mdx`)),d&&(x[(0,r.joinPaths)(i,`Typography.mdx`)]=m(`Typography.mdx`,b(s),`mdx`)),p&&(x[(0,r.joinPaths)(i,`Icons.mdx`)]=m(`Icons.mdx`,w(s),`mdx`)),x[(0,r.joinPaths)(i,`tokens.json`)]=m(`tokens.json`,`${JSON.stringify(c,null,2)}\n`,`json`);let E;if(t.mapTheme){let n=K(t.mapTheme(e.tokens),e,a,t.mapTheme);Object.keys(n).length>0&&(E=Object.keys(n),x[(0,r.joinPaths)(i,`theme.ts`)]=m(`theme.ts`,G(n),`typescript`))}let D=`INSTALL.md`;return x[(0,r.joinPaths)(i,D)]=m(D,t.installGuide??f({outputPath:i,titlePrefix:o,themeFiles:E?[`theme.ts`]:void 0,themeNames:E}),`markdown`),x}var Y=(0,e.definePlugin)(e=>({name:`storybook`,themeGeneration:`combined`,generate:async t=>J(t,e??{})}));exports.applyBrandDefaults=V,exports.default=Y,exports.flattenTokens=l,Object.defineProperty(exports,"formatTokenValue",{enumerable:!0,get:function(){return n.formatTokenValue}}),exports.generateTokenDocs=J,exports.normalizeThemes=K,exports.renderInstallMd=f,exports.renderThemeFile=G,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
@@ -157,6 +157,7 @@ declare function renderInstallMd(options: {
157
157
  titlePrefix?: string;
158
158
  themeFiles?: string[];
159
159
  themeNames?: string[];
160
+ tokenThemeNames?: string[];
160
161
  }): string;
161
162
  //#endregion
162
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;;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;;;;;;;iBCstBc,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
@@ -157,6 +157,7 @@ declare function renderInstallMd(options: {
157
157
  titlePrefix?: string;
158
158
  themeFiles?: string[];
159
159
  themeNames?: string[];
160
+ tokenThemeNames?: string[];
160
161
  }): string;
161
162
  //#endregion
162
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,isObject as l,isSharedThemeId as u,isTokenLeaf as d,mergeTokenTrees as f,resolveSchemaIdentity as ee,resolveTokenSets as p,toCssVar as m,toCssVar as h}from"@razorwind/core/utils";import{joinPaths as g}from"@stryke/path/join";function _(e){return e===!0||e===`true`||e===1}function v(e,t){return e?`${e}:${t}`:t}function y(e){let t=e.theme??e.$theme;return typeof t==`string`&&t.length>0?t:void 0}function te(e,t){return e===`palette`||e===`$palette`?typeof t==`boolean`||typeof t==`number`||typeof t==`string`:(e===`theme`||e===`$theme`)&&typeof t==`string`}function b(e){let t=new Map;function n(e,r,i,a,o){if(!l(e))return;let s=a||_(e.palette)||_(e.$palette),c=y(e)??o;if(d(e)){(s||c)&&t.set(v(i,r.join(`.`)),{...s&&{palette:!0},...c&&{childTheme:c}});return}for(let[t,a]of Object.entries(e))t.startsWith(`$`)&&t!==`$palette`&&t!==`$theme`||te(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 x(e,t={}){let n=t.cssVarPrefix??`rw`,r=b(e);return s(e,{includeTypes:t.includeTypes,enrichToken:e=>{let t=r.get(v(e.theme,e.path));return{...e,cssVar:h(e.path,n),...e.type===`color`&&t}}})}function S(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`).replaceAll(`
2
- `,`\\n`).replaceAll(`\r`,`\\r`)}function C(e){return typeof e==`string`?`"${S(e)}"`:typeof e==`number`||typeof e==`boolean`?String(e):e==null?`undefined`:JSON.stringify(e)}function w(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,54 +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 T(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 E(e,t){return e===t?e.split(`.`).at(-1)??e:e.startsWith(`${t}.`)?e.slice(t.length+1):e.split(`.`).at(-1)??e}function D(e,t={}){let n=e.filter(e=>e.type===`color`),r=t.colorGroupBy??2,i=(e,t=` `)=>[...T(e,r).entries()].toSorted(([e],[t])=>e.localeCompare(t)).map(([e,n])=>{let r=n.map(n=>`${t} ${C(E(n.path,e))}: ${C(n.cssValue)}`).join(`,
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";
75
+
76
+ /**
77
+ * Select a generated token variant. By default this follows Storybook's
78
+ * \`theme\` global; callers may pass \`theme\` to override it.
79
+ */
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(`,
69
93
  `),i=n.find(e=>e.description)?.description??`${n.length} token${n.length===1?``:`s`}`;return`${t}<ColorItem
70
- title={${C(e)}}
71
- subtitle={${C(i)}}
94
+ title={${w(e)}}
95
+ subtitle={${w(i)}}
72
96
  colors={{
73
97
  ${r}
74
98
  }}
75
99
  />`}).join(`
76
- `),a=n.filter(e=>e.palette),o=n.filter(e=>!e.palette&&e.childTheme),s=n.filter(e=>!e.palette&&!e.childTheme),c=a.length>0||o.length>0,l=i(n),u=[[`Color palettes`,a],[`Semantic colors`,o],[`Colors`,s]].filter(e=>!!e[1]&&e[1].length>0).map(([e,t])=>` <section>
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>
77
101
  <h2>${e}</h2>
78
102
  <ColorPalette>
79
- ${i(t,` `)}
103
+ ${o(t,` `)}
80
104
  </ColorPalette>
81
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(`,
82
107
  `);return`import { ColorPalette, ColorItem } from "@storybook/addon-docs/blocks";
108
+ ${a?`import { useThemeVariant } from "./ThemeVariant";
109
+ `:``}
83
110
 
84
111
  /**
85
112
  * Color tokens rendered with Storybook's ColorPalette doc block.
86
113
  *
87
114
  * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-colorpalette
88
115
  */
89
- export function ColorPaletteBlock() {
90
- return (
91
- ${c?` <>
92
- ${u}
93
- </>`:` <ColorPalette>
94
- ${l||` {/* No color tokens */}`}
95
- </ColorPalette>`}
96
- );
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;
97
123
  }
98
- `}function ne(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=>C(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
+ `:``}
99
139
 
100
140
  /**
101
141
  * Typography tokens rendered with Storybook's Typeset doc block.
102
142
  *
103
143
  * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-typeset
104
144
  */
105
- export function TypesetBlock() {
106
- return (
107
- <Typeset
108
- fontFamily={${C(l)}}
109
- fontSizes={${f}}
110
- fontWeight={${C(d)}}
111
- sampleText={${C(a)}}
112
- />
113
- );
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;
114
152
  }
115
- `}function re(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
+ `:``}
116
174
 
117
175
  export interface TokenTableRow {
118
176
  path: string;
@@ -121,19 +179,12 @@ export interface TokenTableRow {
121
179
  cssVar: string;
122
180
  description?: string;
123
181
  theme?: string;
182
+ typography: boolean;
124
183
  }
125
184
 
126
- const TOKENS: TokenTableRow[] = [
127
- ${e.map(e=>{let t=e.theme?C(e.theme):`undefined`;return` {
128
- path: ${C(e.path)},
129
- type: ${e.type?C(e.type):`undefined`},
130
- value: ${C(e.cssValue)},
131
- cssVar: ${C(e.cssVar)},
132
- description: ${e.description?C(e.description):`undefined`},
133
- theme: ${t}
134
- }`}).join(`,
135
- `)||``}
136
- ];
185
+ const TOKEN_VARIANTS: Record<string, TokenTableRow[]> = {
186
+ ${a}
187
+ };
137
188
 
138
189
  const tableStyle: CSSProperties = {
139
190
  width: "100%",
@@ -160,10 +211,14 @@ const swatchStyle = (value: string): CSSProperties => ({
160
211
  });
161
212
 
162
213
  export interface TokenTableBlockProps {
163
- /** Optional path prefix filter (e.g. \`color\`). */
164
- filter?: string;
214
+ /** Optional path prefix filter or filters (e.g. \`color\`). */
215
+ filter?: string | string[];
165
216
  /** Optional DTCG \`$type\` filter. */
166
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;
167
222
  }
168
223
 
169
224
  /**
@@ -171,15 +226,27 @@ export interface TokenTableBlockProps {
171
226
  */
172
227
  export function TokenTableBlock({
173
228
  filter,
174
- type
229
+ type,
230
+ typography,
231
+ theme
175
232
  }: TokenTableBlockProps = {}): ReactElement {
176
- const rows = TOKENS.filter(token => {
177
- 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
+ ) {
178
242
  return false;
179
243
  }
180
244
  if (type && token.type !== type) {
181
245
  return false;
182
246
  }
247
+ if (typography && !token.typography) {
248
+ return false;
249
+ }
183
250
  return true;
184
251
  });
185
252
 
@@ -216,7 +283,7 @@ export function TokenTableBlock({
216
283
  </table>
217
284
  );
218
285
  }
219
- `}function ie(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
286
+ `}function P(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
220
287
  ## Colors
221
288
 
222
289
  <ColorPaletteBlock />
@@ -224,37 +291,53 @@ export function TokenTableBlock({
224
291
  ## Typography
225
292
 
226
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
+ ]} />
227
305
  `:``;return`import { Meta } from "@storybook/addon-docs/blocks";
228
306
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
229
307
  import { TokenTableBlock } from "./blocks/TokenTable";
230
308
  import { TypesetBlock } from "./blocks/Typeset";
231
309
 
232
- <Meta title="${S(t)}/Overview" />
310
+ <Meta title="${C(t)}/Overview" />
233
311
 
234
312
  # ${t}
235
313
 
236
314
  Design tokens generated by \`@razorwind/storybook\` for Storybook MDX docs.
237
- ${n}${r}
315
+ ${n}${r}${i}${a}
238
316
  ## All tokens
239
317
 
240
318
  <TokenTableBlock />
241
- `}function ae(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
319
+ `}function F(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
242
320
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
243
321
 
244
- <Meta title="${S(e.titlePrefix??`Design Tokens`)}/Colors" />
322
+ <Meta title="${C(e.titlePrefix??`Design Tokens`)}/Colors" />
245
323
 
246
324
  # Colors
247
325
 
248
326
  <ColorPaletteBlock />
249
- `}function oe(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
327
+ `}function I(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
250
328
  import { TypesetBlock } from "./blocks/Typeset";
329
+ import { TokenTableBlock } from "./blocks/TokenTable";
251
330
 
252
- <Meta title="${S(e.titlePrefix??`Design Tokens`)}/Typography" />
331
+ <Meta title="${C(e.titlePrefix??`Design Tokens`)}/Typography" />
253
332
 
254
333
  # Typography
255
334
 
256
335
  <TypesetBlock />
257
- `}function O(e,t){let n=e[t];return typeof n==`string`?n:void 0}function k(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function A(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";
258
341
 
259
342
  /**
260
343
  * Icons rendered with Storybook's IconGallery doc block.
@@ -264,30 +347,33 @@ import { TypesetBlock } from "./blocks/Typeset";
264
347
  export function IconGalleryBlock() {
265
348
  return (
266
349
  <IconGallery>
267
- ${(k(e)?Object.values(e).filter(k).toSorted((e,t)=>(O(e,`name`)??``).localeCompare(O(t,`name`)??``)):[]).map(e=>{let t=O(e,`name`)??`unknown`,n=(Array.isArray(e.files)?e.files:[]).find(e=>k(e)&&O(e,`type`)===`svg`&&typeof e.content==`string`),r=k(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
268
351
  style={{ display: "inline-flex", width: 24, height: 24 }}
269
- dangerouslySetInnerHTML={{ __html: ${C(n.content)} }}
270
- />`:`<code>${S(t)}</code>`;return` <IconItem name={${C(t)}}>
352
+ dangerouslySetInnerHTML={{ __html: ${w(n.content)} }}
353
+ />`:`<code>${C(t)}</code>`;return` <IconItem name={${w(t)}}>
271
354
  ${r}
272
355
  </IconItem>`}).join(`
273
356
  `)||` {/* No icons */}`}
274
357
  </IconGallery>
275
358
  );
276
359
  }
277
- `}function j(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
360
+ `}function B(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
278
361
  import { IconGalleryBlock } from "./blocks/IconGallery";
279
362
 
280
- <Meta title="${S(e.titlePrefix??`Design Tokens`)}/Icons" />
363
+ <Meta title="${C(e.titlePrefix??`Design Tokens`)}/Icons" />
281
364
 
282
365
  # Icons
283
366
 
284
367
  <IconGalleryBlock />
285
- `}function M(){return`export { ColorPaletteBlock } from "./ColorPalette";
286
- 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
+ `:``}
287
372
  export { TokenTableBlock } from "./TokenTable";
288
373
  export type { TokenTableBlockProps, TokenTableRow } from "./TokenTable";
289
374
  export { TypesetBlock } from "./Typeset";
290
- `}const N=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 P(e){return k(e)?e.base===`light`||e.base===`dark`:!1}function F(e){return k(e)?P(e)?!0:Object.keys(e).some(e=>N.has(e)):!1}function I(e){if(!k(e)||F(e))return!1;let t=Object.values(e);return t.length>0&&t.every(F)}function L(e,t,n){return t.base===`light`||t.base===`dark`?t.base:`${e} ${n??``}`.toLowerCase().includes(`light`)?`light`:`dark`}function R(e){return/^[a-z_$][\w$]*$/i.test(e)?e:C(e)}function z(e,t){let n=e.find(e=>e.id===a);return!n||u(t.id)?t.tokens:f(t.tokens,n.tokens)}const B=/^\{([^{}]+)\}$/;function V(e){if(typeof e==`string`)return B.exec(e.trim())?.[1]?.trim()}function H(e){return k(e)&&`$value`in e&&!(`colorSpace`in e)&&!(`hex`in e)?e.$value:e}function U(e,t){let n=H(e),r=new Set;for(let e=0;e<8;e++){let e=V(n);if(!e||r.has(e))break;r.add(e);let i=t.get(e);if(!i)break;n=i.value}return n}function W(e){return e==null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`?e:c(e)}function G(e,t){let n=p(e),r=n.find(e=>e.id===t)??(n.length===1?n[0]:void 0),i=r?z(n,r):e,a=new Map;for(let e of x(i))(!a.get(e.path)||e.theme===t)&&a.set(e.path,e);return a}function K(e,t){let n={...e};for(let[r,i]of Object.entries(e))r!==`base`&&i!==void 0&&(n[r]=W(U(i,t)));return n}function se(e,t,n,r,i){let a=K(t,G(i.tokens,e));return q(L(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}: ${C(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(`,
291
377
  `)}\n${t}})`}function Y(e){return`import { create } from "storybook/theming";
292
378
 
293
379
  /**
@@ -304,8 +390,8 @@ export default ${J(e)};
304
390
  * @see https://storybook.js.org/docs/configure/user-interface/theming
305
391
  */
306
392
  export default {
307
- ${Object.entries(e).map(([e,t])=>` ${R(e)}: ${J(t,` `)}`).join(`,
393
+ ${Object.entries(e).map(([e,t])=>` ${fe(e)}: ${J(t,` `)}`).join(`,
308
394
  `)}
309
395
  };
310
- `}function Z(e){if(P(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)=>se(e,r,n,t.fonts,t);if(I(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(z(a,t));if(I(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}F(n)&&(e[t.id]=i(t.id,n))}return e}if(F(e)){let n=o[0]&&o[0].id!=="default"?o[0].id:t.theme??`default`;return{[n]:i(n,e)}}return{}}const ce=e=>(t,n,r)=>o(g(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=x(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&&k(e.icons)&&Object.keys(e.icons).length>0,u=ce(n),d={[g(n,`blocks/ColorPalette.tsx`)]:u(`blocks/ColorPalette.tsx`,D(o,a),`tsx`),[g(n,`blocks/Typeset.tsx`)]:u(`blocks/Typeset.tsx`,ne(o,{...a,fonts:e.fonts}),`tsx`),[g(n,`blocks/TokenTable.tsx`)]:u(`blocks/TokenTable.tsx`,re(o),`tsx`),[g(n,`blocks/IconGallery.tsx`)]:u(`blocks/IconGallery.tsx`,A(t.skipIcons?{}:e.icons),`tsx`),[g(n,`blocks/index.ts`)]:u(`blocks/index.ts`,M(),`typescript`),[g(n,`Tokens.mdx`)]:u(`Tokens.mdx`,ie({titlePrefix:i,hasColors:s,hasTypography:c}),`mdx`)};s&&(d[g(n,`Colors.mdx`)]=u(`Colors.mdx`,ae(a),`mdx`)),c&&(d[g(n,`Typography.mdx`)]=u(`Typography.mdx`,oe(a),`mdx`)),l&&(d[g(n,`Icons.mdx`)]=u(`Icons.mdx`,j(a),`mdx`)),d[g(n,`tokens.json`)]=u(`tokens.json`,`${JSON.stringify(o,null,2)}\n`,`json`);let f;if(t.mapTheme){let i=Q(t.mapTheme(e.tokens),e,r,t.mapTheme);Object.keys(i).length>0&&(f=Object.keys(i),d[g(n,`theme.ts`)]=u(`theme.ts`,Z(i),`typescript`))}let p=`INSTALL.md`;return d[g(n,p)]=u(p,t.installGuide??w({outputPath:n,titlePrefix:i,themeFiles:f?[`theme.ts`]:void 0,themeNames:f}),`markdown`),d}var le=e(e=>({name:`storybook`,themeGeneration:`combined`,generate:async t=>$(t,e??{})}));export{q as applyBrandDefaults,le as default,x as flattenTokens,c as formatTokenValue,$ as generateTokenDocs,Q as normalizeThemes,w as renderInstallMd,Z as renderThemeFile,p as resolveTokenSets,m 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};
311
397
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@razorwind/storybook",
3
- "version": "0.0.60",
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": {
@@ -85,7 +85,7 @@
85
85
  "dependencies": {
86
86
  "@power-plant/core": "^0.0.92",
87
87
  "@power-plant/dtcg-schema": "^0.0.1",
88
- "@razorwind/core": "^0.0.63",
88
+ "@razorwind/core": "^0.0.64",
89
89
  "@stryke/path": "^0.29.41",
90
90
  "@stryke/type-checks": "^0.6.47"
91
91
  },
@@ -106,5 +106,5 @@
106
106
  "typescript": "^6.0.3"
107
107
  },
108
108
  "publishConfig": { "access": "public" },
109
- "gitHead": "574cc85598a992425f1b5fc361c5e48dc8aa4eb9"
109
+ "gitHead": "49873beaca1bec96f7d6869f9dcd8c20efd2be41"
110
110
  }