@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 +142 -56
- package/dist/index.d.cts +1 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +147 -61
- package/package.json +3 -3
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=
|
|
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
|
-
${
|
|
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
|
-
`}
|
|
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
|
-
`),
|
|
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
|
-
${
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
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
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
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
|
|
127
|
-
${
|
|
128
|
-
|
|
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
|
|
177
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
${(
|
|
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
|
|
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
|
|
286
|
-
export {
|
|
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
|
-
|
|
291
|
-
`)}
|
|
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 ${
|
|
299
|
-
`}function
|
|
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])=>` ${
|
|
393
|
+
${Object.entries(e).map(([e,t])=>` ${z(e)}: ${J(t,` `)}`).join(`,
|
|
308
394
|
`)}
|
|
309
395
|
};
|
|
310
|
-
`}function
|
|
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
package/dist/index.d.cts.map
CHANGED
|
@@ -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;;;;;;;
|
|
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
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
|
|
2
|
-
`,`\\n`).replaceAll(`\r`,`\\r`)}function
|
|
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
|
-
${
|
|
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
|
-
`}
|
|
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={${
|
|
71
|
-
subtitle={${
|
|
94
|
+
title={${w(e)}}
|
|
95
|
+
subtitle={${w(i)}}
|
|
72
96
|
colors={{
|
|
73
97
|
${r}
|
|
74
98
|
}}
|
|
75
99
|
/>`}).join(`
|
|
76
|
-
`),
|
|
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
|
-
${
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
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
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
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
|
|
127
|
-
${
|
|
128
|
-
|
|
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
|
|
177
|
-
|
|
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
|
|
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="${
|
|
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
|
|
319
|
+
`}function F(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
|
|
242
320
|
import { ColorPaletteBlock } from "./blocks/ColorPalette";
|
|
243
321
|
|
|
244
|
-
<Meta title="${
|
|
322
|
+
<Meta title="${C(e.titlePrefix??`Design Tokens`)}/Colors" />
|
|
245
323
|
|
|
246
324
|
# Colors
|
|
247
325
|
|
|
248
326
|
<ColorPaletteBlock />
|
|
249
|
-
`}function
|
|
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="${
|
|
331
|
+
<Meta title="${C(e.titlePrefix??`Design Tokens`)}/Typography" />
|
|
253
332
|
|
|
254
333
|
# Typography
|
|
255
334
|
|
|
256
335
|
<TypesetBlock />
|
|
257
|
-
|
|
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
|
-
${(
|
|
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: ${
|
|
270
|
-
/>`:`<code>${
|
|
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
|
|
360
|
+
`}function B(e={}){return`import { Meta } from "@storybook/addon-docs/blocks";
|
|
278
361
|
import { IconGalleryBlock } from "./blocks/IconGallery";
|
|
279
362
|
|
|
280
|
-
<Meta title="${
|
|
363
|
+
<Meta title="${C(e.titlePrefix??`Design Tokens`)}/Icons" />
|
|
281
364
|
|
|
282
365
|
# Icons
|
|
283
366
|
|
|
284
367
|
<IconGalleryBlock />
|
|
285
|
-
`}function
|
|
286
|
-
export {
|
|
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
|
-
|
|
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])=>` ${
|
|
393
|
+
${Object.entries(e).map(([e,t])=>` ${fe(e)}: ${J(t,` `)}`).join(`,
|
|
308
394
|
`)}
|
|
309
395
|
};
|
|
310
|
-
`}function Z(e){if(
|
|
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.
|
|
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.
|
|
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": "
|
|
109
|
+
"gitHead": "49873beaca1bec96f7d6869f9dcd8c20efd2be41"
|
|
110
110
|
}
|