@jfrader/storybook-docs 0.0.0-stage → 0.4.3
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/LICENSE +21 -0
- package/README.md +138 -2
- package/dist/app.d.ts +1 -0
- package/dist/base.d.ts +3 -0
- package/dist/build/catalog.d.ts +20 -0
- package/dist/build/code.d.ts +2 -0
- package/dist/build/global-styles.d.ts +1 -0
- package/dist/build/guidance.d.ts +4 -0
- package/dist/build/module-ids.d.ts +2 -0
- package/dist/build/props.d.ts +10 -0
- package/dist/build/releases.d.ts +7 -0
- package/dist/build/site.d.ts +2 -0
- package/dist/build/storybook-test.d.ts +2 -0
- package/dist/build/tokens.d.ts +2 -0
- package/dist/code.d.ts +16 -0
- package/dist/component-demo.d.ts +23 -0
- package/dist/config.d.ts +98 -0
- package/dist/controls.d.ts +49 -0
- package/dist/guidance-model.d.ts +74 -0
- package/dist/guidance.d.ts +9 -0
- package/dist/index.css +424 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1930 -0
- package/dist/pages/component-page.d.ts +4 -0
- package/dist/pages/foundations-color.d.ts +3 -0
- package/dist/pages/foundations-effects.d.ts +3 -0
- package/dist/pages/foundations-spacing.d.ts +3 -0
- package/dist/pages/foundations-type.d.ts +3 -0
- package/dist/pages/overview.d.ts +3 -0
- package/dist/pages/releases.d.ts +3 -0
- package/dist/prop-docs.d.ts +20 -0
- package/dist/props.d.ts +4 -0
- package/dist/scan.d.ts +19 -0
- package/dist/search-match.d.ts +21 -0
- package/dist/search.d.ts +5 -0
- package/dist/sections.d.ts +52 -0
- package/dist/skeleton.d.ts +11 -0
- package/dist/start.d.ts +4 -0
- package/dist/story-view.d.ts +20 -0
- package/dist/styles.css +688 -0
- package/dist/toc.d.ts +10 -0
- package/dist/virtual.d.ts +42 -0
- package/dist/vite-plugin.d.ts +10 -0
- package/dist/vite-plugin.js +697 -0
- package/docs/CONFIG.md +287 -0
- package/docs/RELEASING.md +127 -0
- package/package.json +83 -4
package/dist/index.js
ADDED
|
@@ -0,0 +1,1930 @@
|
|
|
1
|
+
// src/start.tsx
|
|
2
|
+
import "virtual:storybook-docs/global-styles";
|
|
3
|
+
import { StrictMode, createElement as createElement3 } from "react";
|
|
4
|
+
import { createRoot } from "react-dom/client";
|
|
5
|
+
import { site as site3, themeCss, theme as theme2 } from "virtual:storybook-docs/site";
|
|
6
|
+
|
|
7
|
+
// src/app.tsx
|
|
8
|
+
import { useEffect as useEffect7, useRef as useRef5, useState as useState8 } from "react";
|
|
9
|
+
import { catalog as catalog3, groups as groups2, stats as stats2 } from "virtual:storybook-docs/catalog";
|
|
10
|
+
import { pages, site as site2, theme } from "virtual:storybook-docs/site";
|
|
11
|
+
|
|
12
|
+
// src/pages/component-page.tsx
|
|
13
|
+
import { useMemo as useMemo3 } from "react";
|
|
14
|
+
import { storySource as storySource2 } from "virtual:storybook-docs/catalog";
|
|
15
|
+
|
|
16
|
+
// src/guidance.tsx
|
|
17
|
+
import { createElement, useEffect, useMemo as useMemo2, useState } from "react";
|
|
18
|
+
import { loadGuidance } from "virtual:storybook-docs/guidance";
|
|
19
|
+
|
|
20
|
+
// src/code.tsx
|
|
21
|
+
import { Component, Suspense, useMemo } from "react";
|
|
22
|
+
import { Code as ProvidedCode, provided as hasProvidedCode } from "virtual:storybook-docs/code";
|
|
23
|
+
import { jsx } from "react/jsx-runtime";
|
|
24
|
+
var CodeBoundary = class extends Component {
|
|
25
|
+
state = { failed: false };
|
|
26
|
+
static getDerivedStateFromError() {
|
|
27
|
+
return { failed: true };
|
|
28
|
+
}
|
|
29
|
+
render() {
|
|
30
|
+
if (this.state.failed) return /* @__PURE__ */ jsx(PlainCode, { code: this.props.code, language: this.props.language, label: this.props.label });
|
|
31
|
+
return this.props.children;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
function PlainCode({ code, language, label }) {
|
|
35
|
+
return /* @__PURE__ */ jsx("pre", { className: "code", "data-lang": language || void 0, "aria-label": label, children: code });
|
|
36
|
+
}
|
|
37
|
+
function CodeBlock({ code, language, label }) {
|
|
38
|
+
const Provided = ProvidedCode;
|
|
39
|
+
const trimmed = useMemo(() => code.trim(), [code]);
|
|
40
|
+
if (!hasProvidedCode || !Provided) return /* @__PURE__ */ jsx(PlainCode, { code: trimmed, language, label });
|
|
41
|
+
return /* @__PURE__ */ jsx(CodeBoundary, { code: trimmed, language, label, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(PlainCode, { code: trimmed, language, label }), children: /* @__PURE__ */ jsx(Provided, { code: trimmed, language, label }) }) });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/guidance-model.ts
|
|
45
|
+
import { marked } from "marked";
|
|
46
|
+
var DO_SYMBOLS = ["\u2705", "\u2713", "\u2714"];
|
|
47
|
+
var SYMBOL = /^(✅|✓|✔|⛔|✗|✘|❌|🚫)\uFE0F?\s*/u;
|
|
48
|
+
var WORD = /^(\*\*|__|\*|_)?(don['’]t|do not|do)\1(?![\p{L}\p{N}'’])/iu;
|
|
49
|
+
var SEPARATOR = /^[ \t]*(?:[—–:]|-(?=\s))[ \t]*/u;
|
|
50
|
+
var LINE_END = /^[ \t]*(?:\n|$)/;
|
|
51
|
+
var MIN_HEADING_DEPTH = 2;
|
|
52
|
+
var SAFE_SCHEMES = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]);
|
|
53
|
+
var SCHEME = /^([a-z][a-z\d+.-]*:)/i;
|
|
54
|
+
var EXTERNAL = /^(?:https?:)?\/\//i;
|
|
55
|
+
function readCallout(text) {
|
|
56
|
+
let rest = text.trimStart();
|
|
57
|
+
let tone = "note";
|
|
58
|
+
const symbol = SYMBOL.exec(rest);
|
|
59
|
+
if (symbol?.[1]) {
|
|
60
|
+
tone = DO_SYMBOLS.includes(symbol[1]) ? "do" : "dont";
|
|
61
|
+
rest = rest.slice(symbol[0].length);
|
|
62
|
+
}
|
|
63
|
+
const word = WORD.exec(rest);
|
|
64
|
+
if (word?.[2]) {
|
|
65
|
+
const wordTone = word[2].toLowerCase() === "do" ? "do" : "dont";
|
|
66
|
+
const after = rest.slice(word[0].length);
|
|
67
|
+
const delimited = Boolean(word[1]) || SEPARATOR.test(after) || LINE_END.test(after);
|
|
68
|
+
if (symbol ? tone === wordTone : delimited) {
|
|
69
|
+
tone = wordTone;
|
|
70
|
+
rest = after;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (tone === "note") return { tone, body: text };
|
|
74
|
+
return { tone, body: rest.replace(SEPARATOR, "").trimStart() };
|
|
75
|
+
}
|
|
76
|
+
function safeHref(href) {
|
|
77
|
+
const scheme = SCHEME.exec(href)?.[1]?.toLowerCase();
|
|
78
|
+
return scheme && !SAFE_SCHEMES.has(scheme) ? null : href;
|
|
79
|
+
}
|
|
80
|
+
function toInline(tokens = []) {
|
|
81
|
+
return tokens.flatMap((token4) => {
|
|
82
|
+
switch (token4.type) {
|
|
83
|
+
case "text":
|
|
84
|
+
return token4.tokens ? toInline(token4.tokens) : [{ kind: "text", text: token4.text }];
|
|
85
|
+
case "escape":
|
|
86
|
+
return [{ kind: "text", text: token4.text }];
|
|
87
|
+
case "strong":
|
|
88
|
+
case "em":
|
|
89
|
+
case "del":
|
|
90
|
+
return [{ kind: token4.type, children: toInline(token4.tokens) }];
|
|
91
|
+
case "codespan":
|
|
92
|
+
return [{ kind: "code", text: token4.text }];
|
|
93
|
+
case "br":
|
|
94
|
+
return [{ kind: "br" }];
|
|
95
|
+
case "link": {
|
|
96
|
+
const href = safeHref(token4.href);
|
|
97
|
+
const children = toInline(token4.tokens);
|
|
98
|
+
return href ? [{ kind: "link", href, external: EXTERNAL.test(href), children }] : children;
|
|
99
|
+
}
|
|
100
|
+
case "image": {
|
|
101
|
+
const src = safeHref(token4.href);
|
|
102
|
+
return src ? [{ kind: "image", src, alt: token4.text }] : [];
|
|
103
|
+
}
|
|
104
|
+
default:
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function toCell(cell) {
|
|
110
|
+
return toInline(cell.tokens);
|
|
111
|
+
}
|
|
112
|
+
function toBlocks(tokens) {
|
|
113
|
+
return tokens.flatMap((token4) => {
|
|
114
|
+
switch (token4.type) {
|
|
115
|
+
case "heading":
|
|
116
|
+
return [{ kind: "heading", depth: Math.max(MIN_HEADING_DEPTH, token4.depth), children: toInline(token4.tokens) }];
|
|
117
|
+
case "paragraph":
|
|
118
|
+
return [{ kind: "paragraph", children: toInline(token4.tokens) }];
|
|
119
|
+
case "text":
|
|
120
|
+
return [{ kind: "text", children: toInline([token4]) }];
|
|
121
|
+
case "list":
|
|
122
|
+
return [
|
|
123
|
+
{
|
|
124
|
+
kind: "list",
|
|
125
|
+
ordered: token4.ordered,
|
|
126
|
+
start: token4.start === "" ? 1 : token4.start,
|
|
127
|
+
items: token4.items.map((item) => toBlocks(item.tokens))
|
|
128
|
+
}
|
|
129
|
+
];
|
|
130
|
+
case "code":
|
|
131
|
+
return [{ kind: "code", lang: token4.lang ?? "", text: token4.text }];
|
|
132
|
+
case "table":
|
|
133
|
+
return [{ kind: "table", align: token4.align, header: token4.header.map(toCell), rows: token4.rows.map((row) => row.map(toCell)) }];
|
|
134
|
+
case "blockquote": {
|
|
135
|
+
const { tone, body } = readCallout(token4.text);
|
|
136
|
+
const children = tone === "note" ? toBlocks(token4.tokens) : toBlocks(marked.lexer(body));
|
|
137
|
+
return [{ kind: "callout", tone, children }];
|
|
138
|
+
}
|
|
139
|
+
case "hr":
|
|
140
|
+
return [{ kind: "rule" }];
|
|
141
|
+
default:
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function parseGuidance(markdown) {
|
|
147
|
+
return toBlocks(marked.lexer(markdown));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/skeleton.tsx
|
|
151
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
152
|
+
function Skeleton({
|
|
153
|
+
width = "100%",
|
|
154
|
+
height = 12,
|
|
155
|
+
lines = 1
|
|
156
|
+
}) {
|
|
157
|
+
if (lines > 1) {
|
|
158
|
+
return /* @__PURE__ */ jsx2("span", { className: "skeleton-stack", "aria-hidden": "true", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx2(
|
|
159
|
+
"span",
|
|
160
|
+
{
|
|
161
|
+
className: "skeleton",
|
|
162
|
+
style: { width: index === lines - 1 ? "62%" : width, height }
|
|
163
|
+
},
|
|
164
|
+
index
|
|
165
|
+
)) });
|
|
166
|
+
}
|
|
167
|
+
return /* @__PURE__ */ jsx2("span", { className: "skeleton", "aria-hidden": "true", style: { width, height } });
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/guidance.tsx
|
|
171
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
172
|
+
var CALLOUT_LABELS = { do: "Do", dont: "Don't", note: null };
|
|
173
|
+
function renderInline(nodes) {
|
|
174
|
+
return nodes.map((node, index) => {
|
|
175
|
+
switch (node.kind) {
|
|
176
|
+
case "text":
|
|
177
|
+
return node.text;
|
|
178
|
+
case "strong":
|
|
179
|
+
case "em":
|
|
180
|
+
case "del":
|
|
181
|
+
return createElement(node.kind, { key: index }, renderInline(node.children));
|
|
182
|
+
case "code":
|
|
183
|
+
return /* @__PURE__ */ jsx3("code", { children: node.text }, index);
|
|
184
|
+
case "br":
|
|
185
|
+
return /* @__PURE__ */ jsx3("br", {}, index);
|
|
186
|
+
case "image":
|
|
187
|
+
return /* @__PURE__ */ jsx3("img", { src: node.src, alt: node.alt }, index);
|
|
188
|
+
case "link":
|
|
189
|
+
return node.external ? /* @__PURE__ */ jsx3("a", { href: node.href, target: "_blank", rel: "noreferrer noopener", children: renderInline(node.children) }, index) : /* @__PURE__ */ jsx3("a", { href: node.href, children: renderInline(node.children) }, index);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
function renderBlocks(blocks) {
|
|
194
|
+
return blocks.map((block, index) => {
|
|
195
|
+
switch (block.kind) {
|
|
196
|
+
case "heading":
|
|
197
|
+
return createElement(`h${Math.min(block.depth, 6)}`, { key: index }, renderInline(block.children));
|
|
198
|
+
case "paragraph":
|
|
199
|
+
return /* @__PURE__ */ jsx3("p", { children: renderInline(block.children) }, index);
|
|
200
|
+
case "text":
|
|
201
|
+
return /* @__PURE__ */ jsx3("span", { children: renderInline(block.children) }, index);
|
|
202
|
+
case "list": {
|
|
203
|
+
const items = block.items.map((item, itemIndex) => /* @__PURE__ */ jsx3("li", { children: renderBlocks(item) }, itemIndex));
|
|
204
|
+
return block.ordered ? /* @__PURE__ */ jsx3("ol", { start: block.start, children: items }, index) : /* @__PURE__ */ jsx3("ul", { children: items }, index);
|
|
205
|
+
}
|
|
206
|
+
case "code":
|
|
207
|
+
return /* @__PURE__ */ jsx3(CodeBlock, { code: block.text, language: block.lang || void 0 }, index);
|
|
208
|
+
case "table":
|
|
209
|
+
return /* @__PURE__ */ jsx3("div", { className: "guidance-table", children: /* @__PURE__ */ jsxs("table", { children: [
|
|
210
|
+
/* @__PURE__ */ jsx3("thead", { children: /* @__PURE__ */ jsx3("tr", { children: block.header.map((cell, cellIndex) => /* @__PURE__ */ jsx3("th", { style: { textAlign: block.align[cellIndex] ?? void 0 }, children: renderInline(cell) }, cellIndex)) }) }),
|
|
211
|
+
/* @__PURE__ */ jsx3("tbody", { children: block.rows.map((row, rowIndex) => /* @__PURE__ */ jsx3("tr", { children: row.map((cell, cellIndex) => /* @__PURE__ */ jsx3("td", { style: { textAlign: block.align[cellIndex] ?? void 0 }, children: renderInline(cell) }, cellIndex)) }, rowIndex)) })
|
|
212
|
+
] }) }, index);
|
|
213
|
+
case "callout": {
|
|
214
|
+
const label = CALLOUT_LABELS[block.tone];
|
|
215
|
+
return /* @__PURE__ */ jsxs("aside", { className: `guidance-callout guidance-callout-${block.tone}`, children: [
|
|
216
|
+
label ? /* @__PURE__ */ jsx3("p", { className: "guidance-callout-label", children: label }) : null,
|
|
217
|
+
renderBlocks(block.children)
|
|
218
|
+
] }, index);
|
|
219
|
+
}
|
|
220
|
+
case "rule":
|
|
221
|
+
return /* @__PURE__ */ jsx3("hr", {}, index);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
function MarkdownView({ markdown, className = "guidance" }) {
|
|
226
|
+
const blocks = useMemo2(() => parseGuidance(markdown), [markdown]);
|
|
227
|
+
return /* @__PURE__ */ jsx3("section", { className, children: renderBlocks(blocks) });
|
|
228
|
+
}
|
|
229
|
+
function Guidance({ slug }) {
|
|
230
|
+
const [blocks, setBlocks] = useState(null);
|
|
231
|
+
const [missing, setMissing] = useState(false);
|
|
232
|
+
useEffect(() => {
|
|
233
|
+
let alive = true;
|
|
234
|
+
setBlocks(null);
|
|
235
|
+
setMissing(false);
|
|
236
|
+
loadGuidance(slug).then((module) => {
|
|
237
|
+
if (!alive) return;
|
|
238
|
+
const markdown = module.markdown;
|
|
239
|
+
if (!markdown) {
|
|
240
|
+
setMissing(true);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
setBlocks(parseGuidance(markdown));
|
|
244
|
+
}).catch(() => {
|
|
245
|
+
if (alive) setMissing(true);
|
|
246
|
+
});
|
|
247
|
+
return () => {
|
|
248
|
+
alive = false;
|
|
249
|
+
};
|
|
250
|
+
}, [slug]);
|
|
251
|
+
if (missing) return null;
|
|
252
|
+
if (blocks === null) return /* @__PURE__ */ jsx3("section", { className: "guidance", "aria-busy": "true", children: /* @__PURE__ */ jsx3(Skeleton, { lines: 3 }) });
|
|
253
|
+
return /* @__PURE__ */ jsx3("section", { className: "guidance", children: renderBlocks(blocks) });
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// src/controls.tsx
|
|
257
|
+
import { useState as useState5 } from "react";
|
|
258
|
+
|
|
259
|
+
// src/component-demo.tsx
|
|
260
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useId, useRef as useRef3, useState as useState4 } from "react";
|
|
261
|
+
|
|
262
|
+
// src/story-view.tsx
|
|
263
|
+
import { Component as Component2, createElement as createElement2, useEffect as useEffect2, useRef, useState as useState2 } from "react";
|
|
264
|
+
|
|
265
|
+
// src/sections.ts
|
|
266
|
+
function mergeAnnotations(...values) {
|
|
267
|
+
const merged = {};
|
|
268
|
+
const isRecord = (value) => value !== null && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype;
|
|
269
|
+
for (const value of values) {
|
|
270
|
+
for (const [key, next] of Object.entries(value ?? {})) {
|
|
271
|
+
if (next === void 0) continue;
|
|
272
|
+
const previous = merged[key];
|
|
273
|
+
merged[key] = isRecord(previous) && isRecord(next) ? mergeAnnotations(previous, next) : next;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return merged;
|
|
277
|
+
}
|
|
278
|
+
var SECTIONS = [
|
|
279
|
+
{
|
|
280
|
+
title: "Environments",
|
|
281
|
+
match: /rtl|ltr|dir|theme|forced|reduced|motion|dark|light|contrast|a11y|aria|screen|zoom|locale|intl/i
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
title: "Variants & sizes",
|
|
285
|
+
match: /variant|tone|size|appearance|density|style|colour|color|emphasis|shape|level|orientation|align|position|placement/i
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
title: "States",
|
|
289
|
+
match: /loading|disabled|error|invalid|required|readonly|pending|selected|checked|open|closed|active|focus|hover|pressed|busy|empty|filled|failed|success|indeterminate/i
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
title: "Interaction & keyboard",
|
|
293
|
+
match: /keyboard|pointer|drag|click|typeahead|escape|tab|enter|space|arrow|scroll|wheel|swipe|gesture|hold|capture|press|navigate|activat/i
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
title: "Content & layout",
|
|
297
|
+
match: /long|short|narrow|wide|wrap|overflow|label|children|content|text|icon|image|avatar|number|value|truncat|clamp|stack/i
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
title: "Edge cases",
|
|
301
|
+
match: /error|reject|cancel|unmount|reset|guard|edge|stress|zero|invalid|falsy|boolean|external|controlled|uncontrolled|ref|slot|sx|default|initial|missing|duplicate|unknown|null/i
|
|
302
|
+
}
|
|
303
|
+
];
|
|
304
|
+
function sectionStories(stories) {
|
|
305
|
+
const overview = stories.filter((story) => /^default$/i.test(story));
|
|
306
|
+
const rest = stories.filter((story) => !/^default$/i.test(story));
|
|
307
|
+
const buckets = SECTIONS.map((section) => ({ ...section, stories: [] }));
|
|
308
|
+
const more = [];
|
|
309
|
+
for (const story of rest) {
|
|
310
|
+
const bucket = buckets.find((candidate) => candidate.match.test(story));
|
|
311
|
+
(bucket ? bucket.stories : more).push(story);
|
|
312
|
+
}
|
|
313
|
+
const sections = [];
|
|
314
|
+
if (overview.length > 0) {
|
|
315
|
+
sections.push({ title: "Overview", stories: overview });
|
|
316
|
+
}
|
|
317
|
+
for (const bucket of buckets) {
|
|
318
|
+
if (bucket.stories.length > 0) {
|
|
319
|
+
sections.push({ title: bucket.title, stories: bucket.stories });
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (more.length > 0) {
|
|
323
|
+
sections.push({ title: "More stories", stories: more });
|
|
324
|
+
}
|
|
325
|
+
return sections;
|
|
326
|
+
}
|
|
327
|
+
var DEBUG_STORY = /\b(?:loading|disabled|error|invalid|pending|failure|failed|reject(?:ed)?|rtl|ltr|forced|keyboard|light|dark|theme|motion|controlled|uncontrolled|empty|missing|boundary|boundaries|ref|veto|open|closed|focus|hover|pressed|busy|checked|selected|readonly|read only|indeterminate|success|a11y|aria|contrast|locale|zoom)\b/i;
|
|
328
|
+
var SHOWCASE_STORY = /^(highlighted|card|patterns?|composition|showcase|playground)$/i;
|
|
329
|
+
var CONTENT_STORY = /withicons|sizes|variants|patterns|composition|example|content/i;
|
|
330
|
+
var OPEN_SHOWCASE = /^(?:open|persistent)\b/i;
|
|
331
|
+
var OVERLAY_FIXTURE = /\b(?:debug|test|fixture|zero|falsy|external|refs?|styling|sx|isolation|cleanup|unmount|broken|escape|outside|scroll|prevent|veto|rebase|no description)\b/i;
|
|
332
|
+
function storyWords(name) {
|
|
333
|
+
return name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ");
|
|
334
|
+
}
|
|
335
|
+
function selectExample(stories, parts = [], defaults = {}) {
|
|
336
|
+
const anatomy = parts.some((part) => /^(trigger|target|input)$/i.test(part)) && parts.some((part) => /^(content|panel|popup|list)$/i.test(part));
|
|
337
|
+
const isOpenShowcase = (story) => OPEN_SHOWCASE.test(storyWords(story.name)) && !DEBUG_STORY.test(storyWords(story.name).replace(/\b(?:open|persistent)\b/gi, "")) && !OVERLAY_FIXTURE.test(storyWords(story.name));
|
|
338
|
+
const isOpen = (story) => story.args?.open !== false && (story.args?.open === true || story.args?.defaultOpen === true || /^(?:open|persistent(?: open)?)$/i.test(storyWords(story.name)) && story.args?.defaultOpen !== false);
|
|
339
|
+
const candidates = stories.filter((story) => !DEBUG_STORY.test(storyWords(story.name)) && (!anatomy || !OVERLAY_FIXTURE.test(storyWords(story.name))));
|
|
340
|
+
const current = candidates.find((story) => SHOWCASE_STORY.test(story.name)) ?? candidates.find((story) => /^(default|primary)$/i.test(story.name)) ?? candidates.find((story) => story.description?.trim()) ?? candidates.find((story) => CONTENT_STORY.test(story.name)) ?? candidates.find((story) => /^initial(snapshot|state)$/i.test(story.name)) ?? candidates[0];
|
|
341
|
+
const currentArgs = { ...defaults, ...current?.args };
|
|
342
|
+
const standaloneOpen = (story) => /^(?:open|persistent open)$/i.test(storyWords(story.name)) && isOpen(story) && !(typeof story.play === "function" && /\b(?:userEvent|fireEvent)\b/.test(Function.prototype.toString.call(story.play)));
|
|
343
|
+
const widget = defaults !== null && !(currentArgs.open === true || currentArgs.open === void 0 && currentArgs.defaultOpen === true) && stories.some(standaloneOpen) && stories.some(({ args }) => typeof args?.onOpenChange === "function" && (typeof args.open === "boolean" || typeof args.defaultOpen === "boolean"));
|
|
344
|
+
const overlay = anatomy || widget;
|
|
345
|
+
if (overlay) {
|
|
346
|
+
const open = stories.find((story) => isOpenShowcase(story) && isOpen(story) && (anatomy || standaloneOpen(story))) ?? (anatomy ? candidates.find(isOpen) : void 0);
|
|
347
|
+
if (open) return open.name;
|
|
348
|
+
}
|
|
349
|
+
return current?.name ?? null;
|
|
350
|
+
}
|
|
351
|
+
function serializable(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
352
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return true;
|
|
353
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
354
|
+
if (typeof value !== "object" || ancestors.has(value)) return false;
|
|
355
|
+
if (!Array.isArray(value) && (Object.getPrototypeOf(value) !== Object.prototype || "$$typeof" in value)) return false;
|
|
356
|
+
ancestors.add(value);
|
|
357
|
+
const result = Object.values(value).every((item) => serializable(item, ancestors));
|
|
358
|
+
ancestors.delete(value);
|
|
359
|
+
return result;
|
|
360
|
+
}
|
|
361
|
+
function usageSnippet(componentName, args) {
|
|
362
|
+
if (!args || Object.keys(args).length === 0) return null;
|
|
363
|
+
const attributes = [];
|
|
364
|
+
for (const [key, value] of Object.entries(args)) {
|
|
365
|
+
if (key === "children" || /^on[A-Z]/.test(key) || value === void 0) continue;
|
|
366
|
+
if (!serializable(value)) return null;
|
|
367
|
+
if (typeof value === "string" && !/["&<>\n\r]/.test(value)) attributes.push(`${key}="${value}"`);
|
|
368
|
+
else if (value === true) attributes.push(key);
|
|
369
|
+
else attributes.push(`${key}={${JSON.stringify(value)}}`);
|
|
370
|
+
}
|
|
371
|
+
const opening = `<${componentName}${attributes.length ? ` ${attributes.join(" ")}` : ""}`;
|
|
372
|
+
if (args.children === void 0) return attributes.length ? `${opening} />` : null;
|
|
373
|
+
if (!serializable(args.children) || args.children !== null && typeof args.children === "object") return null;
|
|
374
|
+
const children = typeof args.children === "string" && !/[&<>{}]/.test(args.children) ? args.children : `{${JSON.stringify(args.children)}}`;
|
|
375
|
+
return `${opening}>${children}</${componentName}>`;
|
|
376
|
+
}
|
|
377
|
+
function buildUsageSnippet({ componentName, from, args, source, jsxName, component }) {
|
|
378
|
+
const rootName = componentName.split(".")[0];
|
|
379
|
+
const identity = component;
|
|
380
|
+
const tag = jsxName ?? (typeof identity?.displayName === "string" && identity.displayName.startsWith(`${rootName}.`) ? identity.displayName : componentName);
|
|
381
|
+
const compound = component != null && Object.entries(component).some(([name, part]) => /^[A-Z]/.test(name) && (typeof part === "function" || part !== null && typeof part === "object" && "$$typeof" in part));
|
|
382
|
+
const example = source?.trim() || (compound && !tag.includes(".") ? null : usageSnippet(tag, args));
|
|
383
|
+
if (!example) return null;
|
|
384
|
+
const imports = [...example.matchAll(/import\s*\{([^}]+)\}\s*from\s*(['"])(.*?)\2/g)];
|
|
385
|
+
const imported = imports.some((match) => match[3] === from && match[1].split(",").some((name) => name.trim() === rootName));
|
|
386
|
+
return imported ? example : `import { ${rootName} } from '${from}';
|
|
387
|
+
|
|
388
|
+
${example}`;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// src/story-view.tsx
|
|
392
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
393
|
+
var StoryBoundary = class extends Component2 {
|
|
394
|
+
state = { failed: false, message: "" };
|
|
395
|
+
static getDerivedStateFromError(error) {
|
|
396
|
+
return { failed: true, message: error instanceof Error ? error.message : String(error) };
|
|
397
|
+
}
|
|
398
|
+
componentDidUpdate(previous) {
|
|
399
|
+
if (this.state.failed && (previous.module !== this.props.module || previous.overrides !== this.props.overrides)) {
|
|
400
|
+
this.setState({ failed: false, message: "" });
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
render() {
|
|
404
|
+
if (this.state.failed) {
|
|
405
|
+
return /* @__PURE__ */ jsxs2("div", { className: "story-failed", children: [
|
|
406
|
+
"\u201C",
|
|
407
|
+
this.props.story,
|
|
408
|
+
"\u201D failed to render here: ",
|
|
409
|
+
this.state.message.slice(0, 240)
|
|
410
|
+
] });
|
|
411
|
+
}
|
|
412
|
+
return this.props.children;
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
function StoryView({
|
|
416
|
+
module,
|
|
417
|
+
story,
|
|
418
|
+
overrides
|
|
419
|
+
}) {
|
|
420
|
+
return /* @__PURE__ */ jsx4(StoryBoundary, { story, module, overrides, children: /* @__PURE__ */ jsx4(StoryContent, { module, story, overrides }) }, story);
|
|
421
|
+
}
|
|
422
|
+
function StoryContent({ module, story, overrides }) {
|
|
423
|
+
const meta = module.default ?? {};
|
|
424
|
+
const definition = module[story] ?? {};
|
|
425
|
+
const args = { ...meta.args, ...definition.args, ...overrides };
|
|
426
|
+
const argTypes = mergeAnnotations(meta.argTypes, definition.argTypes);
|
|
427
|
+
for (const [name, type] of Object.entries(argTypes)) {
|
|
428
|
+
const mapping = type.mapping;
|
|
429
|
+
const map = (value) => {
|
|
430
|
+
const key = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : null;
|
|
431
|
+
return mapping && key !== null && Object.hasOwn(mapping, key) ? mapping[key] : value;
|
|
432
|
+
};
|
|
433
|
+
if (Object.hasOwn(args, name)) args[name] = Array.isArray(args[name]) ? args[name].map(map) : map(args[name]);
|
|
434
|
+
}
|
|
435
|
+
const context = {
|
|
436
|
+
args,
|
|
437
|
+
initialArgs: { ...meta.args, ...definition.args },
|
|
438
|
+
argTypes,
|
|
439
|
+
globals: { ...meta.globals, ...definition.globals },
|
|
440
|
+
parameters: mergeAnnotations(meta.parameters, definition.parameters),
|
|
441
|
+
name: definition.name ?? story,
|
|
442
|
+
story: definition.name ?? story,
|
|
443
|
+
title: meta.title,
|
|
444
|
+
component: meta.component,
|
|
445
|
+
viewMode: "story",
|
|
446
|
+
loaded: {}
|
|
447
|
+
};
|
|
448
|
+
const render = definition.render ?? meta.render;
|
|
449
|
+
const renderStory = (current) => typeof render === "function" ? render(current.args, current) : meta.component ? createElement2(meta.component, current.args) : null;
|
|
450
|
+
if (!render && !meta.component) return /* @__PURE__ */ jsxs2("div", { className: "story-failed", children: [
|
|
451
|
+
"Story \u201C",
|
|
452
|
+
story,
|
|
453
|
+
"\u201D has nothing to render."
|
|
454
|
+
] });
|
|
455
|
+
const decorators = [
|
|
456
|
+
...definition.decorators ?? [],
|
|
457
|
+
...meta.decorators ?? []
|
|
458
|
+
];
|
|
459
|
+
const decorated = decorators.reduce(
|
|
460
|
+
(inner, decorator) => (current) => decorator(
|
|
461
|
+
(update) => inner({ ...current, ...update }),
|
|
462
|
+
current
|
|
463
|
+
),
|
|
464
|
+
renderStory
|
|
465
|
+
);
|
|
466
|
+
return decorated(context);
|
|
467
|
+
}
|
|
468
|
+
function useStoryModule(entry) {
|
|
469
|
+
const [module, setModule] = useState2(null);
|
|
470
|
+
const [error, setError] = useState2(null);
|
|
471
|
+
useEffect2(() => {
|
|
472
|
+
let alive = true;
|
|
473
|
+
setModule(null);
|
|
474
|
+
setError(null);
|
|
475
|
+
entry.load().then((loaded) => {
|
|
476
|
+
if (alive) setModule(loaded);
|
|
477
|
+
}).catch((cause) => {
|
|
478
|
+
if (alive) setError(cause instanceof Error ? cause.message : String(cause));
|
|
479
|
+
});
|
|
480
|
+
return () => {
|
|
481
|
+
alive = false;
|
|
482
|
+
};
|
|
483
|
+
}, [entry]);
|
|
484
|
+
return { module, error };
|
|
485
|
+
}
|
|
486
|
+
function LazySection({ children, placeholder = "\u2026" }) {
|
|
487
|
+
const ref = useRef(null);
|
|
488
|
+
const [visible, setVisible] = useState2(false);
|
|
489
|
+
useEffect2(() => {
|
|
490
|
+
const element = ref.current;
|
|
491
|
+
if (!element || visible) return;
|
|
492
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
493
|
+
setVisible(true);
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
const observer = new IntersectionObserver(
|
|
497
|
+
(entries) => {
|
|
498
|
+
if (entries.some((entry) => entry.isIntersecting)) {
|
|
499
|
+
setVisible(true);
|
|
500
|
+
observer.disconnect();
|
|
501
|
+
}
|
|
502
|
+
},
|
|
503
|
+
{ rootMargin: "640px 0px" }
|
|
504
|
+
);
|
|
505
|
+
observer.observe(element);
|
|
506
|
+
return () => observer.disconnect();
|
|
507
|
+
}, [visible]);
|
|
508
|
+
return /* @__PURE__ */ jsx4("div", { ref, children: visible ? children : /* @__PURE__ */ jsx4("div", { className: "lazy-placeholder", children: /* @__PURE__ */ jsx4(Skeleton, { width: 190 }) }) });
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// src/toc.tsx
|
|
512
|
+
import { useCallback, useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
513
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
514
|
+
var STORY_PARAM = "story";
|
|
515
|
+
var SCROLL_OFFSET_PX = 76;
|
|
516
|
+
var SETTLE_TICK_MS = 250;
|
|
517
|
+
var SETTLE_TICKS = 16;
|
|
518
|
+
var SETTLE_TOLERANCE_PX = 4;
|
|
519
|
+
var FLASH_MS = 2600;
|
|
520
|
+
var ACTIVE_ROOT_MARGIN = `-${SCROLL_OFFSET_PX}px 0px -60% 0px`;
|
|
521
|
+
function hashPath(hash) {
|
|
522
|
+
const query = hash.indexOf("?");
|
|
523
|
+
return query === -1 ? hash : hash.slice(0, query);
|
|
524
|
+
}
|
|
525
|
+
function storyFromHash(hash) {
|
|
526
|
+
const query = hash.indexOf("?");
|
|
527
|
+
return query === -1 ? null : new URLSearchParams(hash.slice(query + 1)).get(STORY_PARAM);
|
|
528
|
+
}
|
|
529
|
+
function storyLink(location, story) {
|
|
530
|
+
const base = `${location.origin}${location.pathname}${location.search}`;
|
|
531
|
+
return `${base}${hashPath(location.hash)}?${new URLSearchParams({ [STORY_PARAM]: story })}`;
|
|
532
|
+
}
|
|
533
|
+
var slugify = (text) => text.normalize("NFKD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
534
|
+
function scanPage(root, pageKey) {
|
|
535
|
+
const used = /* @__PURE__ */ new Set();
|
|
536
|
+
const unique = (prefix, text) => {
|
|
537
|
+
const base = `${prefix}-${slugify(text) || "x"}`;
|
|
538
|
+
let id = base;
|
|
539
|
+
for (let n = 2; used.has(id); n += 1) id = `${base}-${n}`;
|
|
540
|
+
used.add(id);
|
|
541
|
+
return id;
|
|
542
|
+
};
|
|
543
|
+
const sections = [];
|
|
544
|
+
const frames = [];
|
|
545
|
+
const subHeadings = [...root.querySelectorAll("h3")].filter((heading) => heading.textContent);
|
|
546
|
+
root.querySelectorAll("h2").forEach((heading) => {
|
|
547
|
+
if (!heading.textContent) return;
|
|
548
|
+
heading.id ||= unique("section", heading.textContent);
|
|
549
|
+
heading.dataset.toc = "";
|
|
550
|
+
const section = heading.parentElement?.tagName === "SECTION" ? heading.parentElement : null;
|
|
551
|
+
const stories = [];
|
|
552
|
+
section?.querySelectorAll(":scope > .frame").forEach((frame) => {
|
|
553
|
+
const header = frame.querySelector(":scope > header");
|
|
554
|
+
const name = header?.querySelector("span")?.textContent;
|
|
555
|
+
if (!header || !name) return;
|
|
556
|
+
const story = frame.dataset.story ?? name;
|
|
557
|
+
frame.id ||= unique("story", story);
|
|
558
|
+
frame.dataset.toc = "";
|
|
559
|
+
const item = { id: frame.id, name, story, element: frame };
|
|
560
|
+
stories.push(item);
|
|
561
|
+
frames.push(item);
|
|
562
|
+
});
|
|
563
|
+
const following = [...root.querySelectorAll("h2, h3")];
|
|
564
|
+
const start2 = following.indexOf(heading);
|
|
565
|
+
const end = following.findIndex((candidate, index) => index > start2 && candidate.tagName === "H2");
|
|
566
|
+
const subs = following.slice(start2 + 1, end === -1 ? void 0 : end).filter((candidate) => candidate.tagName === "H3" && subHeadings.includes(candidate)).map((candidate) => {
|
|
567
|
+
candidate.id ||= unique("sub", candidate.textContent ?? "");
|
|
568
|
+
candidate.dataset.toc = "";
|
|
569
|
+
return { id: candidate.id, title: candidate.textContent ?? "", element: candidate };
|
|
570
|
+
});
|
|
571
|
+
sections.push({ id: heading.id, title: heading.textContent, element: section ?? heading, heading, stories, subs });
|
|
572
|
+
});
|
|
573
|
+
return { pageKey, sections, frames };
|
|
574
|
+
}
|
|
575
|
+
var signature = (scan) => `${scan.pageKey}|${scan.sections.map((s) => `${s.id}(${s.subs.map((sub) => sub.id).join("+")}):${s.stories.map((st) => `${st.id}:${st.name}`).join(",")}`).join(";")}`;
|
|
576
|
+
var prefersReducedMotion = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
577
|
+
function scrollToElement(element) {
|
|
578
|
+
element.scrollIntoView({ behavior: prefersReducedMotion() ? "auto" : "smooth", block: "start" });
|
|
579
|
+
let ticks = SETTLE_TICKS;
|
|
580
|
+
let lastY = window.scrollY;
|
|
581
|
+
const settle = () => {
|
|
582
|
+
if (!element.isConnected || ticks === 0) return;
|
|
583
|
+
ticks -= 1;
|
|
584
|
+
const moving = window.scrollY !== lastY;
|
|
585
|
+
lastY = window.scrollY;
|
|
586
|
+
if (!moving && Math.abs(element.getBoundingClientRect().top - SCROLL_OFFSET_PX) > SETTLE_TOLERANCE_PX) {
|
|
587
|
+
element.scrollIntoView({ behavior: "auto", block: "start" });
|
|
588
|
+
lastY = window.scrollY;
|
|
589
|
+
}
|
|
590
|
+
window.setTimeout(settle, SETTLE_TICK_MS);
|
|
591
|
+
};
|
|
592
|
+
window.setTimeout(settle, SETTLE_TICK_MS);
|
|
593
|
+
}
|
|
594
|
+
function useActiveIds(scan) {
|
|
595
|
+
const [active, setActive] = useState3({ section: null, story: null });
|
|
596
|
+
useEffect3(() => {
|
|
597
|
+
if (!scan) return;
|
|
598
|
+
const targets = [...scan.sections.map((s) => s.element), ...scan.frames.map((f) => f.element)];
|
|
599
|
+
const order = new Map(targets.map((element, index) => [element, index]));
|
|
600
|
+
const visible = /* @__PURE__ */ new Set();
|
|
601
|
+
const observer = new IntersectionObserver(
|
|
602
|
+
(entries) => {
|
|
603
|
+
for (const entry of entries) entry.isIntersecting ? visible.add(entry.target) : visible.delete(entry.target);
|
|
604
|
+
const inView = [...visible].sort((a, b) => order.get(a) - order.get(b));
|
|
605
|
+
const section = scan.sections.find((s) => inView.includes(s.element));
|
|
606
|
+
const story = scan.frames.find((f) => inView.includes(f.element));
|
|
607
|
+
if (section || story) setActive((previous) => ({ section: section?.id ?? previous.section, story: story?.id ?? null }));
|
|
608
|
+
},
|
|
609
|
+
{ rootMargin: ACTIVE_ROOT_MARGIN }
|
|
610
|
+
);
|
|
611
|
+
targets.forEach((element) => observer.observe(element));
|
|
612
|
+
return () => observer.disconnect();
|
|
613
|
+
}, [scan]);
|
|
614
|
+
return active;
|
|
615
|
+
}
|
|
616
|
+
function PageRail({ pageKey }) {
|
|
617
|
+
const [scan, setScan] = useState3(null);
|
|
618
|
+
const pageKeyRef = useRef2(pageKey);
|
|
619
|
+
pageKeyRef.current = pageKey;
|
|
620
|
+
const [target, setTarget] = useState3(() => storyFromHash(window.location.hash));
|
|
621
|
+
const flashed = useRef2(null);
|
|
622
|
+
useEffect3(() => {
|
|
623
|
+
const main = document.querySelector(".main");
|
|
624
|
+
if (!main) return;
|
|
625
|
+
let frame = 0;
|
|
626
|
+
const rescan = () => {
|
|
627
|
+
frame = 0;
|
|
628
|
+
setScan((previous) => {
|
|
629
|
+
const next = scanPage(main, pageKeyRef.current);
|
|
630
|
+
return previous && signature(previous) === signature(next) ? previous : next;
|
|
631
|
+
});
|
|
632
|
+
};
|
|
633
|
+
const schedule = () => {
|
|
634
|
+
if (!frame) frame = requestAnimationFrame(rescan);
|
|
635
|
+
};
|
|
636
|
+
const observer = new MutationObserver(schedule);
|
|
637
|
+
observer.observe(main, { childList: true, subtree: true });
|
|
638
|
+
schedule();
|
|
639
|
+
return () => {
|
|
640
|
+
observer.disconnect();
|
|
641
|
+
cancelAnimationFrame(frame);
|
|
642
|
+
};
|
|
643
|
+
}, [pageKey]);
|
|
644
|
+
useEffect3(() => {
|
|
645
|
+
const onHash = () => setTarget(storyFromHash(window.location.hash));
|
|
646
|
+
window.addEventListener("hashchange", onHash);
|
|
647
|
+
return () => window.removeEventListener("hashchange", onHash);
|
|
648
|
+
}, []);
|
|
649
|
+
useEffect3(() => {
|
|
650
|
+
if (!target || !scan || scan.pageKey !== pageKey) return;
|
|
651
|
+
const match = scan.frames.find((frame) => frame.story === target) ?? scan.frames.find((frame) => frame.story.toLowerCase() === target.toLowerCase()) ?? scan.frames.find((frame) => frame.name === target) ?? scan.frames.find((frame) => frame.name.toLowerCase() === target.toLowerCase());
|
|
652
|
+
if (!match) return;
|
|
653
|
+
scrollToElement(match.element);
|
|
654
|
+
flashed.current?.classList.remove("toc-flash");
|
|
655
|
+
match.element.classList.add("toc-flash");
|
|
656
|
+
flashed.current = match.element;
|
|
657
|
+
window.setTimeout(() => match.element.classList.remove("toc-flash"), FLASH_MS);
|
|
658
|
+
setTarget(null);
|
|
659
|
+
}, [target, scan, pageKey]);
|
|
660
|
+
const active = useActiveIds(scan);
|
|
661
|
+
const go = useCallback((element) => scrollToElement(element), []);
|
|
662
|
+
if (!scan) return null;
|
|
663
|
+
return /* @__PURE__ */ jsx5(Fragment, { children: scan.sections.length > 0 ? /* @__PURE__ */ jsxs3("aside", { className: "toc", "aria-label": "On this page", children: [
|
|
664
|
+
/* @__PURE__ */ jsx5("div", { className: "toc-title", children: "On this page" }),
|
|
665
|
+
/* @__PURE__ */ jsx5("ul", { children: scan.sections.map((section) => /* @__PURE__ */ jsxs3("li", { children: [
|
|
666
|
+
/* @__PURE__ */ jsx5(
|
|
667
|
+
"button",
|
|
668
|
+
{
|
|
669
|
+
type: "button",
|
|
670
|
+
className: "toc-link",
|
|
671
|
+
"aria-current": active.section === section.id ? "location" : void 0,
|
|
672
|
+
onClick: () => go(section.heading),
|
|
673
|
+
children: section.title
|
|
674
|
+
}
|
|
675
|
+
),
|
|
676
|
+
section.subs.length > 0 ? /* @__PURE__ */ jsx5("ul", { children: section.subs.map((sub) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5("button", { type: "button", className: "toc-link toc-sub", onClick: () => go(sub.element), children: sub.title }) }, sub.id)) }) : null,
|
|
677
|
+
section.stories.length > 0 ? /* @__PURE__ */ jsx5("ul", { children: section.stories.map((story) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5(
|
|
678
|
+
"button",
|
|
679
|
+
{
|
|
680
|
+
type: "button",
|
|
681
|
+
className: "toc-link toc-story",
|
|
682
|
+
"aria-current": active.story === story.id ? "location" : void 0,
|
|
683
|
+
onClick: () => go(story.element),
|
|
684
|
+
children: story.name
|
|
685
|
+
}
|
|
686
|
+
) }, story.id)) }) : null
|
|
687
|
+
] }, section.id)) })
|
|
688
|
+
] }) : null });
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// src/component-demo.tsx
|
|
692
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
693
|
+
var COPIED_MS = 1800;
|
|
694
|
+
async function copyText(text) {
|
|
695
|
+
try {
|
|
696
|
+
await navigator.clipboard.writeText(text);
|
|
697
|
+
return true;
|
|
698
|
+
} catch {
|
|
699
|
+
const area = document.createElement("textarea");
|
|
700
|
+
area.value = text;
|
|
701
|
+
area.setAttribute("readonly", "");
|
|
702
|
+
area.className = "toc-clipboard";
|
|
703
|
+
document.body.append(area);
|
|
704
|
+
area.select();
|
|
705
|
+
const copied = document.execCommand("copy");
|
|
706
|
+
area.remove();
|
|
707
|
+
return copied;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
function CopyLink({ name, story }) {
|
|
711
|
+
const [copied, setCopied] = useState4(false);
|
|
712
|
+
useEffect4(() => {
|
|
713
|
+
if (!copied) return;
|
|
714
|
+
const timer = window.setTimeout(() => setCopied(false), COPIED_MS);
|
|
715
|
+
return () => window.clearTimeout(timer);
|
|
716
|
+
}, [copied]);
|
|
717
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
718
|
+
/* @__PURE__ */ jsx6(
|
|
719
|
+
"button",
|
|
720
|
+
{
|
|
721
|
+
type: "button",
|
|
722
|
+
className: "toc-copy",
|
|
723
|
+
"aria-label": `Copy link to ${name}`,
|
|
724
|
+
onClick: async () => setCopied(await copyText(storyLink(window.location, story))),
|
|
725
|
+
children: copied ? "Copied" : "Copy link"
|
|
726
|
+
}
|
|
727
|
+
),
|
|
728
|
+
/* @__PURE__ */ jsx6("span", { role: "status", className: "toc-sr", children: copied ? `Link to ${name} copied` : "" })
|
|
729
|
+
] });
|
|
730
|
+
}
|
|
731
|
+
function ControlInput({ control, value, onChange }) {
|
|
732
|
+
const id = useId();
|
|
733
|
+
const [invalid, setInvalid] = useState4(false);
|
|
734
|
+
useEffect4(() => setInvalid(false), [value]);
|
|
735
|
+
return /* @__PURE__ */ jsxs4("div", { className: "sd-control", children: [
|
|
736
|
+
/* @__PURE__ */ jsx6("label", { htmlFor: id, children: control.name }),
|
|
737
|
+
control.type === "select" ? /* @__PURE__ */ jsxs4(
|
|
738
|
+
"select",
|
|
739
|
+
{
|
|
740
|
+
id,
|
|
741
|
+
value: String(control.options?.findIndex((option) => Object.is(option, value)) ?? -1),
|
|
742
|
+
onChange: (event) => onChange(control.options?.[Number(event.target.value)]),
|
|
743
|
+
children: [
|
|
744
|
+
/* @__PURE__ */ jsx6("option", { value: "-1", disabled: true, children: "\u2014" }),
|
|
745
|
+
control.options?.map((option, index) => /* @__PURE__ */ jsx6("option", { value: index, children: String(option) }, index))
|
|
746
|
+
]
|
|
747
|
+
}
|
|
748
|
+
) : control.type === "boolean" ? /* @__PURE__ */ jsx6("input", { id, type: "checkbox", checked: Boolean(value), onChange: (event) => onChange(event.target.checked) }) : control.type === "object" ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
749
|
+
/* @__PURE__ */ jsx6(
|
|
750
|
+
"textarea",
|
|
751
|
+
{
|
|
752
|
+
id,
|
|
753
|
+
defaultValue: JSON.stringify(value, null, 2) ?? "",
|
|
754
|
+
"aria-invalid": invalid,
|
|
755
|
+
"aria-describedby": invalid ? `${id}-error` : void 0,
|
|
756
|
+
onBlur: (event) => {
|
|
757
|
+
try {
|
|
758
|
+
onChange(JSON.parse(event.target.value));
|
|
759
|
+
setInvalid(false);
|
|
760
|
+
} catch {
|
|
761
|
+
setInvalid(true);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
},
|
|
765
|
+
JSON.stringify(value)
|
|
766
|
+
),
|
|
767
|
+
invalid ? /* @__PURE__ */ jsx6("span", { id: `${id}-error`, role: "status", children: "Enter valid JSON." }) : null
|
|
768
|
+
] }) : /* @__PURE__ */ jsx6(
|
|
769
|
+
"input",
|
|
770
|
+
{
|
|
771
|
+
id,
|
|
772
|
+
type: control.type === "number" || control.type === "range" ? control.type : "text",
|
|
773
|
+
min: control.min,
|
|
774
|
+
max: control.max,
|
|
775
|
+
step: control.step ?? (control.type === "number" ? "any" : void 0),
|
|
776
|
+
value: typeof value === "string" || typeof value === "number" ? value : "",
|
|
777
|
+
onChange: (event) => onChange(control.type === "number" || control.type === "range" ? event.target.value === "" ? void 0 : event.target.valueAsNumber : event.target.value)
|
|
778
|
+
}
|
|
779
|
+
)
|
|
780
|
+
] });
|
|
781
|
+
}
|
|
782
|
+
function hasHorizontalOverflow({ scrollWidth, clientWidth }) {
|
|
783
|
+
return scrollWidth > clientWidth;
|
|
784
|
+
}
|
|
785
|
+
function ComponentDemo({
|
|
786
|
+
story,
|
|
787
|
+
storyName,
|
|
788
|
+
authoredStory,
|
|
789
|
+
skipped,
|
|
790
|
+
controls,
|
|
791
|
+
args,
|
|
792
|
+
unavailable,
|
|
793
|
+
changed,
|
|
794
|
+
onControlChange,
|
|
795
|
+
onReset,
|
|
796
|
+
storyLayout,
|
|
797
|
+
snippet,
|
|
798
|
+
codeLanguage,
|
|
799
|
+
children
|
|
800
|
+
}) {
|
|
801
|
+
const [codeOpen, setCodeOpen] = useState4(false);
|
|
802
|
+
const canvasRef = useRef3(null);
|
|
803
|
+
const [scrollable, setScrollable] = useState4(false);
|
|
804
|
+
useEffect4(() => {
|
|
805
|
+
const canvas = canvasRef.current;
|
|
806
|
+
const content = canvas?.firstElementChild;
|
|
807
|
+
if (!canvas || !content) return;
|
|
808
|
+
const measure = () => setScrollable(hasHorizontalOverflow(canvas));
|
|
809
|
+
let frame = 0;
|
|
810
|
+
const scheduleMeasure = () => {
|
|
811
|
+
cancelAnimationFrame(frame);
|
|
812
|
+
frame = requestAnimationFrame(measure);
|
|
813
|
+
};
|
|
814
|
+
measure();
|
|
815
|
+
const resize = new ResizeObserver(scheduleMeasure);
|
|
816
|
+
resize.observe(canvas);
|
|
817
|
+
resize.observe(content);
|
|
818
|
+
const mutations = new MutationObserver(scheduleMeasure);
|
|
819
|
+
mutations.observe(content, { childList: true, subtree: true, attributes: true, characterData: true });
|
|
820
|
+
return () => {
|
|
821
|
+
resize.disconnect();
|
|
822
|
+
mutations.disconnect();
|
|
823
|
+
cancelAnimationFrame(frame);
|
|
824
|
+
};
|
|
825
|
+
}, [children, story]);
|
|
826
|
+
const [laneLayout, setLaneLayout] = useState4(storyLayout);
|
|
827
|
+
const laneRef = useCallback2(
|
|
828
|
+
(node) => {
|
|
829
|
+
if (!node) return;
|
|
830
|
+
const content = node.firstElementChild;
|
|
831
|
+
if (!(content instanceof HTMLElement)) return;
|
|
832
|
+
setLaneLayout(storyLayout !== "fullscreen" && /^inline/.test(getComputedStyle(content).display) ? "inline" : storyLayout);
|
|
833
|
+
},
|
|
834
|
+
[storyLayout]
|
|
835
|
+
);
|
|
836
|
+
return /* @__PURE__ */ jsxs4("div", { className: "frame", "data-story": story, children: [
|
|
837
|
+
/* @__PURE__ */ jsxs4("header", { children: [
|
|
838
|
+
/* @__PURE__ */ jsx6("span", { children: storyName }),
|
|
839
|
+
/* @__PURE__ */ jsx6("span", { "data-toc-slot": "", children: /* @__PURE__ */ jsx6(CopyLink, { name: storyName, story }) })
|
|
840
|
+
] }),
|
|
841
|
+
authoredStory ? /* @__PURE__ */ jsx6("p", { className: "story-blurb", children: authoredStory }) : null,
|
|
842
|
+
skipped.length ? /* @__PURE__ */ jsxs4("p", { className: "sd-controls-note", children: [
|
|
843
|
+
"Not run here: ",
|
|
844
|
+
skipped.join(", "),
|
|
845
|
+
". See it in Storybook."
|
|
846
|
+
] }) : null,
|
|
847
|
+
unavailable ? /* @__PURE__ */ jsx6("p", { className: "sd-controls-note", children: unavailable }) : /* @__PURE__ */ jsxs4("fieldset", { className: "sd-controls", children: [
|
|
848
|
+
/* @__PURE__ */ jsxs4("legend", { children: [
|
|
849
|
+
"Controls for ",
|
|
850
|
+
storyName
|
|
851
|
+
] }),
|
|
852
|
+
/* @__PURE__ */ jsxs4("div", { className: "sd-controls-fields", children: [
|
|
853
|
+
controls.map((control) => /* @__PURE__ */ jsx6(
|
|
854
|
+
ControlInput,
|
|
855
|
+
{
|
|
856
|
+
control,
|
|
857
|
+
value: args[control.name],
|
|
858
|
+
onChange: (value) => onControlChange(control.name, value)
|
|
859
|
+
},
|
|
860
|
+
control.name
|
|
861
|
+
)),
|
|
862
|
+
/* @__PURE__ */ jsx6("button", { className: "sd-controls-reset", type: "button", disabled: !changed, onClick: onReset, children: "Reset" })
|
|
863
|
+
] })
|
|
864
|
+
] }),
|
|
865
|
+
/* @__PURE__ */ jsx6(
|
|
866
|
+
"div",
|
|
867
|
+
{
|
|
868
|
+
className: "shot",
|
|
869
|
+
"data-layout": storyLayout,
|
|
870
|
+
ref: canvasRef,
|
|
871
|
+
tabIndex: scrollable ? 0 : void 0,
|
|
872
|
+
role: scrollable ? "region" : void 0,
|
|
873
|
+
"aria-label": scrollable ? storyName : void 0,
|
|
874
|
+
children: /* @__PURE__ */ jsx6(LazySection, { children: /* @__PURE__ */ jsx6("div", { className: "story-lane", "data-layout": laneLayout, ref: laneRef, children }) })
|
|
875
|
+
}
|
|
876
|
+
),
|
|
877
|
+
/* @__PURE__ */ jsxs4("details", { className: "code-toggle", onToggle: (event) => setCodeOpen(event.currentTarget.open), children: [
|
|
878
|
+
/* @__PURE__ */ jsx6("summary", { children: /* @__PURE__ */ jsx6("span", { className: "sd-demo-code-actions", children: "Code" }) }),
|
|
879
|
+
codeOpen ? /* @__PURE__ */ jsx6("div", { className: "sd-demo-code", children: snippet ? /* @__PURE__ */ jsx6(CodeBlock, { code: snippet, language: codeLanguage, label: `${storyName} code` }) : /* @__PURE__ */ jsx6("p", { children: "No usage code is authored for this component." }) }) : null
|
|
880
|
+
] })
|
|
881
|
+
] });
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// src/controls.tsx
|
|
885
|
+
import { storySource } from "virtual:storybook-docs/catalog";
|
|
886
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
887
|
+
function parseDefault(value) {
|
|
888
|
+
const text = value.trim();
|
|
889
|
+
if (text === "undefined" || text === "") return void 0;
|
|
890
|
+
try {
|
|
891
|
+
return JSON.parse(text);
|
|
892
|
+
} catch {
|
|
893
|
+
if (text.startsWith("'") && text.endsWith("'") && !text.slice(1, -1).includes("'")) return text.slice(1, -1);
|
|
894
|
+
}
|
|
895
|
+
return void 0;
|
|
896
|
+
}
|
|
897
|
+
function defaultsFromProps(props = []) {
|
|
898
|
+
const defaults = {};
|
|
899
|
+
for (const prop of Array.isArray(props) ? props : []) {
|
|
900
|
+
const declared = prop?.defaultValue;
|
|
901
|
+
const text = typeof declared === "string" ? declared : declared?.value;
|
|
902
|
+
if (typeof text === "string") {
|
|
903
|
+
const value = parseDefault(text);
|
|
904
|
+
if (value !== void 0) defaults[prop.name] = value;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
return defaults;
|
|
908
|
+
}
|
|
909
|
+
function getStoryControls(meta, story, componentDefaults = {}) {
|
|
910
|
+
const args = { ...componentDefaults, ...meta.args, ...story.args };
|
|
911
|
+
const controls = [];
|
|
912
|
+
for (const [name, raw] of Object.entries(mergeAnnotations(meta.argTypes, story.argTypes))) {
|
|
913
|
+
const definition = raw;
|
|
914
|
+
const control = definition.control;
|
|
915
|
+
if (control === false || control === null) continue;
|
|
916
|
+
const type = typeof control === "string" ? control : control && typeof control === "object" && "type" in control ? control.type : void 0;
|
|
917
|
+
if (type === "boolean" || type === "number" || type === "text" || type === "string") {
|
|
918
|
+
controls.push({ name, type: type === "string" ? "text" : type });
|
|
919
|
+
} else if ((type === "select" || type === "radio" || type === "inline-radio") && Array.isArray(definition.options) && definition.options.length > 0) {
|
|
920
|
+
controls.push({ name, type: "select", options: definition.options });
|
|
921
|
+
} else if (type === "range") {
|
|
922
|
+
const settings = control;
|
|
923
|
+
controls.push({ name, type, min: settings.min, max: settings.max, step: settings.step });
|
|
924
|
+
} else if (type === "object") {
|
|
925
|
+
controls.push({ name, type });
|
|
926
|
+
} else {
|
|
927
|
+
continue;
|
|
928
|
+
}
|
|
929
|
+
if (!Object.hasOwn(args, name) && Object.hasOwn(definition, "defaultValue")) args[name] = definition.defaultValue;
|
|
930
|
+
}
|
|
931
|
+
return {
|
|
932
|
+
args,
|
|
933
|
+
controls,
|
|
934
|
+
unavailable: controls.length === 0 ? "No controls." : null
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
function ControlledStoryFrame({ module, story, componentName, componentDefaults }) {
|
|
938
|
+
const meta = module.default ?? {};
|
|
939
|
+
const definition = module[story] ?? {};
|
|
940
|
+
const { args: defaults, controls, unavailable } = getStoryControls(meta, definition, componentDefaults);
|
|
941
|
+
const [edits, setEdits] = useState5({});
|
|
942
|
+
const args = { ...defaults, ...edits };
|
|
943
|
+
const changed = Object.entries(edits).some(([name, value]) => !Object.is(value, defaults[name]));
|
|
944
|
+
const requestedLayout = definition.parameters?.layout ?? meta.parameters?.layout;
|
|
945
|
+
const storyLayout = requestedLayout === "centered" || requestedLayout === "fullscreen" ? requestedLayout : "padded";
|
|
946
|
+
const docsOverride = definition.parameters?.docs;
|
|
947
|
+
const docsMeta = meta.parameters?.docs;
|
|
948
|
+
const authoredCode = docsOverride?.source?.code ?? docsMeta?.source?.code;
|
|
949
|
+
const authoredStory = docsOverride?.description?.story ?? docsMeta?.description?.story;
|
|
950
|
+
const storyName = definition.name ?? story;
|
|
951
|
+
const skipped = ["loaders", "beforeEach"].filter((key) => meta[key] || definition[key]);
|
|
952
|
+
if (definition.parameters?.viewport ?? meta.parameters?.viewport) skipped.push("viewport");
|
|
953
|
+
const codeLanguage = docsOverride?.source?.language ?? docsMeta?.source?.language ?? "tsx";
|
|
954
|
+
const snippet = buildUsageSnippet({
|
|
955
|
+
componentName,
|
|
956
|
+
from: storySource,
|
|
957
|
+
args: { ...meta.args, ...definition.args, ...edits },
|
|
958
|
+
source: authoredCode,
|
|
959
|
+
// A story name is not a component name: only a part-qualified name (the rare `Dialog.Content`
|
|
960
|
+
// story) is worth using as the JSX tag, otherwise the component's own name is the honest one.
|
|
961
|
+
jsxName: storyName.includes(".") ? storyName : void 0,
|
|
962
|
+
component: meta.component
|
|
963
|
+
});
|
|
964
|
+
return /* @__PURE__ */ jsx7(
|
|
965
|
+
ComponentDemo,
|
|
966
|
+
{
|
|
967
|
+
story,
|
|
968
|
+
storyName,
|
|
969
|
+
authoredStory,
|
|
970
|
+
skipped,
|
|
971
|
+
controls,
|
|
972
|
+
args,
|
|
973
|
+
unavailable,
|
|
974
|
+
changed,
|
|
975
|
+
storyLayout,
|
|
976
|
+
snippet,
|
|
977
|
+
codeLanguage,
|
|
978
|
+
onControlChange: (name, value) => setEdits((current) => ({ ...current, [name]: value })),
|
|
979
|
+
onReset: () => setEdits({}),
|
|
980
|
+
children: /* @__PURE__ */ jsx7(StoryView, { module, story, overrides: edits })
|
|
981
|
+
}
|
|
982
|
+
);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
// src/props.ts
|
|
986
|
+
import { useEffect as useEffect5, useState as useState6 } from "react";
|
|
987
|
+
import { loadProps } from "virtual:storybook-docs/props";
|
|
988
|
+
function useProps(slug) {
|
|
989
|
+
const [components, setComponents] = useState6(null);
|
|
990
|
+
useEffect5(() => {
|
|
991
|
+
let alive = true;
|
|
992
|
+
setComponents(null);
|
|
993
|
+
loadProps(slug).then((module) => {
|
|
994
|
+
if (alive) setComponents(module.components);
|
|
995
|
+
}).catch(() => {
|
|
996
|
+
if (alive) setComponents([]);
|
|
997
|
+
});
|
|
998
|
+
return () => {
|
|
999
|
+
alive = false;
|
|
1000
|
+
};
|
|
1001
|
+
}, [slug]);
|
|
1002
|
+
return components;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
// src/pages/component-page.tsx
|
|
1006
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1007
|
+
function formatValue(value) {
|
|
1008
|
+
if (value === void 0) return "\u2014";
|
|
1009
|
+
if (typeof value === "function") return "fn()";
|
|
1010
|
+
if (typeof value === "string") return value.length > 40 ? `${value.slice(0, 37)}\u2026` : value;
|
|
1011
|
+
if (typeof value === "object" && value !== null) {
|
|
1012
|
+
if ("$$typeof" in value) return "<ReactNode>";
|
|
1013
|
+
if (Array.isArray(value)) return `[${value.length}]`;
|
|
1014
|
+
return "{\u2026}";
|
|
1015
|
+
}
|
|
1016
|
+
return String(value);
|
|
1017
|
+
}
|
|
1018
|
+
function TableFrame({ label, children }) {
|
|
1019
|
+
return /* @__PURE__ */ jsx8("div", { className: "table-scroll", role: "region", "aria-label": label, tabIndex: 0, children: /* @__PURE__ */ jsxs5("table", { children: [
|
|
1020
|
+
/* @__PURE__ */ jsx8("caption", { className: "sr-only", children: label }),
|
|
1021
|
+
children
|
|
1022
|
+
] }) });
|
|
1023
|
+
}
|
|
1024
|
+
function PropNotes({ prop }) {
|
|
1025
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1026
|
+
prop.description ? /* @__PURE__ */ jsx8(MarkdownView, { markdown: prop.description }) : null,
|
|
1027
|
+
prop.tags?.map((tag, index) => /* @__PURE__ */ jsxs5("div", { children: [
|
|
1028
|
+
/* @__PURE__ */ jsx8("strong", { children: tag.name === "deprecated" ? "Deprecated" : tag.name === "since" ? "Since" : "Example" }),
|
|
1029
|
+
tag.name === "example" ? /* @__PURE__ */ jsx8("pre", { children: /* @__PURE__ */ jsx8("code", { children: tag.text }) }) : tag.text ? /* @__PURE__ */ jsx8(MarkdownView, { markdown: tag.text }) : null
|
|
1030
|
+
] }, `${tag.name}:${index}`)),
|
|
1031
|
+
prop.inheritedFrom ? /* @__PURE__ */ jsxs5("small", { children: [
|
|
1032
|
+
"Inherited from ",
|
|
1033
|
+
/* @__PURE__ */ jsx8("code", { children: prop.inheritedFrom })
|
|
1034
|
+
] }) : null,
|
|
1035
|
+
!prop.description && !prop.tags?.length && !prop.inheritedFrom ? "\u2014" : null
|
|
1036
|
+
] });
|
|
1037
|
+
}
|
|
1038
|
+
function PropRows({ props }) {
|
|
1039
|
+
return props.map((prop) => /* @__PURE__ */ jsxs5("tr", { children: [
|
|
1040
|
+
/* @__PURE__ */ jsxs5("th", { scope: "row", children: [
|
|
1041
|
+
/* @__PURE__ */ jsx8("code", { children: prop.name }),
|
|
1042
|
+
prop.required ? /* @__PURE__ */ jsx8("span", { className: "req", children: "required" }) : null
|
|
1043
|
+
] }),
|
|
1044
|
+
/* @__PURE__ */ jsxs5("td", { children: [
|
|
1045
|
+
/* @__PURE__ */ jsx8("code", { className: "type", children: prop.typeUnavailable ? "Not resolved" : prop.type }),
|
|
1046
|
+
prop.members?.length ? /* @__PURE__ */ jsxs5("details", { children: [
|
|
1047
|
+
/* @__PURE__ */ jsx8("summary", { children: prop.name === "slotProps" ? "Slots" : "Fields" }),
|
|
1048
|
+
/* @__PURE__ */ jsx8("dl", { children: prop.members.map((member) => /* @__PURE__ */ jsxs5("div", { children: [
|
|
1049
|
+
/* @__PURE__ */ jsxs5("dt", { children: [
|
|
1050
|
+
/* @__PURE__ */ jsx8("code", { children: member.name }),
|
|
1051
|
+
member.required ? " (required)" : ""
|
|
1052
|
+
] }),
|
|
1053
|
+
/* @__PURE__ */ jsxs5("dd", { children: [
|
|
1054
|
+
/* @__PURE__ */ jsx8("code", { children: member.type }),
|
|
1055
|
+
/* @__PURE__ */ jsx8(PropNotes, { prop: member })
|
|
1056
|
+
] })
|
|
1057
|
+
] }, member.name)) })
|
|
1058
|
+
] }) : null
|
|
1059
|
+
] }),
|
|
1060
|
+
/* @__PURE__ */ jsx8("td", { children: /* @__PURE__ */ jsx8("code", { children: prop.defaultValue === "undefined" ? "\u2014" : prop.defaultValue ?? "\u2014" }) }),
|
|
1061
|
+
/* @__PURE__ */ jsx8("td", { children: /* @__PURE__ */ jsx8(PropNotes, { prop }) })
|
|
1062
|
+
] }, prop.name));
|
|
1063
|
+
}
|
|
1064
|
+
function PropsTable({
|
|
1065
|
+
components,
|
|
1066
|
+
argTypes,
|
|
1067
|
+
defaultArgs
|
|
1068
|
+
}) {
|
|
1069
|
+
if (components === null) {
|
|
1070
|
+
return /* @__PURE__ */ jsx8("div", { className: "skeleton-page", "aria-busy": "true", children: /* @__PURE__ */ jsx8(Skeleton, { lines: 4, height: 14 }) });
|
|
1071
|
+
}
|
|
1072
|
+
if (components && components.length > 0) {
|
|
1073
|
+
const single = components.length === 1;
|
|
1074
|
+
return /* @__PURE__ */ jsx8(Fragment3, { children: components.map((component) => /* @__PURE__ */ jsxs5("section", { children: [
|
|
1075
|
+
!single ? /* @__PURE__ */ jsx8("h3", { children: component.name }) : null,
|
|
1076
|
+
component.native ? /* @__PURE__ */ jsxs5("p", { className: "hint", children: [
|
|
1077
|
+
"Native element: ",
|
|
1078
|
+
/* @__PURE__ */ jsxs5("code", { children: [
|
|
1079
|
+
"<",
|
|
1080
|
+
component.native,
|
|
1081
|
+
">"
|
|
1082
|
+
] }),
|
|
1083
|
+
"."
|
|
1084
|
+
] }) : null,
|
|
1085
|
+
component.props.some((prop) => !prop.inheritedFrom) ? /* @__PURE__ */ jsxs5(TableFrame, { label: `${component.name} props`, children: [
|
|
1086
|
+
/* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsxs5("tr", { children: [
|
|
1087
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Prop" }),
|
|
1088
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Type" }),
|
|
1089
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Default" }),
|
|
1090
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Notes" })
|
|
1091
|
+
] }) }),
|
|
1092
|
+
/* @__PURE__ */ jsx8("tbody", { children: /* @__PURE__ */ jsx8(PropRows, { props: component.props.filter((prop) => !prop.inheritedFrom) }) })
|
|
1093
|
+
] }) : /* @__PURE__ */ jsx8("p", { children: "No component-specific props." }),
|
|
1094
|
+
component.props.some((prop) => prop.inheritedFrom) ? /* @__PURE__ */ jsxs5("details", { children: [
|
|
1095
|
+
/* @__PURE__ */ jsxs5("summary", { children: [
|
|
1096
|
+
"Inherited props (",
|
|
1097
|
+
component.props.filter((prop) => prop.inheritedFrom).length,
|
|
1098
|
+
")"
|
|
1099
|
+
] }),
|
|
1100
|
+
/* @__PURE__ */ jsxs5(TableFrame, { label: `${component.name} inherited props`, children: [
|
|
1101
|
+
/* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsxs5("tr", { children: [
|
|
1102
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Prop" }),
|
|
1103
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Type" }),
|
|
1104
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Default" }),
|
|
1105
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Notes" })
|
|
1106
|
+
] }) }),
|
|
1107
|
+
/* @__PURE__ */ jsx8("tbody", { children: /* @__PURE__ */ jsx8(PropRows, { props: component.props.filter((prop) => prop.inheritedFrom) }) })
|
|
1108
|
+
] })
|
|
1109
|
+
] }) : null
|
|
1110
|
+
] }, component.name)) });
|
|
1111
|
+
}
|
|
1112
|
+
if (Object.keys(argTypes).length > 0) {
|
|
1113
|
+
return /* @__PURE__ */ jsxs5(TableFrame, { label: "Props", children: [
|
|
1114
|
+
/* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsxs5("tr", { children: [
|
|
1115
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Prop" }),
|
|
1116
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Control" }),
|
|
1117
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Options" }),
|
|
1118
|
+
/* @__PURE__ */ jsx8("th", { scope: "col", children: "Default" })
|
|
1119
|
+
] }) }),
|
|
1120
|
+
/* @__PURE__ */ jsx8("tbody", { children: Object.entries(argTypes).map(([prop, definition]) => /* @__PURE__ */ jsxs5("tr", { children: [
|
|
1121
|
+
/* @__PURE__ */ jsx8("th", { scope: "row", children: /* @__PURE__ */ jsx8("code", { children: prop }) }),
|
|
1122
|
+
/* @__PURE__ */ jsx8("td", { children: formatValue(definition.control) }),
|
|
1123
|
+
/* @__PURE__ */ jsx8("td", { children: Array.isArray(definition.options) ? definition.options.map((option) => formatValue(option)).join(" | ") : "\u2014" }),
|
|
1124
|
+
/* @__PURE__ */ jsx8("td", { children: formatValue(defaultArgs[prop]) })
|
|
1125
|
+
] }, prop)) })
|
|
1126
|
+
] });
|
|
1127
|
+
}
|
|
1128
|
+
return /* @__PURE__ */ jsx8("p", { children: "No props." });
|
|
1129
|
+
}
|
|
1130
|
+
function ComponentPage({ entry }) {
|
|
1131
|
+
const { module, error } = useStoryModule(entry);
|
|
1132
|
+
const props = useProps(entry.slug);
|
|
1133
|
+
const meta = module?.default ?? {};
|
|
1134
|
+
const argTypes = meta.argTypes ?? {};
|
|
1135
|
+
const defaultArgs = meta.args ?? {};
|
|
1136
|
+
const description = meta.parameters?.docs?.description?.component;
|
|
1137
|
+
const usage = meta.parameters?.docs?.usage;
|
|
1138
|
+
const visibleStories = useMemo3(() => {
|
|
1139
|
+
if (!module) return entry.stories;
|
|
1140
|
+
const metaTags = (meta.tags ?? []).map(String);
|
|
1141
|
+
return entry.stories.filter((name) => {
|
|
1142
|
+
const storyTags = (module[name]?.tags ?? []).map(String);
|
|
1143
|
+
return ![...metaTags, ...storyTags].includes("!autodocs");
|
|
1144
|
+
});
|
|
1145
|
+
}, [entry.stories, meta, module]);
|
|
1146
|
+
const componentDefaults = useMemo3(
|
|
1147
|
+
() => defaultsFromProps(props?.find((component) => component.name === entry.name)?.props ?? []),
|
|
1148
|
+
[props, entry.name]
|
|
1149
|
+
);
|
|
1150
|
+
const example = selectExample(visibleStories.map((name) => ({
|
|
1151
|
+
name,
|
|
1152
|
+
description: module?.[name]?.parameters?.docs?.description?.story,
|
|
1153
|
+
args: { ...defaultArgs, ...module?.[name]?.args },
|
|
1154
|
+
play: module?.[name]?.play
|
|
1155
|
+
})), Object.keys(meta.component ?? {}), props === null ? null : componentDefaults);
|
|
1156
|
+
const sections = useMemo3(() => sectionStories(visibleStories.filter((story) => story !== example)), [visibleStories, example]);
|
|
1157
|
+
const defaultStory = module?.[visibleStories.find((name) => /^default$/i.test(name)) ?? example ?? ""] ?? {};
|
|
1158
|
+
const fallbackSource = visibleStories.map((name) => module?.[name]?.parameters?.docs?.source).find((source2) => source2?.code?.trim());
|
|
1159
|
+
const source = {
|
|
1160
|
+
code: defaultStory.parameters?.docs?.source?.code ?? meta.parameters?.docs?.source?.code ?? fallbackSource?.code,
|
|
1161
|
+
language: defaultStory.parameters?.docs?.source?.language ?? meta.parameters?.docs?.source?.language ?? fallbackSource?.language
|
|
1162
|
+
};
|
|
1163
|
+
const codeLanguage = source?.language ?? "tsx";
|
|
1164
|
+
const snippet = useMemo3(
|
|
1165
|
+
() => entry.hasComponent ? buildUsageSnippet({
|
|
1166
|
+
componentName: entry.name,
|
|
1167
|
+
from: storySource2,
|
|
1168
|
+
component: meta.component,
|
|
1169
|
+
source: source?.code,
|
|
1170
|
+
args: { ...defaultArgs, ...defaultStory.args }
|
|
1171
|
+
}) : null,
|
|
1172
|
+
[source?.code, entry.name, entry.hasComponent, defaultArgs, defaultStory.args, meta.component]
|
|
1173
|
+
);
|
|
1174
|
+
const propCount = props ? props.reduce((total, component) => total + component.props.filter((prop) => !prop.inheritedFrom).length, 0) : Object.keys(argTypes).length;
|
|
1175
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1176
|
+
/* @__PURE__ */ jsxs5("div", { className: "crumb", children: [
|
|
1177
|
+
entry.group,
|
|
1178
|
+
" / ",
|
|
1179
|
+
entry.name
|
|
1180
|
+
] }),
|
|
1181
|
+
/* @__PURE__ */ jsx8("h1", { children: entry.name }),
|
|
1182
|
+
/* @__PURE__ */ jsxs5("div", { className: "summary-row", children: [
|
|
1183
|
+
/* @__PURE__ */ jsxs5("span", { className: "chip", children: [
|
|
1184
|
+
module ? visibleStories.length : entry.stories.length,
|
|
1185
|
+
" stories"
|
|
1186
|
+
] }),
|
|
1187
|
+
/* @__PURE__ */ jsxs5("span", { className: "chip", children: [
|
|
1188
|
+
propCount,
|
|
1189
|
+
" props"
|
|
1190
|
+
] })
|
|
1191
|
+
] }),
|
|
1192
|
+
/* @__PURE__ */ jsx8("p", { className: "lede", children: description ?? `${entry.name} \u2014 every story in ${entry.storybookTitle} is rendered below, in sections.` }),
|
|
1193
|
+
error ? /* @__PURE__ */ jsxs5("div", { className: "story-failed", children: [
|
|
1194
|
+
"Could not load the story module: ",
|
|
1195
|
+
error
|
|
1196
|
+
] }) : null,
|
|
1197
|
+
!module && !error ? /* @__PURE__ */ jsxs5("div", { className: "skeleton-page", "aria-busy": "true", children: [
|
|
1198
|
+
/* @__PURE__ */ jsx8(Skeleton, { width: 260, height: 16 }),
|
|
1199
|
+
/* @__PURE__ */ jsx8(Skeleton, { height: 150 }),
|
|
1200
|
+
/* @__PURE__ */ jsx8(Skeleton, { height: 150 })
|
|
1201
|
+
] }) : null,
|
|
1202
|
+
module ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1203
|
+
example ? /* @__PURE__ */ jsx8(ControlledStoryFrame, { module, story: example, componentName: entry.name, componentDefaults }, `${entry.slug}:${example}`) : null,
|
|
1204
|
+
entry.hasComponent ? /* @__PURE__ */ jsx8("h2", { children: "Usage" }) : null,
|
|
1205
|
+
snippet ? /* @__PURE__ */ jsx8(CodeBlock, { code: snippet, language: codeLanguage }) : entry.hasComponent ? /* @__PURE__ */ jsx8("p", { children: "No usage code is authored for this component." }) : null,
|
|
1206
|
+
usage ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1207
|
+
entry.hasComponent ? null : /* @__PURE__ */ jsx8("h2", { children: "Usage" }),
|
|
1208
|
+
/* @__PURE__ */ jsx8(MarkdownView, { markdown: usage })
|
|
1209
|
+
] }) : null,
|
|
1210
|
+
/* @__PURE__ */ jsx8(Guidance, { slug: entry.slug }),
|
|
1211
|
+
sections.map((section) => /* @__PURE__ */ jsxs5("section", { children: [
|
|
1212
|
+
/* @__PURE__ */ jsx8("h2", { children: section.title }),
|
|
1213
|
+
section.stories.map((story) => /* @__PURE__ */ jsx8(ControlledStoryFrame, { module, story, componentName: entry.name, componentDefaults }, `${entry.slug}:${story}`))
|
|
1214
|
+
] }, section.title))
|
|
1215
|
+
] }) : null,
|
|
1216
|
+
/* @__PURE__ */ jsx8("h2", { children: "Props" }),
|
|
1217
|
+
/* @__PURE__ */ jsx8(PropsTable, { components: props, argTypes, defaultArgs }),
|
|
1218
|
+
/* @__PURE__ */ jsx8("h2", { children: "Notes" }),
|
|
1219
|
+
/* @__PURE__ */ jsx8("p", { children: "Everything above is generated from this component\u2019s story module and source files. Editorial judgement \u2014 when to reach for it, when not to \u2014 is written next to the code and rendered as guidance above." })
|
|
1220
|
+
] });
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
// src/pages/foundations-color.tsx
|
|
1224
|
+
import { vars } from "virtual:storybook-docs/tokens";
|
|
1225
|
+
import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1226
|
+
var colorSection = vars.color;
|
|
1227
|
+
var roles = Object.entries(colorSection ?? {}).sort(([a], [b]) => a.localeCompare(b));
|
|
1228
|
+
function ColorPage() {
|
|
1229
|
+
return /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1230
|
+
/* @__PURE__ */ jsx9("div", { className: "crumb", children: "Foundations / Color" }),
|
|
1231
|
+
/* @__PURE__ */ jsx9("h1", { children: "Color" }),
|
|
1232
|
+
/* @__PURE__ */ jsx9("p", { className: "lede", children: "The design system's colour roles." }),
|
|
1233
|
+
/* @__PURE__ */ jsx9("h2", { children: "Roles" }),
|
|
1234
|
+
/* @__PURE__ */ jsx9("div", { className: "swatches", children: roles.map(([role, reference]) => /* @__PURE__ */ jsxs6("div", { className: "sw", children: [
|
|
1235
|
+
/* @__PURE__ */ jsx9("div", { className: "c", style: { background: reference } }),
|
|
1236
|
+
/* @__PURE__ */ jsxs6("div", { className: "n", children: [
|
|
1237
|
+
/* @__PURE__ */ jsx9("b", { children: role }),
|
|
1238
|
+
reference
|
|
1239
|
+
] })
|
|
1240
|
+
] }, role)) }),
|
|
1241
|
+
/* @__PURE__ */ jsx9("h2", { children: "Rules" }),
|
|
1242
|
+
/* @__PURE__ */ jsxs6("ul", { children: [
|
|
1243
|
+
/* @__PURE__ */ jsx9("li", { children: "Components read token roles; the application decides the theme (an attribute on the root, or a scoped theme wrapper)." }),
|
|
1244
|
+
/* @__PURE__ */ jsx9("li", { children: "Control boundaries hold \u22653:1 against both the page and the control interior (WCAG 1.4.11)." }),
|
|
1245
|
+
/* @__PURE__ */ jsx9("li", { children: "Raw values live in the token source only \u2014 this page is where they are allowed to be visible." }),
|
|
1246
|
+
/* @__PURE__ */ jsx9("li", { children: "State is never signalled by color alone; tones pair with glyphs, text or outlines." })
|
|
1247
|
+
] })
|
|
1248
|
+
] });
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
// src/pages/foundations-effects.tsx
|
|
1252
|
+
import { vars as vars2 } from "virtual:storybook-docs/tokens";
|
|
1253
|
+
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1254
|
+
var token = vars2;
|
|
1255
|
+
var shadow = Object.entries(token.shadow ?? {});
|
|
1256
|
+
var motion = token.motion ?? {};
|
|
1257
|
+
var duration = Object.entries(motion.duration ?? {});
|
|
1258
|
+
var easing = Object.entries(motion.ease ?? motion.easing ?? {});
|
|
1259
|
+
function EffectsPage() {
|
|
1260
|
+
return /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
1261
|
+
/* @__PURE__ */ jsx10("div", { className: "crumb", children: "Foundations / Elevation & motion" }),
|
|
1262
|
+
/* @__PURE__ */ jsx10("h1", { children: "Elevation & motion" }),
|
|
1263
|
+
/* @__PURE__ */ jsx10("p", { className: "lede", children: "Shadow roles and motion timings." }),
|
|
1264
|
+
shadow.length > 0 ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
1265
|
+
/* @__PURE__ */ jsx10("h2", { children: "Elevation" }),
|
|
1266
|
+
/* @__PURE__ */ jsx10("div", { className: "shadow-row", children: shadow.map(([name, reference]) => /* @__PURE__ */ jsxs7("div", { className: "shadow-cell", children: [
|
|
1267
|
+
/* @__PURE__ */ jsx10("span", { className: "shadow-box", style: { boxShadow: reference } }),
|
|
1268
|
+
/* @__PURE__ */ jsxs7("span", { className: "meta", children: [
|
|
1269
|
+
name,
|
|
1270
|
+
" \xB7 ",
|
|
1271
|
+
reference
|
|
1272
|
+
] })
|
|
1273
|
+
] }, name)) })
|
|
1274
|
+
] }) : null,
|
|
1275
|
+
duration.length > 0 ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
1276
|
+
/* @__PURE__ */ jsx10("h2", { children: "Durations" }),
|
|
1277
|
+
/* @__PURE__ */ jsx10("div", { className: "scale-rows", children: duration.map(([name, reference]) => /* @__PURE__ */ jsxs7("div", { className: "space-row", children: [
|
|
1278
|
+
/* @__PURE__ */ jsxs7("span", { className: "meta", children: [
|
|
1279
|
+
name,
|
|
1280
|
+
" \xB7 ",
|
|
1281
|
+
reference
|
|
1282
|
+
] }),
|
|
1283
|
+
/* @__PURE__ */ jsx10("span", { className: "motion-demo", style: { animationDuration: reference } })
|
|
1284
|
+
] }, name)) })
|
|
1285
|
+
] }) : null,
|
|
1286
|
+
easing.length > 0 ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
1287
|
+
/* @__PURE__ */ jsx10("h2", { children: "Easing" }),
|
|
1288
|
+
/* @__PURE__ */ jsx10("div", { className: "scale-rows", children: easing.map(([name, reference]) => /* @__PURE__ */ jsxs7("div", { className: "space-row", children: [
|
|
1289
|
+
/* @__PURE__ */ jsxs7("span", { className: "meta", children: [
|
|
1290
|
+
name,
|
|
1291
|
+
" \xB7 ",
|
|
1292
|
+
reference
|
|
1293
|
+
] }),
|
|
1294
|
+
/* @__PURE__ */ jsx10("code", { children: reference })
|
|
1295
|
+
] }, name)) })
|
|
1296
|
+
] }) : null,
|
|
1297
|
+
/* @__PURE__ */ jsx10("h2", { children: "Rules" }),
|
|
1298
|
+
/* @__PURE__ */ jsxs7("ul", { children: [
|
|
1299
|
+
/* @__PURE__ */ jsx10("li", { children: "Motion is a hint, never a requirement: every animation needs a reduced-motion branch that still completes the lifecycle." }),
|
|
1300
|
+
/* @__PURE__ */ jsxs7("li", { children: [
|
|
1301
|
+
"Transitions list the properties they animate \u2014 never ",
|
|
1302
|
+
/* @__PURE__ */ jsx10("code", { children: "transition: all" }),
|
|
1303
|
+
"."
|
|
1304
|
+
] }),
|
|
1305
|
+
/* @__PURE__ */ jsx10("li", { children: "Elevation encodes layering, not decoration: overlays sit above content, and the shadow role says how far." })
|
|
1306
|
+
] })
|
|
1307
|
+
] });
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
// src/pages/foundations-spacing.tsx
|
|
1311
|
+
import { vars as vars3 } from "virtual:storybook-docs/tokens";
|
|
1312
|
+
import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1313
|
+
var token2 = vars3;
|
|
1314
|
+
var space = Object.entries(token2.space ?? {});
|
|
1315
|
+
var radius = Object.entries(token2.radius ?? {});
|
|
1316
|
+
var sizes = Object.entries(token2.size ?? {});
|
|
1317
|
+
function SpacingPage() {
|
|
1318
|
+
return /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
1319
|
+
/* @__PURE__ */ jsx11("div", { className: "crumb", children: "Foundations / Spacing & shape" }),
|
|
1320
|
+
/* @__PURE__ */ jsx11("h1", { children: "Spacing & shape" }),
|
|
1321
|
+
/* @__PURE__ */ jsx11("p", { className: "lede", children: "The space scale, corner radii and fixed sizes." }),
|
|
1322
|
+
space.length > 0 ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
1323
|
+
/* @__PURE__ */ jsx11("h2", { children: "Space scale" }),
|
|
1324
|
+
/* @__PURE__ */ jsx11("div", { className: "scale-rows", children: space.map(([name, reference]) => /* @__PURE__ */ jsxs8("div", { className: "space-row", children: [
|
|
1325
|
+
/* @__PURE__ */ jsxs8("span", { className: "meta", children: [
|
|
1326
|
+
name,
|
|
1327
|
+
" \xB7 ",
|
|
1328
|
+
reference
|
|
1329
|
+
] }),
|
|
1330
|
+
/* @__PURE__ */ jsx11("span", { className: "bar", style: { width: reference, background: "var(--sd-accent)" } }),
|
|
1331
|
+
/* @__PURE__ */ jsx11("span", { className: "bar-outline", style: { width: reference } })
|
|
1332
|
+
] }, name)) })
|
|
1333
|
+
] }) : /* @__PURE__ */ jsx11("p", { children: "No space tokens were found in the configured token module." }),
|
|
1334
|
+
radius.length > 0 ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
1335
|
+
/* @__PURE__ */ jsx11("h2", { children: "Radii" }),
|
|
1336
|
+
/* @__PURE__ */ jsx11("div", { className: "radius-row", children: radius.map(([name, reference]) => /* @__PURE__ */ jsxs8("div", { className: "radius-cell", children: [
|
|
1337
|
+
/* @__PURE__ */ jsx11("span", { className: "radius-box", style: { borderRadius: reference } }),
|
|
1338
|
+
/* @__PURE__ */ jsxs8("span", { className: "meta", children: [
|
|
1339
|
+
name,
|
|
1340
|
+
" \xB7 ",
|
|
1341
|
+
reference
|
|
1342
|
+
] })
|
|
1343
|
+
] }, name)) })
|
|
1344
|
+
] }) : null,
|
|
1345
|
+
sizes.length > 0 ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
1346
|
+
/* @__PURE__ */ jsx11("h2", { children: "Sizes" }),
|
|
1347
|
+
/* @__PURE__ */ jsx11("div", { className: "scale-rows", children: sizes.map(([name, reference]) => /* @__PURE__ */ jsxs8("div", { className: "space-row", children: [
|
|
1348
|
+
/* @__PURE__ */ jsxs8("span", { className: "meta", children: [
|
|
1349
|
+
name,
|
|
1350
|
+
" \xB7 ",
|
|
1351
|
+
reference
|
|
1352
|
+
] }),
|
|
1353
|
+
/* @__PURE__ */ jsx11("span", { className: "bar-outline", style: { width: reference } })
|
|
1354
|
+
] }, name)) })
|
|
1355
|
+
] }) : null,
|
|
1356
|
+
/* @__PURE__ */ jsx11("h2", { children: "Rules" }),
|
|
1357
|
+
/* @__PURE__ */ jsxs8("ul", { children: [
|
|
1358
|
+
/* @__PURE__ */ jsx11("li", { children: "Spacing between siblings comes from the scale; arbitrary pixel gaps are a smell." }),
|
|
1359
|
+
/* @__PURE__ */ jsx11("li", { children: "Radii follow the token roles so dense and roomy surfaces stay consistent." }),
|
|
1360
|
+
/* @__PURE__ */ jsx11("li", { children: "Fixed sizes exist for hit targets \u2014 interactive controls stay at or above the minimum target size." })
|
|
1361
|
+
] })
|
|
1362
|
+
] });
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
// src/pages/foundations-type.tsx
|
|
1366
|
+
import { vars as vars4 } from "virtual:storybook-docs/tokens";
|
|
1367
|
+
import { Fragment as Fragment7, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1368
|
+
var token3 = vars4;
|
|
1369
|
+
var sizes2 = Object.entries(token3.textSize ?? {});
|
|
1370
|
+
var weights = Object.entries(token3.fontWeight ?? {});
|
|
1371
|
+
var families = Object.entries(token3.font ?? {});
|
|
1372
|
+
function TypePage() {
|
|
1373
|
+
return /* @__PURE__ */ jsxs9(Fragment7, { children: [
|
|
1374
|
+
/* @__PURE__ */ jsx12("div", { className: "crumb", children: "Foundations / Typography" }),
|
|
1375
|
+
/* @__PURE__ */ jsx12("h1", { children: "Typography" }),
|
|
1376
|
+
/* @__PURE__ */ jsx12("p", { className: "lede", children: "The type scale, weights and families." }),
|
|
1377
|
+
families.length > 0 ? /* @__PURE__ */ jsxs9(Fragment7, { children: [
|
|
1378
|
+
/* @__PURE__ */ jsx12("h2", { children: "Family" }),
|
|
1379
|
+
families.map(([name, reference]) => /* @__PURE__ */ jsxs9("div", { className: "scale-row", children: [
|
|
1380
|
+
/* @__PURE__ */ jsxs9("span", { className: "meta", children: [
|
|
1381
|
+
name,
|
|
1382
|
+
" \xB7 ",
|
|
1383
|
+
reference
|
|
1384
|
+
] }),
|
|
1385
|
+
/* @__PURE__ */ jsx12("span", { style: { fontFamily: reference, fontSize: "20px" }, children: "The quick brown fox jumps over the lazy dog" })
|
|
1386
|
+
] }, name))
|
|
1387
|
+
] }) : null,
|
|
1388
|
+
/* @__PURE__ */ jsx12("h2", { children: "Scale" }),
|
|
1389
|
+
sizes2.length > 0 ? sizes2.map(([name, reference]) => /* @__PURE__ */ jsxs9("div", { className: "scale-row", children: [
|
|
1390
|
+
/* @__PURE__ */ jsxs9("span", { className: "meta", children: [
|
|
1391
|
+
name,
|
|
1392
|
+
" \xB7 ",
|
|
1393
|
+
reference
|
|
1394
|
+
] }),
|
|
1395
|
+
/* @__PURE__ */ jsx12("span", { style: { fontSize: reference }, children: "Save changes \xB7 0123456789" })
|
|
1396
|
+
] }, name)) : /* @__PURE__ */ jsx12("p", { children: "No text-size tokens were found in the configured token module." }),
|
|
1397
|
+
weights.length > 0 ? /* @__PURE__ */ jsxs9(Fragment7, { children: [
|
|
1398
|
+
/* @__PURE__ */ jsx12("h2", { children: "Weights" }),
|
|
1399
|
+
weights.map(([name, reference]) => /* @__PURE__ */ jsxs9("div", { className: "scale-row", children: [
|
|
1400
|
+
/* @__PURE__ */ jsxs9("span", { className: "meta", children: [
|
|
1401
|
+
name,
|
|
1402
|
+
" \xB7 ",
|
|
1403
|
+
reference
|
|
1404
|
+
] }),
|
|
1405
|
+
/* @__PURE__ */ jsx12("span", { style: { fontWeight: reference, fontSize: "18px" }, children: "Design system documentation" })
|
|
1406
|
+
] }, name))
|
|
1407
|
+
] }) : null,
|
|
1408
|
+
/* @__PURE__ */ jsx12("h2", { children: "Rules" }),
|
|
1409
|
+
/* @__PURE__ */ jsxs9("ul", { children: [
|
|
1410
|
+
/* @__PURE__ */ jsx12("li", { children: "Sizes and line-heights come from tokens; components never set raw font sizes." }),
|
|
1411
|
+
/* @__PURE__ */ jsx12("li", { children: "Numbers that update live use tabular figures so they do not jitter." })
|
|
1412
|
+
] })
|
|
1413
|
+
] });
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
// src/pages/overview.tsx
|
|
1417
|
+
import { catalog, groups, stats } from "virtual:storybook-docs/catalog";
|
|
1418
|
+
import { site } from "virtual:storybook-docs/site";
|
|
1419
|
+
|
|
1420
|
+
// src/base.ts
|
|
1421
|
+
var STORYBOOK_DOCS_BASE = (() => {
|
|
1422
|
+
const globalBase = globalThis.__STORYBOOK_DOCS_BASE__;
|
|
1423
|
+
if (globalBase) return globalBase.replace(/\/$/, "");
|
|
1424
|
+
const { pathname } = window.location;
|
|
1425
|
+
return pathname === "/" || pathname.endsWith(".html") ? "" : pathname.replace(/\/$/, "");
|
|
1426
|
+
})();
|
|
1427
|
+
var hrefFor = (path) => `${STORYBOOK_DOCS_BASE}${path}`;
|
|
1428
|
+
|
|
1429
|
+
// src/pages/overview.tsx
|
|
1430
|
+
import { Fragment as Fragment8, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1431
|
+
function OverviewPage() {
|
|
1432
|
+
const startHere = catalog.slice(0, 6);
|
|
1433
|
+
return /* @__PURE__ */ jsxs10(Fragment8, { children: [
|
|
1434
|
+
/* @__PURE__ */ jsx13("div", { className: "crumb", children: "Overview" }),
|
|
1435
|
+
/* @__PURE__ */ jsx13("h1", { children: site.title }),
|
|
1436
|
+
site.tagline ? /* @__PURE__ */ jsx13("p", { className: "lede", children: site.tagline }) : null,
|
|
1437
|
+
/* @__PURE__ */ jsx13(Guidance, { slug: "index" }),
|
|
1438
|
+
/* @__PURE__ */ jsxs10("div", { className: "tiles", children: [
|
|
1439
|
+
/* @__PURE__ */ jsxs10("div", { className: "card tile", children: [
|
|
1440
|
+
/* @__PURE__ */ jsx13("div", { className: "num", children: stats.components }),
|
|
1441
|
+
/* @__PURE__ */ jsx13("b", { children: "Components" })
|
|
1442
|
+
] }),
|
|
1443
|
+
/* @__PURE__ */ jsxs10("div", { className: "card tile", children: [
|
|
1444
|
+
/* @__PURE__ */ jsx13("div", { className: "num", children: stats.stories }),
|
|
1445
|
+
/* @__PURE__ */ jsx13("b", { children: "Stories" })
|
|
1446
|
+
] })
|
|
1447
|
+
] }),
|
|
1448
|
+
/* @__PURE__ */ jsx13("h2", { children: "Browse by area" }),
|
|
1449
|
+
/* @__PURE__ */ jsx13("div", { className: "group-grid", children: groups.map((group) => {
|
|
1450
|
+
const inGroup = catalog.filter((entry) => entry.group === group);
|
|
1451
|
+
const shown = inGroup.slice(0, 6);
|
|
1452
|
+
return /* @__PURE__ */ jsxs10("div", { className: "card group-card", children: [
|
|
1453
|
+
/* @__PURE__ */ jsxs10("h3", { children: [
|
|
1454
|
+
group,
|
|
1455
|
+
" ",
|
|
1456
|
+
/* @__PURE__ */ jsx13("span", { className: "count", children: inGroup.length })
|
|
1457
|
+
] }),
|
|
1458
|
+
/* @__PURE__ */ jsx13("ul", { children: shown.map((entry) => /* @__PURE__ */ jsx13("li", { children: /* @__PURE__ */ jsx13("a", { href: `#${hrefFor(`/components/${entry.slug}`)}`, children: entry.name }) }, entry.slug)) }),
|
|
1459
|
+
inGroup.length > shown.length ? /* @__PURE__ */ jsxs10("p", { className: "hint", children: [
|
|
1460
|
+
"+ ",
|
|
1461
|
+
inGroup.length - shown.length,
|
|
1462
|
+
" more in this area"
|
|
1463
|
+
] }) : null
|
|
1464
|
+
] }, group);
|
|
1465
|
+
}) }),
|
|
1466
|
+
/* @__PURE__ */ jsx13("h2", { children: "How this works" }),
|
|
1467
|
+
/* @__PURE__ */ jsxs10("div", { className: "grid2", children: [
|
|
1468
|
+
/* @__PURE__ */ jsxs10("div", { className: "card", children: [
|
|
1469
|
+
/* @__PURE__ */ jsx13("h3", { children: "1 \xB7 The config points at the stories" }),
|
|
1470
|
+
/* @__PURE__ */ jsxs10("p", { children: [
|
|
1471
|
+
"The host app declares where its story files live (a package name or a path) and a glob inside it. The Vite plugin reads them, takes each module's ",
|
|
1472
|
+
/* @__PURE__ */ jsx13("code", { children: "title" }),
|
|
1473
|
+
" and exported stories, and builds the sidebar \u2014 including any group renames, so authored titles can stay as they are."
|
|
1474
|
+
] })
|
|
1475
|
+
] }),
|
|
1476
|
+
/* @__PURE__ */ jsxs10("div", { className: "card", children: [
|
|
1477
|
+
/* @__PURE__ */ jsx13("h3", { children: "2 \xB7 Examples are the story modules" }),
|
|
1478
|
+
/* @__PURE__ */ jsxs10("p", { children: [
|
|
1479
|
+
"Opening a component lazily imports the same module Storybook renders and evaluates it here: the meta's",
|
|
1480
|
+
" ",
|
|
1481
|
+
/* @__PURE__ */ jsx13("code", { children: "component" }),
|
|
1482
|
+
", merged ",
|
|
1483
|
+
/* @__PURE__ */ jsx13("code", { children: "args" }),
|
|
1484
|
+
", or the story's own ",
|
|
1485
|
+
/* @__PURE__ */ jsx13("code", { children: "render" }),
|
|
1486
|
+
". A design system gets a docs page without writing one."
|
|
1487
|
+
] })
|
|
1488
|
+
] }),
|
|
1489
|
+
/* @__PURE__ */ jsxs10("div", { className: "card", children: [
|
|
1490
|
+
/* @__PURE__ */ jsx13("h3", { children: "3 \xB7 API tables are argTypes" }),
|
|
1491
|
+
/* @__PURE__ */ jsxs10("p", { children: [
|
|
1492
|
+
"Each page's prop table is derived from the story meta's ",
|
|
1493
|
+
/* @__PURE__ */ jsx13("code", { children: "argTypes" }),
|
|
1494
|
+
" and default",
|
|
1495
|
+
" ",
|
|
1496
|
+
/* @__PURE__ */ jsx13("code", { children: "args" }),
|
|
1497
|
+
" at runtime. Add a control to a story and the table follows."
|
|
1498
|
+
] })
|
|
1499
|
+
] }),
|
|
1500
|
+
/* @__PURE__ */ jsxs10("div", { className: "card", children: [
|
|
1501
|
+
/* @__PURE__ */ jsx13("h3", { children: "4 \xB7 The chrome uses the system's tokens" }),
|
|
1502
|
+
/* @__PURE__ */ jsx13("p", { children: "Optional theme and token bridges map the engine's semantic roles to the design system's CSS variables and token module \u2014 which is why the theme toggle restyles this site through the system's own theme attribute." })
|
|
1503
|
+
] })
|
|
1504
|
+
] }),
|
|
1505
|
+
/* @__PURE__ */ jsx13("h2", { children: "Start here" }),
|
|
1506
|
+
/* @__PURE__ */ jsx13("ul", { children: startHere.map((entry) => /* @__PURE__ */ jsxs10("li", { children: [
|
|
1507
|
+
/* @__PURE__ */ jsx13("a", { href: `#${hrefFor(`/components/${entry.slug}`)}`, children: entry.name }),
|
|
1508
|
+
" \u2014 ",
|
|
1509
|
+
entry.stories.length,
|
|
1510
|
+
" stories"
|
|
1511
|
+
] }, entry.slug)) })
|
|
1512
|
+
] });
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
// src/pages/releases.tsx
|
|
1516
|
+
import { releases } from "virtual:storybook-docs/releases";
|
|
1517
|
+
import { Fragment as Fragment9, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1518
|
+
function ReleasesPage() {
|
|
1519
|
+
return /* @__PURE__ */ jsxs11(Fragment9, { children: [
|
|
1520
|
+
/* @__PURE__ */ jsx14("div", { className: "crumb", children: "Releases" }),
|
|
1521
|
+
/* @__PURE__ */ jsx14("h1", { children: "Releases" }),
|
|
1522
|
+
releases.version ? /* @__PURE__ */ jsxs11("p", { className: "lede", children: [
|
|
1523
|
+
"Current release ",
|
|
1524
|
+
/* @__PURE__ */ jsxs11("span", { className: "chip", children: [
|
|
1525
|
+
"v",
|
|
1526
|
+
releases.version
|
|
1527
|
+
] })
|
|
1528
|
+
] }) : null,
|
|
1529
|
+
releases.changelog ? /* @__PURE__ */ jsx14(MarkdownView, { markdown: releases.changelog }) : null
|
|
1530
|
+
] });
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
// src/search.tsx
|
|
1534
|
+
import { useEffect as useEffect6, useMemo as useMemo4, useRef as useRef4, useState as useState7 } from "react";
|
|
1535
|
+
import { catalog as catalog2 } from "virtual:storybook-docs/catalog";
|
|
1536
|
+
|
|
1537
|
+
// src/search-match.ts
|
|
1538
|
+
var MAX_COMPONENTS = 10;
|
|
1539
|
+
var MAX_STORIES_PER_COMPONENT = 2;
|
|
1540
|
+
function highlightSegments(text, needle) {
|
|
1541
|
+
const term = needle.trim().toLowerCase();
|
|
1542
|
+
const lower = text.toLowerCase();
|
|
1543
|
+
const start2 = term && lower.length === text.length ? lower.indexOf(term) : -1;
|
|
1544
|
+
if (start2 < 0) return [{ text, match: false }];
|
|
1545
|
+
const end = start2 + term.length;
|
|
1546
|
+
return [
|
|
1547
|
+
{ text: text.slice(0, start2), match: false },
|
|
1548
|
+
{ text: text.slice(start2, end), match: true },
|
|
1549
|
+
{ text: text.slice(end), match: false }
|
|
1550
|
+
].filter((segment) => segment.text);
|
|
1551
|
+
}
|
|
1552
|
+
function scoreEntry(entry, needle) {
|
|
1553
|
+
const name = entry.name.toLowerCase();
|
|
1554
|
+
if (name === needle) return 100;
|
|
1555
|
+
if (name.startsWith(needle)) return 80;
|
|
1556
|
+
if (name.includes(needle)) return 60;
|
|
1557
|
+
if (entry.group.toLowerCase().includes(needle)) return 40;
|
|
1558
|
+
if (entry.storybookTitle.toLowerCase().includes(needle)) return 30;
|
|
1559
|
+
return -1;
|
|
1560
|
+
}
|
|
1561
|
+
function searchCatalog(catalog4, query) {
|
|
1562
|
+
const needle = query.trim().toLowerCase();
|
|
1563
|
+
if (!needle) return [];
|
|
1564
|
+
return catalog4.map((entry) => {
|
|
1565
|
+
const stories = entry.stories.filter((story) => story.toLowerCase().includes(needle)).slice(0, MAX_STORIES_PER_COMPONENT);
|
|
1566
|
+
const score = scoreEntry(entry, needle);
|
|
1567
|
+
return { entry, stories, score: score >= 0 ? score : stories.length ? 20 : -1, componentHit: score >= 0 };
|
|
1568
|
+
}).filter((candidate) => candidate.score >= 0).sort((a, b) => b.score - a.score || a.entry.name.localeCompare(b.entry.name)).slice(0, MAX_COMPONENTS).flatMap(({ entry, stories, componentHit }) => [
|
|
1569
|
+
...componentHit ? [{ entry }] : [],
|
|
1570
|
+
...stories.map((story) => ({ entry, story }))
|
|
1571
|
+
]);
|
|
1572
|
+
}
|
|
1573
|
+
var rowKey = (row) => row.story ? `${row.entry.slug}--${row.story}` : row.entry.slug;
|
|
1574
|
+
var rowPath = (row) => `/components/${row.entry.slug}${row.story ? `?story=${encodeURIComponent(row.story)}` : ""}`;
|
|
1575
|
+
|
|
1576
|
+
// src/search.tsx
|
|
1577
|
+
import { Fragment as Fragment10, jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1578
|
+
function renderHighlighted(text, query) {
|
|
1579
|
+
const segments = highlightSegments(text, query);
|
|
1580
|
+
return segments.map(
|
|
1581
|
+
(segment, index) => segment.match ? /* @__PURE__ */ jsx15("mark", { children: segment.text }, index) : segment.text
|
|
1582
|
+
);
|
|
1583
|
+
}
|
|
1584
|
+
function SearchBox() {
|
|
1585
|
+
const [query, setQuery] = useState7("");
|
|
1586
|
+
const [open, setOpen] = useState7(false);
|
|
1587
|
+
const [active, setActive] = useState7(0);
|
|
1588
|
+
const inputRef = useRef4(null);
|
|
1589
|
+
const listId = "storybook-docs-search-results";
|
|
1590
|
+
const optionId = (key) => `${listId}-${key}`;
|
|
1591
|
+
const results = useMemo4(() => {
|
|
1592
|
+
return searchCatalog(catalog2, query);
|
|
1593
|
+
}, [query]);
|
|
1594
|
+
useEffect6(() => {
|
|
1595
|
+
setActive(0);
|
|
1596
|
+
}, [query]);
|
|
1597
|
+
useEffect6(() => {
|
|
1598
|
+
const onGlobalKeyDown = (event) => {
|
|
1599
|
+
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
|
|
1600
|
+
event.preventDefault();
|
|
1601
|
+
inputRef.current?.focus();
|
|
1602
|
+
inputRef.current?.select();
|
|
1603
|
+
setOpen(true);
|
|
1604
|
+
}
|
|
1605
|
+
};
|
|
1606
|
+
window.addEventListener("keydown", onGlobalKeyDown);
|
|
1607
|
+
return () => window.removeEventListener("keydown", onGlobalKeyDown);
|
|
1608
|
+
}, []);
|
|
1609
|
+
const go = (row) => {
|
|
1610
|
+
window.location.hash = hrefFor(rowPath(row));
|
|
1611
|
+
setOpen(false);
|
|
1612
|
+
setQuery("");
|
|
1613
|
+
inputRef.current?.blur();
|
|
1614
|
+
};
|
|
1615
|
+
const hasQuery = query.trim().length > 0;
|
|
1616
|
+
const hasResults = results.length > 0;
|
|
1617
|
+
const showDropdown = open && (hasResults || hasQuery);
|
|
1618
|
+
const activeRow = hasResults && results[active] ? results[active] : void 0;
|
|
1619
|
+
const activeOptionId = activeRow ? optionId(rowKey(activeRow)) : void 0;
|
|
1620
|
+
useEffect6(() => {
|
|
1621
|
+
if (showDropdown && activeOptionId) {
|
|
1622
|
+
const el = document.getElementById(activeOptionId);
|
|
1623
|
+
el?.scrollIntoView({ block: "nearest" });
|
|
1624
|
+
}
|
|
1625
|
+
}, [activeOptionId, showDropdown]);
|
|
1626
|
+
const onKeyDown = (event) => {
|
|
1627
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
1628
|
+
event.preventDefault();
|
|
1629
|
+
if (!open) {
|
|
1630
|
+
setOpen(true);
|
|
1631
|
+
return;
|
|
1632
|
+
}
|
|
1633
|
+
if (results.length === 0) return;
|
|
1634
|
+
setActive((current) => {
|
|
1635
|
+
const next = event.key === "ArrowDown" ? current + 1 : current - 1;
|
|
1636
|
+
return (next + results.length) % results.length;
|
|
1637
|
+
});
|
|
1638
|
+
return;
|
|
1639
|
+
}
|
|
1640
|
+
if (event.key === "Enter") {
|
|
1641
|
+
if (activeRow) {
|
|
1642
|
+
event.preventDefault();
|
|
1643
|
+
go(activeRow);
|
|
1644
|
+
}
|
|
1645
|
+
return;
|
|
1646
|
+
}
|
|
1647
|
+
if (event.key === "Escape") {
|
|
1648
|
+
event.preventDefault();
|
|
1649
|
+
setOpen(false);
|
|
1650
|
+
setQuery("");
|
|
1651
|
+
inputRef.current?.blur();
|
|
1652
|
+
}
|
|
1653
|
+
};
|
|
1654
|
+
return /* @__PURE__ */ jsxs12("div", { className: "search", children: [
|
|
1655
|
+
/* @__PURE__ */ jsx15(
|
|
1656
|
+
"input",
|
|
1657
|
+
{
|
|
1658
|
+
ref: inputRef,
|
|
1659
|
+
type: "text",
|
|
1660
|
+
role: "combobox",
|
|
1661
|
+
"aria-expanded": showDropdown,
|
|
1662
|
+
"aria-controls": hasResults ? listId : void 0,
|
|
1663
|
+
"aria-activedescendant": showDropdown ? activeOptionId : void 0,
|
|
1664
|
+
"aria-autocomplete": "list",
|
|
1665
|
+
"aria-label": `Search ${catalog2.length} components`,
|
|
1666
|
+
placeholder: `Search ${catalog2.length} components\u2026 \u2318K`,
|
|
1667
|
+
value: query,
|
|
1668
|
+
onChange: (event) => {
|
|
1669
|
+
setQuery(event.target.value);
|
|
1670
|
+
setOpen(true);
|
|
1671
|
+
},
|
|
1672
|
+
onFocus: () => setOpen(true),
|
|
1673
|
+
onBlur: () => window.setTimeout(() => setOpen(false), 150),
|
|
1674
|
+
onKeyDown
|
|
1675
|
+
}
|
|
1676
|
+
),
|
|
1677
|
+
showDropdown ? /* @__PURE__ */ jsxs12("div", { className: "search-dropdown", children: [
|
|
1678
|
+
hasResults ? /* @__PURE__ */ jsx15("ul", { id: listId, role: "listbox", "aria-label": "Components", className: "search-results", children: results.map((row, index) => {
|
|
1679
|
+
const key = rowKey(row);
|
|
1680
|
+
const optId = optionId(key);
|
|
1681
|
+
return /* @__PURE__ */ jsxs12(
|
|
1682
|
+
"li",
|
|
1683
|
+
{
|
|
1684
|
+
id: optId,
|
|
1685
|
+
role: "option",
|
|
1686
|
+
"aria-selected": index === active,
|
|
1687
|
+
onMouseEnter: () => {
|
|
1688
|
+
setActive(index);
|
|
1689
|
+
void row.entry.load();
|
|
1690
|
+
},
|
|
1691
|
+
onFocus: () => {
|
|
1692
|
+
setActive(index);
|
|
1693
|
+
void row.entry.load();
|
|
1694
|
+
},
|
|
1695
|
+
onMouseDown: (event) => {
|
|
1696
|
+
event.preventDefault();
|
|
1697
|
+
go(row);
|
|
1698
|
+
},
|
|
1699
|
+
children: [
|
|
1700
|
+
/* @__PURE__ */ jsxs12("span", { className: "search-result-main", children: [
|
|
1701
|
+
/* @__PURE__ */ jsx15("b", { className: "search-result-name", children: renderHighlighted(row.entry.name, query) }),
|
|
1702
|
+
row.story ? /* @__PURE__ */ jsxs12(Fragment10, { children: [
|
|
1703
|
+
/* @__PURE__ */ jsx15("span", { className: "search-result-sep", "aria-hidden": "true", children: " \u203A " }),
|
|
1704
|
+
/* @__PURE__ */ jsx15("span", { className: "search-result-story", children: renderHighlighted(row.story, query) })
|
|
1705
|
+
] }) : null
|
|
1706
|
+
] }),
|
|
1707
|
+
/* @__PURE__ */ jsx15("span", { className: "search-result-meta", children: row.story ? row.entry.group : `${row.entry.group} \xB7 ${row.entry.stories.length} stories` })
|
|
1708
|
+
]
|
|
1709
|
+
},
|
|
1710
|
+
key
|
|
1711
|
+
);
|
|
1712
|
+
}) }) : /* @__PURE__ */ jsxs12("div", { className: "search-empty", role: "status", children: [
|
|
1713
|
+
"No components match \u2018",
|
|
1714
|
+
query.trim(),
|
|
1715
|
+
"\u2019"
|
|
1716
|
+
] }),
|
|
1717
|
+
/* @__PURE__ */ jsxs12("div", { className: "search-footer", "aria-hidden": "true", children: [
|
|
1718
|
+
/* @__PURE__ */ jsxs12("span", { className: "search-footer-item", children: [
|
|
1719
|
+
/* @__PURE__ */ jsx15("kbd", { children: "\u2191" }),
|
|
1720
|
+
/* @__PURE__ */ jsx15("kbd", { children: "\u2193" }),
|
|
1721
|
+
" navigate"
|
|
1722
|
+
] }),
|
|
1723
|
+
/* @__PURE__ */ jsx15("span", { className: "search-footer-sep", children: "\xB7" }),
|
|
1724
|
+
/* @__PURE__ */ jsxs12("span", { className: "search-footer-item", children: [
|
|
1725
|
+
/* @__PURE__ */ jsx15("kbd", { children: "Enter" }),
|
|
1726
|
+
" open"
|
|
1727
|
+
] }),
|
|
1728
|
+
/* @__PURE__ */ jsx15("span", { className: "search-footer-sep", children: "\xB7" }),
|
|
1729
|
+
/* @__PURE__ */ jsxs12("span", { className: "search-footer-item", children: [
|
|
1730
|
+
/* @__PURE__ */ jsx15("kbd", { children: "Esc" }),
|
|
1731
|
+
" close"
|
|
1732
|
+
] })
|
|
1733
|
+
] })
|
|
1734
|
+
] }) : null
|
|
1735
|
+
] });
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
// src/app.tsx
|
|
1739
|
+
import { releases as releases2 } from "virtual:storybook-docs/releases";
|
|
1740
|
+
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1741
|
+
var routeHref = (path) => `#${hrefFor(path)}`;
|
|
1742
|
+
function parseRoute(hash) {
|
|
1743
|
+
const path = hashPath(hash).replace(new RegExp(`^#?\\/?${STORYBOOK_DOCS_BASE}`), "").replace(/^\/+/, "");
|
|
1744
|
+
if (path.startsWith("components/")) {
|
|
1745
|
+
const slug = path.slice("components/".length);
|
|
1746
|
+
if (catalog3.some((entry) => entry.slug === slug)) return { kind: "component", slug };
|
|
1747
|
+
}
|
|
1748
|
+
if (path === "releases" && releases2.changelog) return { kind: "releases" };
|
|
1749
|
+
if (path === "tokens/color") return { kind: "color" };
|
|
1750
|
+
if (path === "tokens/typography") return { kind: "typography" };
|
|
1751
|
+
if (path === "tokens/spacing") return { kind: "spacing" };
|
|
1752
|
+
if (path === "tokens/effects") return { kind: "effects" };
|
|
1753
|
+
return { kind: "overview" };
|
|
1754
|
+
}
|
|
1755
|
+
function DocsApp() {
|
|
1756
|
+
const [route, setRoute] = useState8(() => parseRoute(window.location.hash));
|
|
1757
|
+
const [mode, setMode] = useState8(theme.values?.[0] ?? "dark");
|
|
1758
|
+
const [navOpen, setNavOpen] = useState8(false);
|
|
1759
|
+
const headerRef = useRef5(null);
|
|
1760
|
+
const mainRef = useRef5(null);
|
|
1761
|
+
useEffect7(() => {
|
|
1762
|
+
const header = headerRef.current;
|
|
1763
|
+
if (!header) return;
|
|
1764
|
+
const root = document.documentElement;
|
|
1765
|
+
const previousHeight = root.style.getPropertyValue("--sd-header-height");
|
|
1766
|
+
const measure = () => root.style.setProperty("--sd-header-height", `${header.getBoundingClientRect().height}px`);
|
|
1767
|
+
measure();
|
|
1768
|
+
const observer = new ResizeObserver(measure);
|
|
1769
|
+
observer.observe(header);
|
|
1770
|
+
return () => {
|
|
1771
|
+
observer.disconnect();
|
|
1772
|
+
if (previousHeight) root.style.setProperty("--sd-header-height", previousHeight);
|
|
1773
|
+
else root.style.removeProperty("--sd-header-height");
|
|
1774
|
+
};
|
|
1775
|
+
}, []);
|
|
1776
|
+
useEffect7(() => {
|
|
1777
|
+
const onHash = () => {
|
|
1778
|
+
setRoute(parseRoute(window.location.hash));
|
|
1779
|
+
setNavOpen(false);
|
|
1780
|
+
window.scrollTo(0, 0);
|
|
1781
|
+
mainRef.current?.focus({ preventScroll: true });
|
|
1782
|
+
};
|
|
1783
|
+
window.addEventListener("hashchange", onHash);
|
|
1784
|
+
return () => window.removeEventListener("hashchange", onHash);
|
|
1785
|
+
}, []);
|
|
1786
|
+
useEffect7(() => {
|
|
1787
|
+
document.documentElement.setAttribute(theme.attribute ?? "data-theme", mode);
|
|
1788
|
+
}, [mode]);
|
|
1789
|
+
const [darkMode, lightMode] = theme.values ?? ["dark", "light"];
|
|
1790
|
+
const activeSlug = route.kind === "component" ? route.slug : null;
|
|
1791
|
+
const foundations = [
|
|
1792
|
+
...pages.color ? [{ href: routeHref(`/tokens/color`), label: "Color", kind: "color" }] : [],
|
|
1793
|
+
...pages.typography ? [{ href: routeHref(`/tokens/typography`), label: "Typography", kind: "typography" }] : [],
|
|
1794
|
+
...pages.spacing ? [{ href: routeHref(`/tokens/spacing`), label: "Spacing & shape", kind: "spacing" }] : [],
|
|
1795
|
+
...pages.effects ? [{ href: routeHref(`/tokens/effects`), label: "Elevation & motion", kind: "effects" }] : []
|
|
1796
|
+
];
|
|
1797
|
+
return /* @__PURE__ */ jsxs13("div", { className: route.kind === "overview" ? "app" : "app has-toc", children: [
|
|
1798
|
+
/* @__PURE__ */ jsx16(
|
|
1799
|
+
"a",
|
|
1800
|
+
{
|
|
1801
|
+
className: "skip",
|
|
1802
|
+
href: "#main",
|
|
1803
|
+
onClick: (event) => {
|
|
1804
|
+
event.preventDefault();
|
|
1805
|
+
mainRef.current?.focus();
|
|
1806
|
+
},
|
|
1807
|
+
children: "Skip to content"
|
|
1808
|
+
}
|
|
1809
|
+
),
|
|
1810
|
+
/* @__PURE__ */ jsxs13("header", { className: "top", ref: headerRef, children: [
|
|
1811
|
+
/* @__PURE__ */ jsx16(
|
|
1812
|
+
"button",
|
|
1813
|
+
{
|
|
1814
|
+
type: "button",
|
|
1815
|
+
className: "tool nav-toggle",
|
|
1816
|
+
"aria-expanded": navOpen,
|
|
1817
|
+
"aria-controls": "docs-nav",
|
|
1818
|
+
onClick: () => setNavOpen(!navOpen),
|
|
1819
|
+
children: "Menu"
|
|
1820
|
+
}
|
|
1821
|
+
),
|
|
1822
|
+
/* @__PURE__ */ jsxs13("a", { className: "brand-link", href: routeHref("/"), children: [
|
|
1823
|
+
/* @__PURE__ */ jsx16("span", { className: "mark", "aria-hidden": "true", children: site2.mark ?? site2.title.slice(0, 1).toUpperCase() }),
|
|
1824
|
+
/* @__PURE__ */ jsx16("span", { className: "brand", children: site2.title })
|
|
1825
|
+
] }),
|
|
1826
|
+
/* @__PURE__ */ jsxs13("span", { className: "chip", children: [
|
|
1827
|
+
"docs",
|
|
1828
|
+
releases2.version ? ` \xB7 v${releases2.version}` : ""
|
|
1829
|
+
] }),
|
|
1830
|
+
/* @__PURE__ */ jsx16(SearchBox, {}),
|
|
1831
|
+
/* @__PURE__ */ jsx16("span", { className: "spacer" }),
|
|
1832
|
+
/* @__PURE__ */ jsx16(
|
|
1833
|
+
"button",
|
|
1834
|
+
{
|
|
1835
|
+
type: "button",
|
|
1836
|
+
className: "tool",
|
|
1837
|
+
"aria-label": `Switch to ${mode === darkMode ? lightMode : darkMode} theme`,
|
|
1838
|
+
onClick: () => setMode(mode === darkMode ? lightMode : darkMode),
|
|
1839
|
+
children: mode === darkMode ? lightMode : darkMode
|
|
1840
|
+
}
|
|
1841
|
+
),
|
|
1842
|
+
(site2.links ?? []).map((link) => /* @__PURE__ */ jsxs13("a", { className: "tool", href: link.href, children: [
|
|
1843
|
+
link.label,
|
|
1844
|
+
" ",
|
|
1845
|
+
/* @__PURE__ */ jsx16("span", { "aria-hidden": "true", children: "\u2197" })
|
|
1846
|
+
] }, link.href))
|
|
1847
|
+
] }),
|
|
1848
|
+
/* @__PURE__ */ jsxs13("nav", { id: "docs-nav", className: navOpen ? "nav open" : "nav", "aria-label": "Documentation", children: [
|
|
1849
|
+
/* @__PURE__ */ jsx16("a", { href: routeHref("/"), className: route.kind === "overview" ? "on" : void 0, "aria-current": route.kind === "overview" ? "page" : void 0, children: "Overview" }),
|
|
1850
|
+
releases2.changelog ? /* @__PURE__ */ jsxs13(
|
|
1851
|
+
"a",
|
|
1852
|
+
{
|
|
1853
|
+
href: routeHref("/releases"),
|
|
1854
|
+
className: route.kind === "releases" ? "on" : void 0,
|
|
1855
|
+
"aria-current": route.kind === "releases" ? "page" : void 0,
|
|
1856
|
+
children: [
|
|
1857
|
+
"Releases",
|
|
1858
|
+
releases2.version ? /* @__PURE__ */ jsxs13("span", { className: "nav-count", children: [
|
|
1859
|
+
"v",
|
|
1860
|
+
releases2.version
|
|
1861
|
+
] }) : null
|
|
1862
|
+
]
|
|
1863
|
+
}
|
|
1864
|
+
) : null,
|
|
1865
|
+
foundations.length > 0 ? /* @__PURE__ */ jsxs13("div", { role: "group", "aria-labelledby": "nav-grp-foundations", children: [
|
|
1866
|
+
/* @__PURE__ */ jsx16("div", { className: "grp", id: "nav-grp-foundations", children: "Foundations" }),
|
|
1867
|
+
foundations.map((item) => /* @__PURE__ */ jsx16(
|
|
1868
|
+
"a",
|
|
1869
|
+
{
|
|
1870
|
+
href: item.href,
|
|
1871
|
+
className: route.kind === item.kind ? "on" : void 0,
|
|
1872
|
+
"aria-current": route.kind === item.kind ? "page" : void 0,
|
|
1873
|
+
children: item.label
|
|
1874
|
+
},
|
|
1875
|
+
item.href
|
|
1876
|
+
))
|
|
1877
|
+
] }) : null,
|
|
1878
|
+
groups2.map((group, index) => /* @__PURE__ */ jsxs13("div", { role: "group", "aria-labelledby": `nav-grp-${index}`, children: [
|
|
1879
|
+
/* @__PURE__ */ jsx16("div", { className: "grp", id: `nav-grp-${index}`, children: group }),
|
|
1880
|
+
catalog3.filter((entry) => entry.group === group).map((entry) => /* @__PURE__ */ jsx16(
|
|
1881
|
+
"a",
|
|
1882
|
+
{
|
|
1883
|
+
href: routeHref(`/components/${entry.slug}`),
|
|
1884
|
+
className: activeSlug === entry.slug ? "on" : void 0,
|
|
1885
|
+
"aria-current": activeSlug === entry.slug ? "page" : void 0,
|
|
1886
|
+
onMouseEnter: () => void entry.load(),
|
|
1887
|
+
onFocus: () => void entry.load(),
|
|
1888
|
+
children: entry.name
|
|
1889
|
+
},
|
|
1890
|
+
entry.slug
|
|
1891
|
+
))
|
|
1892
|
+
] }, group)),
|
|
1893
|
+
/* @__PURE__ */ jsxs13("div", { className: "nav-note", children: [
|
|
1894
|
+
"navigation, examples and API tables generated from ",
|
|
1895
|
+
stats2.components,
|
|
1896
|
+
" story files \xB7 ",
|
|
1897
|
+
stats2.stories,
|
|
1898
|
+
" stories"
|
|
1899
|
+
] })
|
|
1900
|
+
] }),
|
|
1901
|
+
/* @__PURE__ */ jsx16("main", { id: "main", className: "main", tabIndex: -1, ref: mainRef, children: route.kind === "component" ? /* @__PURE__ */ jsx16(ComponentPage, { entry: catalog3.find((entry) => entry.slug === route.slug) }) : route.kind === "color" ? /* @__PURE__ */ jsx16(ColorPage, {}) : route.kind === "typography" ? /* @__PURE__ */ jsx16(TypePage, {}) : route.kind === "spacing" ? /* @__PURE__ */ jsx16(SpacingPage, {}) : route.kind === "effects" ? /* @__PURE__ */ jsx16(EffectsPage, {}) : route.kind === "releases" ? /* @__PURE__ */ jsx16(ReleasesPage, {}) : /* @__PURE__ */ jsx16(OverviewPage, {}) }),
|
|
1902
|
+
route.kind !== "overview" ? /* @__PURE__ */ jsx16(PageRail, { pageKey: activeSlug ?? route.kind }) : null
|
|
1903
|
+
] });
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
// src/start.tsx
|
|
1907
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1908
|
+
function start() {
|
|
1909
|
+
let container = document.getElementById("root");
|
|
1910
|
+
if (!container) {
|
|
1911
|
+
container = document.createElement("div");
|
|
1912
|
+
container.id = "root";
|
|
1913
|
+
document.body.append(container);
|
|
1914
|
+
}
|
|
1915
|
+
const attribute = theme2.attribute ?? "data-theme";
|
|
1916
|
+
document.documentElement.setAttribute(attribute, theme2.values?.[0] ?? "dark");
|
|
1917
|
+
if (themeCss) {
|
|
1918
|
+
const style = document.createElement("style");
|
|
1919
|
+
style.dataset.storybookDocs = "theme";
|
|
1920
|
+
style.textContent = themeCss;
|
|
1921
|
+
document.head.append(style);
|
|
1922
|
+
}
|
|
1923
|
+
document.title = site3.title;
|
|
1924
|
+
createRoot(container).render(/* @__PURE__ */ jsx17(StrictMode, { children: createElement3(DocsApp) }));
|
|
1925
|
+
}
|
|
1926
|
+
export {
|
|
1927
|
+
ComponentDemo,
|
|
1928
|
+
start
|
|
1929
|
+
};
|
|
1930
|
+
import './index.css';
|