@razorwind/storybook 0.0.60 → 0.0.62

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,28 @@ 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, useMemo } 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
+
87
+ return useMemo(() => {
88
+ const candidate = theme ?? globals.theme;
89
+
90
+ return typeof candidate === "string" && candidate in variants
91
+ ? (candidate as keyof T & string)
92
+ : fallback;
93
+ }, [fallback, globals.theme, theme, variants]);
94
+ }
95
+ `}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
96
  `),i=n.find(e=>e.description)?.description??`${n.length} token${n.length===1?``:`s`}`;return`${t}<ColorItem
70
97
  title={${d(e)}}
71
98
  subtitle={${d(i)}}
@@ -73,46 +100,80 @@ Re-run Razorwind generate when tokens change to refresh docs under \`${e.outputP
73
100
  ${r}
74
101
  }}
75
102
  />`}).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>
103
+ `),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
104
  <h2>${e}</h2>
78
105
  <ColorPalette>
79
- ${i(t,` `)}
106
+ ${o(t,` `)}
80
107
  </ColorPalette>
81
108
  </section>`).join(`
109
+ `);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
110
  `);return`import { ColorPalette, ColorItem } from "@storybook/addon-docs/blocks";
111
+ ${a?`import { useThemeVariant } from "./ThemeVariant";
112
+ `:``}
83
113
 
84
114
  /**
85
115
  * Color tokens rendered with Storybook's ColorPalette doc block.
86
116
  *
87
117
  * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-colorpalette
88
118
  */
89
- export function ColorPaletteBlock() {
90
- return (
91
- ${c?` <>
92
- ${u}
93
- </>`:` <ColorPalette>
94
- ${l||` {/* No color tokens */}`}
95
- </ColorPalette>`}
96
- );
119
+ const COLOR_VARIANTS = {
120
+ ${c}
121
+ };
122
+
123
+ export interface ColorPaletteBlockProps {
124
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
125
+ theme?: string;
97
126
  }
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";
127
+
128
+ export function ColorPaletteBlock({ theme }: ColorPaletteBlockProps = {}) {
129
+ const activeTheme = ${a?`useThemeVariant(COLOR_VARIANTS, ${d(i)}, theme)`:d(i)};
130
+
131
+ return COLOR_VARIANTS[activeTheme];
132
+ }
133
+ `}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
134
+ fontFamily={${d(s)}}
135
+ fontSizes={${u}}
136
+ fontWeight={${d(l)}}
137
+ sampleText={${d(r)}}
138
+ />`},c=a.map(([e,t])=>` ${d(e)}: (${s(t)})`).join(`,
139
+ `);return`import { Typeset } from "@storybook/addon-docs/blocks";
140
+ ${i?`import { useThemeVariant } from "./ThemeVariant";
141
+ `:``}
99
142
 
100
143
  /**
101
144
  * Typography tokens rendered with Storybook's Typeset doc block.
102
145
  *
103
146
  * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-typeset
104
147
  */
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
- );
148
+ const TYPESET_VARIANTS = {
149
+ ${c}
150
+ };
151
+
152
+ export interface TypesetBlockProps {
153
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
154
+ theme?: string;
114
155
  }
115
- `}function _(e){return`import type { CSSProperties, ReactElement } from "react";
156
+
157
+ export function TypesetBlock({ theme }: TypesetBlockProps = {}) {
158
+ const activeTheme = ${i?`useThemeVariant(TYPESET_VARIANTS, ${d(o)}, theme)`:d(o)};
159
+
160
+ return TYPESET_VARIANTS[activeTheme];
161
+ }
162
+ `}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` {
163
+ path: ${d(e.path)},
164
+ type: ${e.type?d(e.type):`undefined`},
165
+ value: ${d(e.cssValue)},
166
+ cssVar: ${d(e.cssVar)},
167
+ description: ${e.description?d(e.description):`undefined`},
168
+ theme: ${t},
169
+ typography: ${h(e)}
170
+ }`}).join(`,
171
+ `),a=n.map(([e,t])=>` ${d(e)}: [
172
+ ${i(t)}
173
+ ]`).join(`,
174
+ `);return`import type { CSSProperties, ReactElement } from "react";
175
+ ${t?`import { useThemeVariant } from "./ThemeVariant";
176
+ `:``}
116
177
 
117
178
  export interface TokenTableRow {
118
179
  path: string;
@@ -121,19 +182,12 @@ export interface TokenTableRow {
121
182
  cssVar: string;
122
183
  description?: string;
123
184
  theme?: string;
185
+ typography: boolean;
124
186
  }
125
187
 
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
- ];
188
+ const TOKEN_VARIANTS: Record<string, TokenTableRow[]> = {
189
+ ${a}
190
+ };
137
191
 
138
192
  const tableStyle: CSSProperties = {
139
193
  width: "100%",
@@ -160,10 +214,14 @@ const swatchStyle = (value: string): CSSProperties => ({
160
214
  });
161
215
 
162
216
  export interface TokenTableBlockProps {
163
- /** Optional path prefix filter (e.g. \`color\`). */
164
- filter?: string;
217
+ /** Optional path prefix filter or filters (e.g. \`color\`). */
218
+ filter?: string | string[];
165
219
  /** Optional DTCG \`$type\` filter. */
166
220
  type?: string;
221
+ /** Restrict rows to tokens used to define typography. */
222
+ typography?: boolean;
223
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
224
+ theme?: string;
167
225
  }
168
226
 
169
227
  /**
@@ -171,15 +229,27 @@ export interface TokenTableBlockProps {
171
229
  */
172
230
  export function TokenTableBlock({
173
231
  filter,
174
- type
232
+ type,
233
+ typography,
234
+ theme
175
235
  }: TokenTableBlockProps = {}): ReactElement {
176
- const rows = TOKENS.filter(token => {
177
- if (filter && !token.path.startsWith(filter)) {
236
+ const activeTheme = ${t?`useThemeVariant(TOKEN_VARIANTS, ${d(r)}, theme)`:d(r)};
237
+ const rows = TOKEN_VARIANTS[activeTheme].filter(token => {
238
+ const filters = typeof filter === "string" ? [filter] : filter;
239
+ if (
240
+ filters &&
241
+ !filters.some(prefix =>
242
+ token.path === prefix || token.path.startsWith(\`\${prefix}.\`)
243
+ )
244
+ ) {
178
245
  return false;
179
246
  }
180
247
  if (type && token.type !== type) {
181
248
  return false;
182
249
  }
250
+ if (typography && !token.typography) {
251
+ return false;
252
+ }
183
253
  return true;
184
254
  });
185
255
 
@@ -216,7 +286,7 @@ export function TokenTableBlock({
216
286
  </table>
217
287
  );
218
288
  }
219
- `}function v(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
289
+ `}function k(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
220
290
  ## Colors
221
291
 
222
292
  <ColorPaletteBlock />
@@ -224,6 +294,17 @@ export function TokenTableBlock({
224
294
  ## Typography
225
295
 
226
296
  <TypesetBlock />
297
+ `:``,i=e.hasSizes?`
298
+ ## Size
299
+
300
+ <TokenTableBlock filter="size" />
301
+ `:``,a=e.hasSpaces?`
302
+ ## Space
303
+
304
+ <TokenTableBlock filter={[
305
+ "space",
306
+ "spacing"
307
+ ]} />
227
308
  `:``;return`import { Meta } from "@storybook/addon-docs/blocks";
228
309
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
229
310
  import { TokenTableBlock } from "./blocks/TokenTable";
@@ -234,11 +315,11 @@ import { TypesetBlock } from "./blocks/Typeset";
234
315
  # ${t}
235
316
 
236
317
  Design tokens generated by \`@razorwind/storybook\` for Storybook MDX docs.
237
- ${n}${r}
318
+ ${n}${r}${i}${a}
238
319
  ## All tokens
239
320
 
240
321
  <TokenTableBlock />
241
- `}function y(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
322
+ `}function A(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
242
323
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
243
324
 
244
325
  <Meta title="${u(e.titlePrefix??`Design Tokens`)}/Colors" />
@@ -246,15 +327,20 @@ import { ColorPaletteBlock } from "./blocks/ColorPalette";
246
327
  # Colors
247
328
 
248
329
  <ColorPaletteBlock />
249
- `}function b(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
330
+ `}function j(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
250
331
  import { TypesetBlock } from "./blocks/Typeset";
332
+ import { TokenTableBlock } from "./blocks/TokenTable";
251
333
 
252
334
  <Meta title="${u(e.titlePrefix??`Design Tokens`)}/Typography" />
253
335
 
254
336
  # Typography
255
337
 
256
338
  <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";
339
+
340
+ ## Typography tokens
341
+
342
+ <TokenTableBlock typography />
343
+ `}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
344
 
259
345
  /**
260
346
  * Icons rendered with Storybook's IconGallery doc block.
@@ -264,7 +350,7 @@ import { TypesetBlock } from "./blocks/Typeset";
264
350
  export function IconGalleryBlock() {
265
351
  return (
266
352
  <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
353
+ ${(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
354
  style={{ display: "inline-flex", width: 24, height: 24 }}
269
355
  dangerouslySetInnerHTML={{ __html: ${d(n.content)} }}
270
356
  />`:`<code>${u(t)}</code>`;return` <IconItem name={${d(t)}}>
@@ -274,7 +360,7 @@ ${(S(e)?Object.values(e).filter(S).toSorted((e,t)=>(x(e,`name`)??``).localeCompa
274
360
  </IconGallery>
275
361
  );
276
362
  }
277
- `}function w(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
363
+ `}function ne(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
278
364
  import { IconGalleryBlock } from "./blocks/IconGallery";
279
365
 
280
366
  <Meta title="${u(e.titlePrefix??`Design Tokens`)}/Icons" />
@@ -282,21 +368,24 @@ import { IconGalleryBlock } from "./blocks/IconGallery";
282
368
  # Icons
283
369
 
284
370
  <IconGalleryBlock />
285
- `}function T(){return`export { ColorPaletteBlock } from "./ColorPalette";
286
- export { IconGalleryBlock } from "./IconGallery";
371
+ `}function re(e=!0){return`export { ColorPaletteBlock } from "./ColorPalette";
372
+ export type { ColorPaletteBlockProps } from "./ColorPalette";
373
+ ${e?`export { IconGalleryBlock } from "./IconGallery";
374
+ `:``}
287
375
  export { TokenTableBlock } from "./TokenTable";
288
376
  export type { TokenTableBlockProps, TokenTableRow } from "./TokenTable";
289
377
  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";
378
+ export type { TypesetBlockProps } from "./Typeset";
379
+ `}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(`,
380
+ `)}\n${t}})`}function Y(e){return`import { create } from "storybook/theming";
292
381
 
293
382
  /**
294
383
  * Storybook UI theme generated by \`@razorwind/storybook\`.
295
384
  *
296
385
  * @see https://storybook.js.org/docs/configure/user-interface/theming
297
386
  */
298
- export default ${H(e)};
299
- `}function W(e){return`import { create } from "storybook/theming";
387
+ export default ${J(e)};
388
+ `}function X(e){return`import { create } from "storybook/theming";
300
389
 
301
390
  /**
302
391
  * Storybook UI themes generated by \`@razorwind/storybook\`.
@@ -304,7 +393,7 @@ export default ${H(e)};
304
393
  * @see https://storybook.js.org/docs/configure/user-interface/theming
305
394
  */
306
395
  export default {
307
- ${Object.entries(e).map(([e,t])=>` ${j(e)}: ${H(t,` `)}`).join(`,
396
+ ${Object.entries(e).map(([e,t])=>` ${z(e)}: ${J(t,` `)}`).join(`,
308
397
  `)}
309
398
  };
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}});
399
+ `}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;;;;;;;iBCi7Bc,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,109 @@ 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, useMemo } 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
+
87
+ return useMemo(() => {
88
+ const candidate = theme ?? globals.theme;
89
+
90
+ return typeof candidate === "string" && candidate in variants
91
+ ? (candidate as keyof T & string)
92
+ : fallback;
93
+ }, [fallback, globals.theme, theme, variants]);
94
+ }
95
+ `}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
96
  `),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)}}
97
+ title={${w(e)}}
98
+ subtitle={${w(i)}}
72
99
  colors={{
73
100
  ${r}
74
101
  }}
75
102
  />`}).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>
103
+ `),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
104
  <h2>${e}</h2>
78
105
  <ColorPalette>
79
- ${i(t,` `)}
106
+ ${o(t,` `)}
80
107
  </ColorPalette>
81
108
  </section>`).join(`
109
+ `);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
110
  `);return`import { ColorPalette, ColorItem } from "@storybook/addon-docs/blocks";
111
+ ${a?`import { useThemeVariant } from "./ThemeVariant";
112
+ `:``}
83
113
 
84
114
  /**
85
115
  * Color tokens rendered with Storybook's ColorPalette doc block.
86
116
  *
87
117
  * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-colorpalette
88
118
  */
89
- export function ColorPaletteBlock() {
90
- return (
91
- ${c?` <>
92
- ${u}
93
- </>`:` <ColorPalette>
94
- ${l||` {/* No color tokens */}`}
95
- </ColorPalette>`}
96
- );
119
+ const COLOR_VARIANTS = {
120
+ ${c}
121
+ };
122
+
123
+ export interface ColorPaletteBlockProps {
124
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
125
+ theme?: string;
97
126
  }
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";
127
+
128
+ export function ColorPaletteBlock({ theme }: ColorPaletteBlockProps = {}) {
129
+ const activeTheme = ${a?`useThemeVariant(COLOR_VARIANTS, ${w(i)}, theme)`:w(i)};
130
+
131
+ return COLOR_VARIANTS[activeTheme];
132
+ }
133
+ `}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
134
+ fontFamily={${w(l)}}
135
+ fontSizes={${f}}
136
+ fontWeight={${w(d)}}
137
+ sampleText={${w(a)}}
138
+ />`},u=s.map(([e,t])=>` ${w(e)}: (${l(t)})`).join(`,
139
+ `);return`import { Typeset } from "@storybook/addon-docs/blocks";
140
+ ${o?`import { useThemeVariant } from "./ThemeVariant";
141
+ `:``}
99
142
 
100
143
  /**
101
144
  * Typography tokens rendered with Storybook's Typeset doc block.
102
145
  *
103
146
  * @see https://storybook.js.org/docs/api/doc-blocks/doc-block-typeset
104
147
  */
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
- );
148
+ const TYPESET_VARIANTS = {
149
+ ${u}
150
+ };
151
+
152
+ export interface TypesetBlockProps {
153
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
154
+ theme?: string;
114
155
  }
115
- `}function re(e){return`import type { CSSProperties, ReactElement } from "react";
156
+
157
+ export function TypesetBlock({ theme }: TypesetBlockProps = {}) {
158
+ const activeTheme = ${o?`useThemeVariant(TYPESET_VARIANTS, ${w(c)}, theme)`:w(c)};
159
+
160
+ return TYPESET_VARIANTS[activeTheme];
161
+ }
162
+ `}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` {
163
+ path: ${w(e.path)},
164
+ type: ${e.type?w(e.type):`undefined`},
165
+ value: ${w(e.cssValue)},
166
+ cssVar: ${w(e.cssVar)},
167
+ description: ${e.description?w(e.description):`undefined`},
168
+ theme: ${t},
169
+ typography: ${D(e)}
170
+ }`}).join(`,
171
+ `),a=n.map(([e,t])=>` ${w(e)}: [
172
+ ${i(t)}
173
+ ]`).join(`,
174
+ `);return`import type { CSSProperties, ReactElement } from "react";
175
+ ${t?`import { useThemeVariant } from "./ThemeVariant";
176
+ `:``}
116
177
 
117
178
  export interface TokenTableRow {
118
179
  path: string;
@@ -121,19 +182,12 @@ export interface TokenTableRow {
121
182
  cssVar: string;
122
183
  description?: string;
123
184
  theme?: string;
185
+ typography: boolean;
124
186
  }
125
187
 
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
- ];
188
+ const TOKEN_VARIANTS: Record<string, TokenTableRow[]> = {
189
+ ${a}
190
+ };
137
191
 
138
192
  const tableStyle: CSSProperties = {
139
193
  width: "100%",
@@ -160,10 +214,14 @@ const swatchStyle = (value: string): CSSProperties => ({
160
214
  });
161
215
 
162
216
  export interface TokenTableBlockProps {
163
- /** Optional path prefix filter (e.g. \`color\`). */
164
- filter?: string;
217
+ /** Optional path prefix filter or filters (e.g. \`color\`). */
218
+ filter?: string | string[];
165
219
  /** Optional DTCG \`$type\` filter. */
166
220
  type?: string;
221
+ /** Restrict rows to tokens used to define typography. */
222
+ typography?: boolean;
223
+ /** Generated token-set name. Defaults to Storybook's \`theme\` global. */
224
+ theme?: string;
167
225
  }
168
226
 
169
227
  /**
@@ -171,15 +229,27 @@ export interface TokenTableBlockProps {
171
229
  */
172
230
  export function TokenTableBlock({
173
231
  filter,
174
- type
232
+ type,
233
+ typography,
234
+ theme
175
235
  }: TokenTableBlockProps = {}): ReactElement {
176
- const rows = TOKENS.filter(token => {
177
- if (filter && !token.path.startsWith(filter)) {
236
+ const activeTheme = ${t?`useThemeVariant(TOKEN_VARIANTS, ${w(r)}, theme)`:w(r)};
237
+ const rows = TOKEN_VARIANTS[activeTheme].filter(token => {
238
+ const filters = typeof filter === "string" ? [filter] : filter;
239
+ if (
240
+ filters &&
241
+ !filters.some(prefix =>
242
+ token.path === prefix || token.path.startsWith(\`\${prefix}.\`)
243
+ )
244
+ ) {
178
245
  return false;
179
246
  }
180
247
  if (type && token.type !== type) {
181
248
  return false;
182
249
  }
250
+ if (typography && !token.typography) {
251
+ return false;
252
+ }
183
253
  return true;
184
254
  });
185
255
 
@@ -216,7 +286,7 @@ export function TokenTableBlock({
216
286
  </table>
217
287
  );
218
288
  }
219
- `}function ie(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
289
+ `}function P(e){let t=e.titlePrefix??`Design Tokens`,n=e.hasColors?`
220
290
  ## Colors
221
291
 
222
292
  <ColorPaletteBlock />
@@ -224,37 +294,53 @@ export function TokenTableBlock({
224
294
  ## Typography
225
295
 
226
296
  <TypesetBlock />
297
+ `:``,i=e.hasSizes?`
298
+ ## Size
299
+
300
+ <TokenTableBlock filter="size" />
301
+ `:``,a=e.hasSpaces?`
302
+ ## Space
303
+
304
+ <TokenTableBlock filter={[
305
+ "space",
306
+ "spacing"
307
+ ]} />
227
308
  `:``;return`import { Meta } from "@storybook/addon-docs/blocks";
228
309
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
229
310
  import { TokenTableBlock } from "./blocks/TokenTable";
230
311
  import { TypesetBlock } from "./blocks/Typeset";
231
312
 
232
- <Meta title="${S(t)}/Overview" />
313
+ <Meta title="${C(t)}/Overview" />
233
314
 
234
315
  # ${t}
235
316
 
236
317
  Design tokens generated by \`@razorwind/storybook\` for Storybook MDX docs.
237
- ${n}${r}
318
+ ${n}${r}${i}${a}
238
319
  ## All tokens
239
320
 
240
321
  <TokenTableBlock />
241
- `}function ae(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
322
+ `}function F(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
242
323
  import { ColorPaletteBlock } from "./blocks/ColorPalette";
243
324
 
244
- <Meta title="${S(e.titlePrefix??`Design Tokens`)}/Colors" />
325
+ <Meta title="${C(e.titlePrefix??`Design Tokens`)}/Colors" />
245
326
 
246
327
  # Colors
247
328
 
248
329
  <ColorPaletteBlock />
249
- `}function oe(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
330
+ `}function I(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
250
331
  import { TypesetBlock } from "./blocks/Typeset";
332
+ import { TokenTableBlock } from "./blocks/TokenTable";
251
333
 
252
- <Meta title="${S(e.titlePrefix??`Design Tokens`)}/Typography" />
334
+ <Meta title="${C(e.titlePrefix??`Design Tokens`)}/Typography" />
253
335
 
254
336
  # Typography
255
337
 
256
338
  <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";
339
+
340
+ ## Typography tokens
341
+
342
+ <TokenTableBlock typography />
343
+ `}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
344
 
259
345
  /**
260
346
  * Icons rendered with Storybook's IconGallery doc block.
@@ -264,30 +350,33 @@ import { TypesetBlock } from "./blocks/Typeset";
264
350
  export function IconGalleryBlock() {
265
351
  return (
266
352
  <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
353
+ ${(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
354
  style={{ display: "inline-flex", width: 24, height: 24 }}
269
- dangerouslySetInnerHTML={{ __html: ${C(n.content)} }}
270
- />`:`<code>${S(t)}</code>`;return` <IconItem name={${C(t)}}>
355
+ dangerouslySetInnerHTML={{ __html: ${w(n.content)} }}
356
+ />`:`<code>${C(t)}</code>`;return` <IconItem name={${w(t)}}>
271
357
  ${r}
272
358
  </IconItem>`}).join(`
273
359
  `)||` {/* No icons */}`}
274
360
  </IconGallery>
275
361
  );
276
362
  }
277
- `}function j(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
363
+ `}function B(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
278
364
  import { IconGalleryBlock } from "./blocks/IconGallery";
279
365
 
280
- <Meta title="${S(e.titlePrefix??`Design Tokens`)}/Icons" />
366
+ <Meta title="${C(e.titlePrefix??`Design Tokens`)}/Icons" />
281
367
 
282
368
  # Icons
283
369
 
284
370
  <IconGalleryBlock />
285
- `}function M(){return`export { ColorPaletteBlock } from "./ColorPalette";
286
- export { IconGalleryBlock } from "./IconGallery";
371
+ `}function V(e=!0){return`export { ColorPaletteBlock } from "./ColorPalette";
372
+ export type { ColorPaletteBlockProps } from "./ColorPalette";
373
+ ${e?`export { IconGalleryBlock } from "./IconGallery";
374
+ `:``}
287
375
  export { TokenTableBlock } from "./TokenTable";
288
376
  export type { TokenTableBlockProps, TokenTableRow } from "./TokenTable";
289
377
  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(`,
378
+ export type { TypesetBlockProps } from "./Typeset";
379
+ `}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
380
  `)}\n${t}})`}function Y(e){return`import { create } from "storybook/theming";
292
381
 
293
382
  /**
@@ -304,8 +393,8 @@ export default ${J(e)};
304
393
  * @see https://storybook.js.org/docs/configure/user-interface/theming
305
394
  */
306
395
  export default {
307
- ${Object.entries(e).map(([e,t])=>` ${R(e)}: ${J(t,` `)}`).join(`,
396
+ ${Object.entries(e).map(([e,t])=>` ${fe(e)}: ${J(t,` `)}`).join(`,
308
397
  `)}
309
398
  };
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};
399
+ `}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
400
  //# 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.62",
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": "c84f0264563cf2de9e59fef95d25924ebebe6f80"
110
110
  }