@jfrader/storybook-docs 0.0.0-stage → 0.4.4

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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +138 -2
  3. package/dist/app.d.ts +1 -0
  4. package/dist/base.d.ts +3 -0
  5. package/dist/build/catalog.d.ts +20 -0
  6. package/dist/build/code.d.ts +2 -0
  7. package/dist/build/global-styles.d.ts +1 -0
  8. package/dist/build/guidance.d.ts +4 -0
  9. package/dist/build/module-ids.d.ts +2 -0
  10. package/dist/build/props.d.ts +10 -0
  11. package/dist/build/releases.d.ts +7 -0
  12. package/dist/build/site.d.ts +2 -0
  13. package/dist/build/storybook-test.d.ts +2 -0
  14. package/dist/build/tokens.d.ts +2 -0
  15. package/dist/code.d.ts +16 -0
  16. package/dist/component-demo.d.ts +23 -0
  17. package/dist/config.d.ts +98 -0
  18. package/dist/controls.d.ts +49 -0
  19. package/dist/css.d.ts +1 -0
  20. package/dist/guidance-model.d.ts +74 -0
  21. package/dist/guidance.d.ts +9 -0
  22. package/dist/index.css +420 -0
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.js +1971 -0
  25. package/dist/pages/component-page.d.ts +4 -0
  26. package/dist/pages/foundations-color.d.ts +3 -0
  27. package/dist/pages/foundations-effects.d.ts +3 -0
  28. package/dist/pages/foundations-spacing.d.ts +3 -0
  29. package/dist/pages/foundations-type.d.ts +3 -0
  30. package/dist/pages/overview.d.ts +3 -0
  31. package/dist/pages/releases.d.ts +3 -0
  32. package/dist/prop-docs.d.ts +20 -0
  33. package/dist/props.d.ts +4 -0
  34. package/dist/scan.d.ts +19 -0
  35. package/dist/search-match.d.ts +21 -0
  36. package/dist/search.d.ts +5 -0
  37. package/dist/sections.d.ts +52 -0
  38. package/dist/skeleton.d.ts +11 -0
  39. package/dist/start.d.ts +4 -0
  40. package/dist/story-view.d.ts +20 -0
  41. package/dist/styles.css +685 -0
  42. package/dist/toc.d.ts +19 -0
  43. package/dist/virtual.d.ts +42 -0
  44. package/dist/vite-plugin.d.ts +10 -0
  45. package/dist/vite-plugin.js +697 -0
  46. package/docs/CONFIG.md +287 -0
  47. package/docs/RELEASING.md +153 -0
  48. package/package.json +75 -3
package/dist/index.js ADDED
@@ -0,0 +1,1971 @@
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 } 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 useRailFollow(ref, ready = true) {
535
+ useEffect3(() => {
536
+ const element = ref.current;
537
+ if (!element) return;
538
+ let frame = 0;
539
+ let applied = 0;
540
+ const limit = () => window.innerHeight - (Number.parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--sd-header-height")) || 56) - 20;
541
+ const apply = () => {
542
+ frame = 0;
543
+ const bottomInDocument = element.getBoundingClientRect().bottom + window.scrollY - applied;
544
+ const crossing = bottomInDocument - limit();
545
+ const next = Math.max(0, window.scrollY - crossing);
546
+ if (next !== applied) {
547
+ applied = next;
548
+ element.style.setProperty("--sd-rail-follow", `${next}px`);
549
+ }
550
+ };
551
+ const schedule = () => {
552
+ if (!frame) frame = requestAnimationFrame(apply);
553
+ };
554
+ apply();
555
+ window.addEventListener("scroll", schedule, { passive: true });
556
+ window.addEventListener("resize", schedule);
557
+ const observer = new ResizeObserver(schedule);
558
+ observer.observe(element);
559
+ return () => {
560
+ window.removeEventListener("scroll", schedule);
561
+ window.removeEventListener("resize", schedule);
562
+ observer.disconnect();
563
+ if (frame) cancelAnimationFrame(frame);
564
+ };
565
+ }, [ready, ref]);
566
+ }
567
+ function scanPage(root, pageKey) {
568
+ const used = /* @__PURE__ */ new Set();
569
+ const unique = (prefix, text) => {
570
+ const base = `${prefix}-${slugify(text) || "x"}`;
571
+ let id = base;
572
+ for (let n = 2; used.has(id); n += 1) id = `${base}-${n}`;
573
+ used.add(id);
574
+ return id;
575
+ };
576
+ const sections = [];
577
+ const frames = [];
578
+ const subHeadings = [...root.querySelectorAll("h3")].filter(
579
+ (heading) => heading.textContent && !heading.closest(".story-lane") && !heading.closest(".frame")
580
+ );
581
+ root.querySelectorAll("h2").forEach((heading) => {
582
+ if (!heading.textContent) return;
583
+ if (heading.closest(".story-lane") || heading.closest(".frame")) return;
584
+ heading.id ||= unique("section", heading.textContent);
585
+ heading.dataset.toc = "";
586
+ const section = heading.parentElement?.tagName === "SECTION" ? heading.parentElement : null;
587
+ const stories = [];
588
+ section?.querySelectorAll(":scope > .frame").forEach((frame) => {
589
+ const header = frame.querySelector(":scope > header");
590
+ const name = header?.querySelector("span")?.textContent;
591
+ if (!header || !name) return;
592
+ const story = frame.dataset.story ?? name;
593
+ frame.id ||= unique("story", story);
594
+ frame.dataset.toc = "";
595
+ const item = { id: frame.id, name, story, element: frame };
596
+ stories.push(item);
597
+ frames.push(item);
598
+ });
599
+ const following = [...root.querySelectorAll("h2, h3")];
600
+ const start2 = following.indexOf(heading);
601
+ const end = following.findIndex((candidate, index) => index > start2 && candidate.tagName === "H2");
602
+ const subs = following.slice(start2 + 1, end === -1 ? void 0 : end).filter((candidate) => candidate.tagName === "H3" && subHeadings.includes(candidate)).map((candidate) => {
603
+ candidate.id ||= unique("sub", candidate.textContent ?? "");
604
+ candidate.dataset.toc = "";
605
+ return { id: candidate.id, title: candidate.textContent ?? "", element: candidate };
606
+ });
607
+ sections.push({ id: heading.id, title: heading.textContent, element: section ?? heading, heading, stories, subs });
608
+ });
609
+ const counts = /* @__PURE__ */ new Map();
610
+ for (const item of frames) counts.set(item.name, (counts.get(item.name) ?? 0) + 1);
611
+ for (const item of frames) {
612
+ if ((counts.get(item.name) ?? 0) > 1 && item.story && item.story !== item.name) {
613
+ item.name = `${item.name} \xB7 ${item.story}`;
614
+ }
615
+ }
616
+ return { pageKey, sections, frames };
617
+ }
618
+ 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(";")}`;
619
+ var prefersReducedMotion = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches;
620
+ function scrollToElement(element) {
621
+ element.scrollIntoView({ behavior: prefersReducedMotion() ? "auto" : "smooth", block: "start" });
622
+ let ticks = SETTLE_TICKS;
623
+ let lastY = window.scrollY;
624
+ const settle = () => {
625
+ if (!element.isConnected || ticks === 0) return;
626
+ ticks -= 1;
627
+ const moving = window.scrollY !== lastY;
628
+ lastY = window.scrollY;
629
+ if (!moving && Math.abs(element.getBoundingClientRect().top - SCROLL_OFFSET_PX) > SETTLE_TOLERANCE_PX) {
630
+ element.scrollIntoView({ behavior: "auto", block: "start" });
631
+ lastY = window.scrollY;
632
+ }
633
+ window.setTimeout(settle, SETTLE_TICK_MS);
634
+ };
635
+ window.setTimeout(settle, SETTLE_TICK_MS);
636
+ }
637
+ function useActiveIds(scan) {
638
+ const [active, setActive] = useState3({ section: null, story: null });
639
+ useEffect3(() => {
640
+ if (!scan) return;
641
+ const targets = [...scan.sections.map((s) => s.element), ...scan.frames.map((f) => f.element)];
642
+ const order = new Map(targets.map((element, index) => [element, index]));
643
+ const visible = /* @__PURE__ */ new Set();
644
+ const observer = new IntersectionObserver(
645
+ (entries) => {
646
+ for (const entry of entries) entry.isIntersecting ? visible.add(entry.target) : visible.delete(entry.target);
647
+ const inView = [...visible].sort((a, b) => order.get(a) - order.get(b));
648
+ const section = scan.sections.find((s) => inView.includes(s.element));
649
+ const story = scan.frames.find((f) => inView.includes(f.element));
650
+ if (section || story) setActive((previous) => ({ section: section?.id ?? previous.section, story: story?.id ?? null }));
651
+ },
652
+ { rootMargin: ACTIVE_ROOT_MARGIN }
653
+ );
654
+ targets.forEach((element) => observer.observe(element));
655
+ return () => observer.disconnect();
656
+ }, [scan]);
657
+ return active;
658
+ }
659
+ function PageRail({ pageKey }) {
660
+ const [scan, setScan] = useState3(null);
661
+ const pageKeyRef = useRef2(pageKey);
662
+ pageKeyRef.current = pageKey;
663
+ const [target, setTarget] = useState3(() => storyFromHash(window.location.hash));
664
+ const flashed = useRef2(null);
665
+ useEffect3(() => {
666
+ const main = document.querySelector(".main");
667
+ if (!main) return;
668
+ let frame = 0;
669
+ const rescan = () => {
670
+ frame = 0;
671
+ setScan((previous) => {
672
+ const next = scanPage(main, pageKeyRef.current);
673
+ return previous && signature(previous) === signature(next) ? previous : next;
674
+ });
675
+ };
676
+ const schedule = () => {
677
+ if (!frame) frame = requestAnimationFrame(rescan);
678
+ };
679
+ const observer = new MutationObserver(schedule);
680
+ observer.observe(main, { childList: true, subtree: true });
681
+ schedule();
682
+ return () => {
683
+ observer.disconnect();
684
+ cancelAnimationFrame(frame);
685
+ };
686
+ }, [pageKey]);
687
+ useEffect3(() => {
688
+ const onHash = () => setTarget(storyFromHash(window.location.hash));
689
+ window.addEventListener("hashchange", onHash);
690
+ return () => window.removeEventListener("hashchange", onHash);
691
+ }, []);
692
+ useEffect3(() => {
693
+ if (!target || !scan || scan.pageKey !== pageKey) return;
694
+ 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());
695
+ if (!match) return;
696
+ scrollToElement(match.element);
697
+ flashed.current?.classList.remove("toc-flash");
698
+ match.element.classList.add("toc-flash");
699
+ flashed.current = match.element;
700
+ window.setTimeout(() => match.element.classList.remove("toc-flash"), FLASH_MS);
701
+ setTarget(null);
702
+ }, [target, scan, pageKey]);
703
+ const railRef = useRef2(null);
704
+ useRailFollow(railRef, scan !== null);
705
+ const active = useActiveIds(scan);
706
+ const go = useCallback((element) => scrollToElement(element), []);
707
+ if (!scan) return null;
708
+ return /* @__PURE__ */ jsx5(Fragment, { children: scan.sections.length > 0 ? /* @__PURE__ */ jsxs3("aside", { className: "toc", "aria-label": "On this page", ref: railRef, children: [
709
+ /* @__PURE__ */ jsx5("div", { className: "toc-title", children: "On this page" }),
710
+ /* @__PURE__ */ jsx5("ul", { children: scan.sections.map((section) => /* @__PURE__ */ jsxs3("li", { children: [
711
+ /* @__PURE__ */ jsx5(
712
+ "button",
713
+ {
714
+ type: "button",
715
+ className: "toc-link",
716
+ "aria-current": active.section === section.id ? "location" : void 0,
717
+ onClick: () => go(section.heading),
718
+ children: section.title
719
+ }
720
+ ),
721
+ 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,
722
+ section.stories.length > 0 ? /* @__PURE__ */ jsx5("ul", { children: section.stories.map((story) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5(
723
+ "button",
724
+ {
725
+ type: "button",
726
+ className: "toc-link toc-story",
727
+ "aria-current": active.story === story.id ? "location" : void 0,
728
+ onClick: () => go(story.element),
729
+ children: story.name
730
+ }
731
+ ) }, story.id)) }) : null
732
+ ] }, section.id)) })
733
+ ] }) : null });
734
+ }
735
+
736
+ // src/component-demo.tsx
737
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
738
+ var COPIED_MS = 1800;
739
+ async function copyText(text) {
740
+ try {
741
+ await navigator.clipboard.writeText(text);
742
+ return true;
743
+ } catch {
744
+ const area = document.createElement("textarea");
745
+ area.value = text;
746
+ area.setAttribute("readonly", "");
747
+ area.className = "toc-clipboard";
748
+ document.body.append(area);
749
+ area.select();
750
+ const copied = document.execCommand("copy");
751
+ area.remove();
752
+ return copied;
753
+ }
754
+ }
755
+ function CopyLink({ name, story }) {
756
+ const [copied, setCopied] = useState4(false);
757
+ useEffect4(() => {
758
+ if (!copied) return;
759
+ const timer = window.setTimeout(() => setCopied(false), COPIED_MS);
760
+ return () => window.clearTimeout(timer);
761
+ }, [copied]);
762
+ return /* @__PURE__ */ jsxs4(Fragment2, { children: [
763
+ /* @__PURE__ */ jsx6(
764
+ "button",
765
+ {
766
+ type: "button",
767
+ className: "toc-copy",
768
+ "aria-label": `Copy link to ${name}`,
769
+ onClick: async () => setCopied(await copyText(storyLink(window.location, story))),
770
+ children: copied ? "Copied" : "Copy link"
771
+ }
772
+ ),
773
+ /* @__PURE__ */ jsx6("span", { role: "status", className: "toc-sr", children: copied ? `Link to ${name} copied` : "" })
774
+ ] });
775
+ }
776
+ function ControlInput({ control, value, onChange }) {
777
+ const id = useId();
778
+ const [invalid, setInvalid] = useState4(false);
779
+ useEffect4(() => setInvalid(false), [value]);
780
+ return /* @__PURE__ */ jsxs4("div", { className: "sd-control", children: [
781
+ /* @__PURE__ */ jsx6("label", { htmlFor: id, children: control.name }),
782
+ control.type === "select" ? /* @__PURE__ */ jsxs4(
783
+ "select",
784
+ {
785
+ id,
786
+ value: String(control.options?.findIndex((option) => Object.is(option, value)) ?? -1),
787
+ onChange: (event) => onChange(control.options?.[Number(event.target.value)]),
788
+ children: [
789
+ /* @__PURE__ */ jsx6("option", { value: "-1", disabled: true, children: "\u2014" }),
790
+ control.options?.map((option, index) => /* @__PURE__ */ jsx6("option", { value: index, children: String(option) }, index))
791
+ ]
792
+ }
793
+ ) : 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: [
794
+ /* @__PURE__ */ jsx6(
795
+ "textarea",
796
+ {
797
+ id,
798
+ defaultValue: JSON.stringify(value, null, 2) ?? "",
799
+ "aria-invalid": invalid,
800
+ "aria-describedby": invalid ? `${id}-error` : void 0,
801
+ onBlur: (event) => {
802
+ try {
803
+ onChange(JSON.parse(event.target.value));
804
+ setInvalid(false);
805
+ } catch {
806
+ setInvalid(true);
807
+ }
808
+ }
809
+ },
810
+ JSON.stringify(value)
811
+ ),
812
+ invalid ? /* @__PURE__ */ jsx6("span", { id: `${id}-error`, role: "status", children: "Enter valid JSON." }) : null
813
+ ] }) : /* @__PURE__ */ jsx6(
814
+ "input",
815
+ {
816
+ id,
817
+ type: control.type === "number" || control.type === "range" ? control.type : "text",
818
+ min: control.min,
819
+ max: control.max,
820
+ step: control.step ?? (control.type === "number" ? "any" : void 0),
821
+ value: typeof value === "string" || typeof value === "number" ? value : "",
822
+ onChange: (event) => onChange(control.type === "number" || control.type === "range" ? event.target.value === "" ? void 0 : event.target.valueAsNumber : event.target.value)
823
+ }
824
+ )
825
+ ] });
826
+ }
827
+ function hasHorizontalOverflow({ scrollWidth, clientWidth }) {
828
+ return scrollWidth > clientWidth;
829
+ }
830
+ function ComponentDemo({
831
+ story,
832
+ storyName,
833
+ authoredStory,
834
+ skipped,
835
+ controls,
836
+ args,
837
+ unavailable,
838
+ changed,
839
+ onControlChange,
840
+ onReset,
841
+ storyLayout,
842
+ snippet,
843
+ codeLanguage,
844
+ children
845
+ }) {
846
+ const [codeOpen, setCodeOpen] = useState4(false);
847
+ const controlsLabelId = useId();
848
+ const canvasRef = useRef3(null);
849
+ const [scrollable, setScrollable] = useState4(false);
850
+ useEffect4(() => {
851
+ const canvas = canvasRef.current;
852
+ const content = canvas?.firstElementChild;
853
+ if (!canvas || !content) return;
854
+ const measure = () => setScrollable(hasHorizontalOverflow(canvas));
855
+ let frame = 0;
856
+ const scheduleMeasure = () => {
857
+ cancelAnimationFrame(frame);
858
+ frame = requestAnimationFrame(measure);
859
+ };
860
+ measure();
861
+ const resize = new ResizeObserver(scheduleMeasure);
862
+ resize.observe(canvas);
863
+ resize.observe(content);
864
+ const mutations = new MutationObserver(scheduleMeasure);
865
+ mutations.observe(content, { childList: true, subtree: true, attributes: true, characterData: true });
866
+ return () => {
867
+ resize.disconnect();
868
+ mutations.disconnect();
869
+ cancelAnimationFrame(frame);
870
+ };
871
+ }, [children, story]);
872
+ const [laneLayout, setLaneLayout] = useState4(storyLayout);
873
+ const laneRef = useCallback2(
874
+ (node) => {
875
+ if (!node) return;
876
+ const content = node.firstElementChild;
877
+ if (!(content instanceof HTMLElement)) return;
878
+ setLaneLayout(storyLayout !== "fullscreen" && /^inline/.test(getComputedStyle(content).display) ? "inline" : storyLayout);
879
+ },
880
+ [storyLayout]
881
+ );
882
+ return /* @__PURE__ */ jsxs4("div", { className: "frame", "data-story": story, children: [
883
+ /* @__PURE__ */ jsxs4("header", { children: [
884
+ /* @__PURE__ */ jsx6("span", { children: storyName }),
885
+ /* @__PURE__ */ jsx6("span", { "data-toc-slot": "", children: /* @__PURE__ */ jsx6(CopyLink, { name: storyName, story }) })
886
+ ] }),
887
+ authoredStory ? /* @__PURE__ */ jsx6("p", { className: "story-blurb", children: authoredStory }) : null,
888
+ skipped.length ? /* @__PURE__ */ jsxs4("p", { className: "sd-controls-note", children: [
889
+ "Not run here: ",
890
+ skipped.join(", "),
891
+ ". See it in Storybook."
892
+ ] }) : null,
893
+ unavailable ? /* @__PURE__ */ jsx6("p", { className: "sd-controls-note", children: unavailable }) : /* @__PURE__ */ jsxs4("div", { className: "sd-controls", role: "group", "aria-labelledby": controlsLabelId, children: [
894
+ /* @__PURE__ */ jsxs4("p", { className: "sd-controls-label", id: controlsLabelId, children: [
895
+ "Controls for ",
896
+ storyName
897
+ ] }),
898
+ /* @__PURE__ */ jsxs4("div", { className: "sd-controls-fields", children: [
899
+ controls.map((control) => /* @__PURE__ */ jsx6(
900
+ ControlInput,
901
+ {
902
+ control,
903
+ value: args[control.name],
904
+ onChange: (value) => onControlChange(control.name, value)
905
+ },
906
+ control.name
907
+ )),
908
+ /* @__PURE__ */ jsx6("button", { className: "sd-controls-reset", type: "button", disabled: !changed, onClick: onReset, children: "Reset" })
909
+ ] })
910
+ ] }),
911
+ /* @__PURE__ */ jsx6(
912
+ "div",
913
+ {
914
+ className: "shot",
915
+ "data-layout": storyLayout,
916
+ ref: canvasRef,
917
+ tabIndex: scrollable ? 0 : void 0,
918
+ role: scrollable ? "region" : void 0,
919
+ "aria-label": scrollable ? storyName : void 0,
920
+ children: /* @__PURE__ */ jsx6(LazySection, { children: /* @__PURE__ */ jsx6("div", { className: "story-lane", "data-layout": laneLayout, ref: laneRef, children }) })
921
+ }
922
+ ),
923
+ /* @__PURE__ */ jsxs4("details", { className: "code-toggle", onToggle: (event) => setCodeOpen(event.currentTarget.open), children: [
924
+ /* @__PURE__ */ jsx6("summary", { children: /* @__PURE__ */ jsx6("span", { className: "sd-demo-code-actions", children: "Code" }) }),
925
+ 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
926
+ ] })
927
+ ] });
928
+ }
929
+
930
+ // src/controls.tsx
931
+ import { storySource } from "virtual:storybook-docs/catalog";
932
+ import { jsx as jsx7 } from "react/jsx-runtime";
933
+ function parseDefault(value) {
934
+ const text = value.trim();
935
+ if (text === "undefined" || text === "") return void 0;
936
+ try {
937
+ return JSON.parse(text);
938
+ } catch {
939
+ if (text.startsWith("'") && text.endsWith("'") && !text.slice(1, -1).includes("'")) return text.slice(1, -1);
940
+ }
941
+ return void 0;
942
+ }
943
+ function defaultsFromProps(props = []) {
944
+ const defaults = {};
945
+ for (const prop of Array.isArray(props) ? props : []) {
946
+ const declared = prop?.defaultValue;
947
+ const text = typeof declared === "string" ? declared : declared?.value;
948
+ if (typeof text === "string") {
949
+ const value = parseDefault(text);
950
+ if (value !== void 0) defaults[prop.name] = value;
951
+ }
952
+ }
953
+ return defaults;
954
+ }
955
+ function getStoryControls(meta, story, componentDefaults = {}) {
956
+ const args = { ...componentDefaults, ...meta.args, ...story.args };
957
+ const controls = [];
958
+ for (const [name, raw] of Object.entries(mergeAnnotations(meta.argTypes, story.argTypes))) {
959
+ const definition = raw;
960
+ const control = definition.control;
961
+ if (control === false || control === null) continue;
962
+ const type = typeof control === "string" ? control : control && typeof control === "object" && "type" in control ? control.type : void 0;
963
+ if (type === "boolean" || type === "number" || type === "text" || type === "string") {
964
+ controls.push({ name, type: type === "string" ? "text" : type });
965
+ } else if ((type === "select" || type === "radio" || type === "inline-radio") && Array.isArray(definition.options) && definition.options.length > 0) {
966
+ controls.push({ name, type: "select", options: definition.options });
967
+ } else if (type === "range") {
968
+ const settings = control;
969
+ controls.push({ name, type, min: settings.min, max: settings.max, step: settings.step });
970
+ } else if (type === "object") {
971
+ controls.push({ name, type });
972
+ } else {
973
+ continue;
974
+ }
975
+ if (!Object.hasOwn(args, name) && Object.hasOwn(definition, "defaultValue")) args[name] = definition.defaultValue;
976
+ }
977
+ return {
978
+ args,
979
+ controls,
980
+ unavailable: controls.length === 0 ? "No controls." : null
981
+ };
982
+ }
983
+ function ControlledStoryFrame({ module, story, componentName, componentDefaults }) {
984
+ const meta = module.default ?? {};
985
+ const definition = module[story] ?? {};
986
+ const { args: defaults, controls, unavailable } = getStoryControls(meta, definition, componentDefaults);
987
+ const [edits, setEdits] = useState5({});
988
+ const args = { ...defaults, ...edits };
989
+ const changed = Object.entries(edits).some(([name, value]) => !Object.is(value, defaults[name]));
990
+ const requestedLayout = definition.parameters?.layout ?? meta.parameters?.layout;
991
+ const storyLayout = requestedLayout === "centered" || requestedLayout === "fullscreen" ? requestedLayout : "padded";
992
+ const docsOverride = definition.parameters?.docs;
993
+ const docsMeta = meta.parameters?.docs;
994
+ const authoredCode = docsOverride?.source?.code ?? docsMeta?.source?.code;
995
+ const authoredStory = docsOverride?.description?.story ?? docsMeta?.description?.story;
996
+ const storyName = definition.name ?? story;
997
+ const skipped = ["loaders", "beforeEach"].filter((key) => meta[key] || definition[key]);
998
+ if (definition.parameters?.viewport ?? meta.parameters?.viewport) skipped.push("viewport");
999
+ const codeLanguage = docsOverride?.source?.language ?? docsMeta?.source?.language ?? "tsx";
1000
+ const snippet = buildUsageSnippet({
1001
+ componentName,
1002
+ from: storySource,
1003
+ args: { ...meta.args, ...definition.args, ...edits },
1004
+ source: authoredCode,
1005
+ // A story name is not a component name: only a part-qualified name (the rare `Dialog.Content`
1006
+ // story) is worth using as the JSX tag, otherwise the component's own name is the honest one.
1007
+ jsxName: storyName.includes(".") ? storyName : void 0,
1008
+ component: meta.component
1009
+ });
1010
+ return /* @__PURE__ */ jsx7(
1011
+ ComponentDemo,
1012
+ {
1013
+ story,
1014
+ storyName,
1015
+ authoredStory,
1016
+ skipped,
1017
+ controls,
1018
+ args,
1019
+ unavailable,
1020
+ changed,
1021
+ storyLayout,
1022
+ snippet,
1023
+ codeLanguage,
1024
+ onControlChange: (name, value) => setEdits((current) => ({ ...current, [name]: value })),
1025
+ onReset: () => setEdits({}),
1026
+ children: /* @__PURE__ */ jsx7(StoryView, { module, story, overrides: edits })
1027
+ }
1028
+ );
1029
+ }
1030
+
1031
+ // src/props.ts
1032
+ import { useEffect as useEffect5, useState as useState6 } from "react";
1033
+ import { loadProps } from "virtual:storybook-docs/props";
1034
+ function useProps(slug) {
1035
+ const [components, setComponents] = useState6(null);
1036
+ useEffect5(() => {
1037
+ let alive = true;
1038
+ setComponents(null);
1039
+ loadProps(slug).then((module) => {
1040
+ if (alive) setComponents(module.components);
1041
+ }).catch(() => {
1042
+ if (alive) setComponents([]);
1043
+ });
1044
+ return () => {
1045
+ alive = false;
1046
+ };
1047
+ }, [slug]);
1048
+ return components;
1049
+ }
1050
+
1051
+ // src/pages/component-page.tsx
1052
+ import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1053
+ function formatValue(value) {
1054
+ if (value === void 0) return "\u2014";
1055
+ if (typeof value === "function") return "fn()";
1056
+ if (typeof value === "string") return value.length > 40 ? `${value.slice(0, 37)}\u2026` : value;
1057
+ if (typeof value === "object" && value !== null) {
1058
+ if ("$$typeof" in value) return "<ReactNode>";
1059
+ if (Array.isArray(value)) return `[${value.length}]`;
1060
+ return "{\u2026}";
1061
+ }
1062
+ return String(value);
1063
+ }
1064
+ function TableFrame({ label, children }) {
1065
+ return /* @__PURE__ */ jsx8("div", { className: "table-scroll", role: "region", "aria-label": label, tabIndex: 0, children: /* @__PURE__ */ jsxs5("table", { children: [
1066
+ /* @__PURE__ */ jsx8("caption", { className: "sr-only", children: label }),
1067
+ children
1068
+ ] }) });
1069
+ }
1070
+ function PropNotes({ prop }) {
1071
+ return /* @__PURE__ */ jsxs5(Fragment3, { children: [
1072
+ prop.description ? /* @__PURE__ */ jsx8(MarkdownView, { markdown: prop.description }) : null,
1073
+ prop.tags?.map((tag, index) => /* @__PURE__ */ jsxs5("div", { children: [
1074
+ /* @__PURE__ */ jsx8("strong", { children: tag.name === "deprecated" ? "Deprecated" : tag.name === "since" ? "Since" : "Example" }),
1075
+ tag.name === "example" ? /* @__PURE__ */ jsx8("pre", { children: /* @__PURE__ */ jsx8("code", { children: tag.text }) }) : tag.text ? /* @__PURE__ */ jsx8(MarkdownView, { markdown: tag.text }) : null
1076
+ ] }, `${tag.name}:${index}`)),
1077
+ prop.inheritedFrom ? /* @__PURE__ */ jsxs5("small", { children: [
1078
+ "Inherited from ",
1079
+ /* @__PURE__ */ jsx8("code", { children: prop.inheritedFrom })
1080
+ ] }) : null,
1081
+ !prop.description && !prop.tags?.length && !prop.inheritedFrom ? "\u2014" : null
1082
+ ] });
1083
+ }
1084
+ function PropRows({ props }) {
1085
+ return props.map((prop) => /* @__PURE__ */ jsxs5("tr", { children: [
1086
+ /* @__PURE__ */ jsxs5("th", { scope: "row", children: [
1087
+ /* @__PURE__ */ jsx8("code", { children: prop.name }),
1088
+ prop.required ? /* @__PURE__ */ jsx8("span", { className: "req", children: "required" }) : null
1089
+ ] }),
1090
+ /* @__PURE__ */ jsxs5("td", { children: [
1091
+ /* @__PURE__ */ jsx8("code", { className: "type", children: prop.typeUnavailable ? "Not resolved" : prop.type }),
1092
+ prop.members?.length ? /* @__PURE__ */ jsxs5("details", { children: [
1093
+ /* @__PURE__ */ jsx8("summary", { children: prop.name === "slotProps" ? "Slots" : "Fields" }),
1094
+ /* @__PURE__ */ jsx8("dl", { children: prop.members.map((member) => /* @__PURE__ */ jsxs5("div", { children: [
1095
+ /* @__PURE__ */ jsxs5("dt", { children: [
1096
+ /* @__PURE__ */ jsx8("code", { children: member.name }),
1097
+ member.required ? " (required)" : ""
1098
+ ] }),
1099
+ /* @__PURE__ */ jsxs5("dd", { children: [
1100
+ /* @__PURE__ */ jsx8("code", { children: member.type }),
1101
+ /* @__PURE__ */ jsx8(PropNotes, { prop: member })
1102
+ ] })
1103
+ ] }, member.name)) })
1104
+ ] }) : null
1105
+ ] }),
1106
+ /* @__PURE__ */ jsx8("td", { children: /* @__PURE__ */ jsx8("code", { children: prop.defaultValue === "undefined" ? "\u2014" : prop.defaultValue ?? "\u2014" }) }),
1107
+ /* @__PURE__ */ jsx8("td", { children: /* @__PURE__ */ jsx8(PropNotes, { prop }) })
1108
+ ] }, prop.name));
1109
+ }
1110
+ function PropsTable({
1111
+ components,
1112
+ argTypes,
1113
+ defaultArgs
1114
+ }) {
1115
+ if (components === null) {
1116
+ return /* @__PURE__ */ jsx8("div", { className: "skeleton-page", "aria-busy": "true", children: /* @__PURE__ */ jsx8(Skeleton, { lines: 4, height: 14 }) });
1117
+ }
1118
+ if (components && components.length > 0) {
1119
+ const single = components.length === 1;
1120
+ return /* @__PURE__ */ jsx8(Fragment3, { children: components.map((component) => /* @__PURE__ */ jsxs5("section", { children: [
1121
+ !single ? /* @__PURE__ */ jsx8("h3", { children: component.name }) : null,
1122
+ component.native ? /* @__PURE__ */ jsxs5("p", { className: "hint", children: [
1123
+ "Native element: ",
1124
+ /* @__PURE__ */ jsxs5("code", { children: [
1125
+ "<",
1126
+ component.native,
1127
+ ">"
1128
+ ] }),
1129
+ "."
1130
+ ] }) : null,
1131
+ component.props.some((prop) => !prop.inheritedFrom) ? /* @__PURE__ */ jsxs5(TableFrame, { label: `${component.name} props`, children: [
1132
+ /* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsxs5("tr", { children: [
1133
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Prop" }),
1134
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Type" }),
1135
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Default" }),
1136
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Notes" })
1137
+ ] }) }),
1138
+ /* @__PURE__ */ jsx8("tbody", { children: /* @__PURE__ */ jsx8(PropRows, { props: component.props.filter((prop) => !prop.inheritedFrom) }) })
1139
+ ] }) : /* @__PURE__ */ jsx8("p", { children: "No component-specific props." }),
1140
+ component.props.some((prop) => prop.inheritedFrom) ? /* @__PURE__ */ jsxs5("details", { children: [
1141
+ /* @__PURE__ */ jsxs5("summary", { children: [
1142
+ "Inherited props (",
1143
+ component.props.filter((prop) => prop.inheritedFrom).length,
1144
+ ")"
1145
+ ] }),
1146
+ /* @__PURE__ */ jsxs5(TableFrame, { label: `${component.name} inherited props`, children: [
1147
+ /* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsxs5("tr", { children: [
1148
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Prop" }),
1149
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Type" }),
1150
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Default" }),
1151
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Notes" })
1152
+ ] }) }),
1153
+ /* @__PURE__ */ jsx8("tbody", { children: /* @__PURE__ */ jsx8(PropRows, { props: component.props.filter((prop) => prop.inheritedFrom) }) })
1154
+ ] })
1155
+ ] }) : null
1156
+ ] }, component.name)) });
1157
+ }
1158
+ if (Object.keys(argTypes).length > 0) {
1159
+ return /* @__PURE__ */ jsxs5(TableFrame, { label: "Props", children: [
1160
+ /* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsxs5("tr", { children: [
1161
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Prop" }),
1162
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Control" }),
1163
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Options" }),
1164
+ /* @__PURE__ */ jsx8("th", { scope: "col", children: "Default" })
1165
+ ] }) }),
1166
+ /* @__PURE__ */ jsx8("tbody", { children: Object.entries(argTypes).map(([prop, definition]) => /* @__PURE__ */ jsxs5("tr", { children: [
1167
+ /* @__PURE__ */ jsx8("th", { scope: "row", children: /* @__PURE__ */ jsx8("code", { children: prop }) }),
1168
+ /* @__PURE__ */ jsx8("td", { children: formatValue(definition.control) }),
1169
+ /* @__PURE__ */ jsx8("td", { children: Array.isArray(definition.options) ? definition.options.map((option) => formatValue(option)).join(" | ") : "\u2014" }),
1170
+ /* @__PURE__ */ jsx8("td", { children: formatValue(defaultArgs[prop]) })
1171
+ ] }, prop)) })
1172
+ ] });
1173
+ }
1174
+ return /* @__PURE__ */ jsx8("p", { children: "No props." });
1175
+ }
1176
+ function ComponentPage({ entry }) {
1177
+ const { module, error } = useStoryModule(entry);
1178
+ const props = useProps(entry.slug);
1179
+ const meta = module?.default ?? {};
1180
+ const argTypes = meta.argTypes ?? {};
1181
+ const defaultArgs = meta.args ?? {};
1182
+ const description = meta.parameters?.docs?.description?.component;
1183
+ const usage = meta.parameters?.docs?.usage;
1184
+ const visibleStories = useMemo3(() => {
1185
+ if (!module) return entry.stories;
1186
+ const metaTags = (meta.tags ?? []).map(String);
1187
+ return entry.stories.filter((name) => {
1188
+ const storyTags = (module[name]?.tags ?? []).map(String);
1189
+ return ![...metaTags, ...storyTags].includes("!autodocs");
1190
+ });
1191
+ }, [entry.stories, meta, module]);
1192
+ const componentDefaults = useMemo3(
1193
+ () => defaultsFromProps(props?.find((component) => component.name === entry.name)?.props ?? []),
1194
+ [props, entry.name]
1195
+ );
1196
+ const example = selectExample(visibleStories.map((name) => ({
1197
+ name,
1198
+ description: module?.[name]?.parameters?.docs?.description?.story,
1199
+ args: { ...defaultArgs, ...module?.[name]?.args },
1200
+ play: module?.[name]?.play
1201
+ })), Object.keys(meta.component ?? {}), props === null ? null : componentDefaults);
1202
+ const sections = useMemo3(() => sectionStories(visibleStories.filter((story) => story !== example)), [visibleStories, example]);
1203
+ const defaultStory = module?.[visibleStories.find((name) => /^default$/i.test(name)) ?? example ?? ""] ?? {};
1204
+ const fallbackSource = visibleStories.map((name) => module?.[name]?.parameters?.docs?.source).find((source2) => source2?.code?.trim());
1205
+ const source = {
1206
+ code: defaultStory.parameters?.docs?.source?.code ?? meta.parameters?.docs?.source?.code ?? fallbackSource?.code,
1207
+ language: defaultStory.parameters?.docs?.source?.language ?? meta.parameters?.docs?.source?.language ?? fallbackSource?.language
1208
+ };
1209
+ const codeLanguage = source?.language ?? "tsx";
1210
+ const snippet = useMemo3(
1211
+ () => entry.hasComponent ? buildUsageSnippet({
1212
+ componentName: entry.name,
1213
+ from: storySource2,
1214
+ component: meta.component,
1215
+ source: source?.code,
1216
+ args: { ...defaultArgs, ...defaultStory.args }
1217
+ }) : null,
1218
+ [source?.code, entry.name, entry.hasComponent, defaultArgs, defaultStory.args, meta.component]
1219
+ );
1220
+ const propCount = props ? props.reduce((total, component) => total + component.props.filter((prop) => !prop.inheritedFrom).length, 0) : Object.keys(argTypes).length;
1221
+ return /* @__PURE__ */ jsxs5(Fragment3, { children: [
1222
+ /* @__PURE__ */ jsxs5("div", { className: "crumb", children: [
1223
+ entry.group,
1224
+ " / ",
1225
+ entry.name
1226
+ ] }),
1227
+ /* @__PURE__ */ jsx8("h1", { children: entry.name }),
1228
+ /* @__PURE__ */ jsxs5("div", { className: "summary-row", children: [
1229
+ /* @__PURE__ */ jsxs5("span", { className: "chip", children: [
1230
+ module ? visibleStories.length : entry.stories.length,
1231
+ " stories"
1232
+ ] }),
1233
+ /* @__PURE__ */ jsxs5("span", { className: "chip", children: [
1234
+ propCount,
1235
+ " props"
1236
+ ] })
1237
+ ] }),
1238
+ /* @__PURE__ */ jsx8("p", { className: "lede", children: description ?? `${entry.name} \u2014 every story in ${entry.storybookTitle} is rendered below, in sections.` }),
1239
+ error ? /* @__PURE__ */ jsxs5("div", { className: "story-failed", children: [
1240
+ "Could not load the story module: ",
1241
+ error
1242
+ ] }) : null,
1243
+ !module && !error ? /* @__PURE__ */ jsxs5("div", { className: "skeleton-page", "aria-busy": "true", children: [
1244
+ /* @__PURE__ */ jsx8(Skeleton, { width: 260, height: 16 }),
1245
+ /* @__PURE__ */ jsx8(Skeleton, { height: 150 }),
1246
+ /* @__PURE__ */ jsx8(Skeleton, { height: 150 })
1247
+ ] }) : null,
1248
+ module ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
1249
+ example ? /* @__PURE__ */ jsx8(ControlledStoryFrame, { module, story: example, componentName: entry.name, componentDefaults }, `${entry.slug}:${example}`) : null,
1250
+ entry.hasComponent ? /* @__PURE__ */ jsx8("h2", { children: "Usage" }) : null,
1251
+ snippet ? /* @__PURE__ */ jsx8(CodeBlock, { code: snippet, language: codeLanguage }) : entry.hasComponent ? /* @__PURE__ */ jsx8("p", { children: "No usage code is authored for this component." }) : null,
1252
+ usage ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
1253
+ entry.hasComponent ? null : /* @__PURE__ */ jsx8("h2", { children: "Usage" }),
1254
+ /* @__PURE__ */ jsx8(MarkdownView, { markdown: usage })
1255
+ ] }) : null,
1256
+ /* @__PURE__ */ jsx8(Guidance, { slug: entry.slug }),
1257
+ sections.map((section) => /* @__PURE__ */ jsxs5("section", { children: [
1258
+ /* @__PURE__ */ jsx8("h2", { children: section.title }),
1259
+ section.stories.map((story) => /* @__PURE__ */ jsx8(ControlledStoryFrame, { module, story, componentName: entry.name, componentDefaults }, `${entry.slug}:${story}`))
1260
+ ] }, section.title))
1261
+ ] }) : null,
1262
+ /* @__PURE__ */ jsx8("h2", { children: "Props" }),
1263
+ /* @__PURE__ */ jsx8(PropsTable, { components: props, argTypes, defaultArgs }),
1264
+ /* @__PURE__ */ jsx8("h2", { children: "Notes" }),
1265
+ /* @__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." })
1266
+ ] });
1267
+ }
1268
+
1269
+ // src/pages/foundations-color.tsx
1270
+ import { vars } from "virtual:storybook-docs/tokens";
1271
+ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
1272
+ var colorSection = vars.color;
1273
+ var roles = Object.entries(colorSection ?? {}).sort(([a], [b]) => a.localeCompare(b));
1274
+ function ColorPage() {
1275
+ return /* @__PURE__ */ jsxs6(Fragment4, { children: [
1276
+ /* @__PURE__ */ jsx9("div", { className: "crumb", children: "Foundations / Color" }),
1277
+ /* @__PURE__ */ jsx9("h1", { children: "Color" }),
1278
+ /* @__PURE__ */ jsx9("p", { className: "lede", children: "The design system's colour roles." }),
1279
+ /* @__PURE__ */ jsx9("h2", { children: "Roles" }),
1280
+ /* @__PURE__ */ jsx9("div", { className: "swatches", children: roles.map(([role, reference]) => /* @__PURE__ */ jsxs6("div", { className: "sw", children: [
1281
+ /* @__PURE__ */ jsx9("div", { className: "c", style: { background: reference } }),
1282
+ /* @__PURE__ */ jsxs6("div", { className: "n", children: [
1283
+ /* @__PURE__ */ jsx9("b", { children: role }),
1284
+ reference
1285
+ ] })
1286
+ ] }, role)) }),
1287
+ /* @__PURE__ */ jsx9("h2", { children: "Rules" }),
1288
+ /* @__PURE__ */ jsxs6("ul", { children: [
1289
+ /* @__PURE__ */ jsx9("li", { children: "Components read token roles; the application decides the theme (an attribute on the root, or a scoped theme wrapper)." }),
1290
+ /* @__PURE__ */ jsx9("li", { children: "Control boundaries hold \u22653:1 against both the page and the control interior (WCAG 1.4.11)." }),
1291
+ /* @__PURE__ */ jsx9("li", { children: "Raw values live in the token source only \u2014 this page is where they are allowed to be visible." }),
1292
+ /* @__PURE__ */ jsx9("li", { children: "State is never signalled by color alone; tones pair with glyphs, text or outlines." })
1293
+ ] })
1294
+ ] });
1295
+ }
1296
+
1297
+ // src/pages/foundations-effects.tsx
1298
+ import { vars as vars2 } from "virtual:storybook-docs/tokens";
1299
+ import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
1300
+ var token = vars2;
1301
+ var shadow = Object.entries(token.shadow ?? {});
1302
+ var motion = token.motion ?? {};
1303
+ var duration = Object.entries(motion.duration ?? {});
1304
+ var easing = Object.entries(motion.ease ?? motion.easing ?? {});
1305
+ function EffectsPage() {
1306
+ return /* @__PURE__ */ jsxs7(Fragment5, { children: [
1307
+ /* @__PURE__ */ jsx10("div", { className: "crumb", children: "Foundations / Elevation & motion" }),
1308
+ /* @__PURE__ */ jsx10("h1", { children: "Elevation & motion" }),
1309
+ /* @__PURE__ */ jsx10("p", { className: "lede", children: "Shadow roles and motion timings." }),
1310
+ shadow.length > 0 ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
1311
+ /* @__PURE__ */ jsx10("h2", { children: "Elevation" }),
1312
+ /* @__PURE__ */ jsx10("div", { className: "shadow-row", children: shadow.map(([name, reference]) => /* @__PURE__ */ jsxs7("div", { className: "shadow-cell", children: [
1313
+ /* @__PURE__ */ jsx10("span", { className: "shadow-box", style: { boxShadow: reference } }),
1314
+ /* @__PURE__ */ jsxs7("span", { className: "meta", children: [
1315
+ name,
1316
+ " \xB7 ",
1317
+ reference
1318
+ ] })
1319
+ ] }, name)) })
1320
+ ] }) : null,
1321
+ duration.length > 0 ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
1322
+ /* @__PURE__ */ jsx10("h2", { children: "Durations" }),
1323
+ /* @__PURE__ */ jsx10("div", { className: "scale-rows", children: duration.map(([name, reference]) => /* @__PURE__ */ jsxs7("div", { className: "space-row", children: [
1324
+ /* @__PURE__ */ jsxs7("span", { className: "meta", children: [
1325
+ name,
1326
+ " \xB7 ",
1327
+ reference
1328
+ ] }),
1329
+ /* @__PURE__ */ jsx10("span", { className: "motion-demo", style: { animationDuration: reference } })
1330
+ ] }, name)) })
1331
+ ] }) : null,
1332
+ easing.length > 0 ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
1333
+ /* @__PURE__ */ jsx10("h2", { children: "Easing" }),
1334
+ /* @__PURE__ */ jsx10("div", { className: "scale-rows", children: easing.map(([name, reference]) => /* @__PURE__ */ jsxs7("div", { className: "space-row", children: [
1335
+ /* @__PURE__ */ jsxs7("span", { className: "meta", children: [
1336
+ name,
1337
+ " \xB7 ",
1338
+ reference
1339
+ ] }),
1340
+ /* @__PURE__ */ jsx10("code", { children: reference })
1341
+ ] }, name)) })
1342
+ ] }) : null,
1343
+ /* @__PURE__ */ jsx10("h2", { children: "Rules" }),
1344
+ /* @__PURE__ */ jsxs7("ul", { children: [
1345
+ /* @__PURE__ */ jsx10("li", { children: "Motion is a hint, never a requirement: every animation needs a reduced-motion branch that still completes the lifecycle." }),
1346
+ /* @__PURE__ */ jsxs7("li", { children: [
1347
+ "Transitions list the properties they animate \u2014 never ",
1348
+ /* @__PURE__ */ jsx10("code", { children: "transition: all" }),
1349
+ "."
1350
+ ] }),
1351
+ /* @__PURE__ */ jsx10("li", { children: "Elevation encodes layering, not decoration: overlays sit above content, and the shadow role says how far." })
1352
+ ] })
1353
+ ] });
1354
+ }
1355
+
1356
+ // src/pages/foundations-spacing.tsx
1357
+ import { vars as vars3 } from "virtual:storybook-docs/tokens";
1358
+ import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
1359
+ var token2 = vars3;
1360
+ var space = Object.entries(token2.space ?? {});
1361
+ var radius = Object.entries(token2.radius ?? {});
1362
+ var sizes = Object.entries(token2.size ?? {});
1363
+ function SpacingPage() {
1364
+ return /* @__PURE__ */ jsxs8(Fragment6, { children: [
1365
+ /* @__PURE__ */ jsx11("div", { className: "crumb", children: "Foundations / Spacing & shape" }),
1366
+ /* @__PURE__ */ jsx11("h1", { children: "Spacing & shape" }),
1367
+ /* @__PURE__ */ jsx11("p", { className: "lede", children: "The space scale, corner radii and fixed sizes." }),
1368
+ space.length > 0 ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
1369
+ /* @__PURE__ */ jsx11("h2", { children: "Space scale" }),
1370
+ /* @__PURE__ */ jsx11("div", { className: "scale-rows", children: space.map(([name, reference]) => /* @__PURE__ */ jsxs8("div", { className: "space-row", children: [
1371
+ /* @__PURE__ */ jsxs8("span", { className: "meta", children: [
1372
+ name,
1373
+ " \xB7 ",
1374
+ reference
1375
+ ] }),
1376
+ /* @__PURE__ */ jsx11("span", { className: "bar", style: { width: reference, background: "var(--sd-accent)" } }),
1377
+ /* @__PURE__ */ jsx11("span", { className: "bar-outline", style: { width: reference } })
1378
+ ] }, name)) })
1379
+ ] }) : /* @__PURE__ */ jsx11("p", { children: "No space tokens were found in the configured token module." }),
1380
+ radius.length > 0 ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
1381
+ /* @__PURE__ */ jsx11("h2", { children: "Radii" }),
1382
+ /* @__PURE__ */ jsx11("div", { className: "radius-row", children: radius.map(([name, reference]) => /* @__PURE__ */ jsxs8("div", { className: "radius-cell", children: [
1383
+ /* @__PURE__ */ jsx11("span", { className: "radius-box", style: { borderRadius: reference } }),
1384
+ /* @__PURE__ */ jsxs8("span", { className: "meta", children: [
1385
+ name,
1386
+ " \xB7 ",
1387
+ reference
1388
+ ] })
1389
+ ] }, name)) })
1390
+ ] }) : null,
1391
+ sizes.length > 0 ? /* @__PURE__ */ jsxs8(Fragment6, { children: [
1392
+ /* @__PURE__ */ jsx11("h2", { children: "Sizes" }),
1393
+ /* @__PURE__ */ jsx11("div", { className: "scale-rows", children: sizes.map(([name, reference]) => /* @__PURE__ */ jsxs8("div", { className: "space-row", children: [
1394
+ /* @__PURE__ */ jsxs8("span", { className: "meta", children: [
1395
+ name,
1396
+ " \xB7 ",
1397
+ reference
1398
+ ] }),
1399
+ /* @__PURE__ */ jsx11("span", { className: "bar-outline", style: { width: reference } })
1400
+ ] }, name)) })
1401
+ ] }) : null,
1402
+ /* @__PURE__ */ jsx11("h2", { children: "Rules" }),
1403
+ /* @__PURE__ */ jsxs8("ul", { children: [
1404
+ /* @__PURE__ */ jsx11("li", { children: "Spacing between siblings comes from the scale; arbitrary pixel gaps are a smell." }),
1405
+ /* @__PURE__ */ jsx11("li", { children: "Radii follow the token roles so dense and roomy surfaces stay consistent." }),
1406
+ /* @__PURE__ */ jsx11("li", { children: "Fixed sizes exist for hit targets \u2014 interactive controls stay at or above the minimum target size." })
1407
+ ] })
1408
+ ] });
1409
+ }
1410
+
1411
+ // src/pages/foundations-type.tsx
1412
+ import { vars as vars4 } from "virtual:storybook-docs/tokens";
1413
+ import { Fragment as Fragment7, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
1414
+ var token3 = vars4;
1415
+ var sizes2 = Object.entries(token3.textSize ?? {});
1416
+ var weights = Object.entries(token3.fontWeight ?? {});
1417
+ var families = Object.entries(token3.font ?? {});
1418
+ function TypePage() {
1419
+ return /* @__PURE__ */ jsxs9(Fragment7, { children: [
1420
+ /* @__PURE__ */ jsx12("div", { className: "crumb", children: "Foundations / Typography" }),
1421
+ /* @__PURE__ */ jsx12("h1", { children: "Typography" }),
1422
+ /* @__PURE__ */ jsx12("p", { className: "lede", children: "The type scale, weights and families." }),
1423
+ families.length > 0 ? /* @__PURE__ */ jsxs9(Fragment7, { children: [
1424
+ /* @__PURE__ */ jsx12("h2", { children: "Family" }),
1425
+ families.map(([name, reference]) => /* @__PURE__ */ jsxs9("div", { className: "scale-row", children: [
1426
+ /* @__PURE__ */ jsxs9("span", { className: "meta", children: [
1427
+ name,
1428
+ " \xB7 ",
1429
+ reference
1430
+ ] }),
1431
+ /* @__PURE__ */ jsx12("span", { style: { fontFamily: reference, fontSize: "20px" }, children: "The quick brown fox jumps over the lazy dog" })
1432
+ ] }, name))
1433
+ ] }) : null,
1434
+ /* @__PURE__ */ jsx12("h2", { children: "Scale" }),
1435
+ sizes2.length > 0 ? sizes2.map(([name, reference]) => /* @__PURE__ */ jsxs9("div", { className: "scale-row", children: [
1436
+ /* @__PURE__ */ jsxs9("span", { className: "meta", children: [
1437
+ name,
1438
+ " \xB7 ",
1439
+ reference
1440
+ ] }),
1441
+ /* @__PURE__ */ jsx12("span", { style: { fontSize: reference }, children: "Save changes \xB7 0123456789" })
1442
+ ] }, name)) : /* @__PURE__ */ jsx12("p", { children: "No text-size tokens were found in the configured token module." }),
1443
+ weights.length > 0 ? /* @__PURE__ */ jsxs9(Fragment7, { children: [
1444
+ /* @__PURE__ */ jsx12("h2", { children: "Weights" }),
1445
+ weights.map(([name, reference]) => /* @__PURE__ */ jsxs9("div", { className: "scale-row", children: [
1446
+ /* @__PURE__ */ jsxs9("span", { className: "meta", children: [
1447
+ name,
1448
+ " \xB7 ",
1449
+ reference
1450
+ ] }),
1451
+ /* @__PURE__ */ jsx12("span", { style: { fontWeight: reference, fontSize: "18px" }, children: "Design system documentation" })
1452
+ ] }, name))
1453
+ ] }) : null,
1454
+ /* @__PURE__ */ jsx12("h2", { children: "Rules" }),
1455
+ /* @__PURE__ */ jsxs9("ul", { children: [
1456
+ /* @__PURE__ */ jsx12("li", { children: "Sizes and line-heights come from tokens; components never set raw font sizes." }),
1457
+ /* @__PURE__ */ jsx12("li", { children: "Numbers that update live use tabular figures so they do not jitter." })
1458
+ ] })
1459
+ ] });
1460
+ }
1461
+
1462
+ // src/pages/overview.tsx
1463
+ import { catalog, groups, stats } from "virtual:storybook-docs/catalog";
1464
+ import { site } from "virtual:storybook-docs/site";
1465
+
1466
+ // src/base.ts
1467
+ var STORYBOOK_DOCS_BASE = (() => {
1468
+ const globalBase = globalThis.__STORYBOOK_DOCS_BASE__;
1469
+ if (globalBase) return globalBase.replace(/\/$/, "");
1470
+ const { pathname } = window.location;
1471
+ return pathname === "/" || pathname.endsWith(".html") ? "" : pathname.replace(/\/$/, "");
1472
+ })();
1473
+ var hrefFor = (path) => `${STORYBOOK_DOCS_BASE}${path}`;
1474
+
1475
+ // src/pages/overview.tsx
1476
+ import { Fragment as Fragment8, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1477
+ function OverviewPage() {
1478
+ const startHere = catalog.slice(0, 6);
1479
+ return /* @__PURE__ */ jsxs10(Fragment8, { children: [
1480
+ /* @__PURE__ */ jsx13("div", { className: "crumb", children: "Overview" }),
1481
+ /* @__PURE__ */ jsx13("h1", { children: site.title }),
1482
+ site.tagline ? /* @__PURE__ */ jsx13("p", { className: "lede", children: site.tagline }) : null,
1483
+ /* @__PURE__ */ jsx13(Guidance, { slug: "index" }),
1484
+ /* @__PURE__ */ jsxs10("div", { className: "tiles", children: [
1485
+ /* @__PURE__ */ jsxs10("div", { className: "card tile", children: [
1486
+ /* @__PURE__ */ jsx13("div", { className: "num", children: stats.components }),
1487
+ /* @__PURE__ */ jsx13("b", { children: "Components" })
1488
+ ] }),
1489
+ /* @__PURE__ */ jsxs10("div", { className: "card tile", children: [
1490
+ /* @__PURE__ */ jsx13("div", { className: "num", children: stats.stories }),
1491
+ /* @__PURE__ */ jsx13("b", { children: "Stories" })
1492
+ ] })
1493
+ ] }),
1494
+ /* @__PURE__ */ jsx13("h2", { children: "Browse by area" }),
1495
+ /* @__PURE__ */ jsx13("div", { className: "group-grid", children: groups.map((group) => {
1496
+ const inGroup = catalog.filter((entry) => entry.group === group);
1497
+ const shown = inGroup.slice(0, 6);
1498
+ return /* @__PURE__ */ jsxs10("div", { className: "card group-card", children: [
1499
+ /* @__PURE__ */ jsxs10("h3", { children: [
1500
+ group,
1501
+ " ",
1502
+ /* @__PURE__ */ jsx13("span", { className: "count", children: inGroup.length })
1503
+ ] }),
1504
+ /* @__PURE__ */ jsx13("ul", { children: shown.map((entry) => /* @__PURE__ */ jsx13("li", { children: /* @__PURE__ */ jsx13("a", { href: `#${hrefFor(`/components/${entry.slug}`)}`, children: entry.name }) }, entry.slug)) }),
1505
+ inGroup.length > shown.length ? /* @__PURE__ */ jsxs10("p", { className: "hint", children: [
1506
+ "+ ",
1507
+ inGroup.length - shown.length,
1508
+ " more in this area"
1509
+ ] }) : null
1510
+ ] }, group);
1511
+ }) }),
1512
+ /* @__PURE__ */ jsx13("h2", { children: "How this works" }),
1513
+ /* @__PURE__ */ jsxs10("div", { className: "grid2", children: [
1514
+ /* @__PURE__ */ jsxs10("div", { className: "card", children: [
1515
+ /* @__PURE__ */ jsx13("h3", { children: "1 \xB7 The config points at the stories" }),
1516
+ /* @__PURE__ */ jsxs10("p", { children: [
1517
+ "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 ",
1518
+ /* @__PURE__ */ jsx13("code", { children: "title" }),
1519
+ " and exported stories, and builds the sidebar \u2014 including any group renames, so authored titles can stay as they are."
1520
+ ] })
1521
+ ] }),
1522
+ /* @__PURE__ */ jsxs10("div", { className: "card", children: [
1523
+ /* @__PURE__ */ jsx13("h3", { children: "2 \xB7 Examples are the story modules" }),
1524
+ /* @__PURE__ */ jsxs10("p", { children: [
1525
+ "Opening a component lazily imports the same module Storybook renders and evaluates it here: the meta's",
1526
+ " ",
1527
+ /* @__PURE__ */ jsx13("code", { children: "component" }),
1528
+ ", merged ",
1529
+ /* @__PURE__ */ jsx13("code", { children: "args" }),
1530
+ ", or the story's own ",
1531
+ /* @__PURE__ */ jsx13("code", { children: "render" }),
1532
+ ". A design system gets a docs page without writing one."
1533
+ ] })
1534
+ ] }),
1535
+ /* @__PURE__ */ jsxs10("div", { className: "card", children: [
1536
+ /* @__PURE__ */ jsx13("h3", { children: "3 \xB7 API tables are argTypes" }),
1537
+ /* @__PURE__ */ jsxs10("p", { children: [
1538
+ "Each page's prop table is derived from the story meta's ",
1539
+ /* @__PURE__ */ jsx13("code", { children: "argTypes" }),
1540
+ " and default",
1541
+ " ",
1542
+ /* @__PURE__ */ jsx13("code", { children: "args" }),
1543
+ " at runtime. Add a control to a story and the table follows."
1544
+ ] })
1545
+ ] }),
1546
+ /* @__PURE__ */ jsxs10("div", { className: "card", children: [
1547
+ /* @__PURE__ */ jsx13("h3", { children: "4 \xB7 The chrome uses the system's tokens" }),
1548
+ /* @__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." })
1549
+ ] })
1550
+ ] }),
1551
+ /* @__PURE__ */ jsx13("h2", { children: "Start here" }),
1552
+ /* @__PURE__ */ jsx13("ul", { children: startHere.map((entry) => /* @__PURE__ */ jsxs10("li", { children: [
1553
+ /* @__PURE__ */ jsx13("a", { href: `#${hrefFor(`/components/${entry.slug}`)}`, children: entry.name }),
1554
+ " \u2014 ",
1555
+ entry.stories.length,
1556
+ " stories"
1557
+ ] }, entry.slug)) })
1558
+ ] });
1559
+ }
1560
+
1561
+ // src/pages/releases.tsx
1562
+ import { releases } from "virtual:storybook-docs/releases";
1563
+ import { Fragment as Fragment9, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1564
+ function ReleasesPage() {
1565
+ return /* @__PURE__ */ jsxs11(Fragment9, { children: [
1566
+ /* @__PURE__ */ jsx14("div", { className: "crumb", children: "Releases" }),
1567
+ /* @__PURE__ */ jsx14("h1", { children: "Releases" }),
1568
+ releases.version ? /* @__PURE__ */ jsxs11("p", { className: "lede", children: [
1569
+ "Current release ",
1570
+ /* @__PURE__ */ jsxs11("span", { className: "chip", children: [
1571
+ "v",
1572
+ releases.version
1573
+ ] })
1574
+ ] }) : null,
1575
+ releases.changelog ? /* @__PURE__ */ jsx14(MarkdownView, { markdown: releases.changelog }) : null
1576
+ ] });
1577
+ }
1578
+
1579
+ // src/search.tsx
1580
+ import { useEffect as useEffect6, useMemo as useMemo4, useRef as useRef4, useState as useState7 } from "react";
1581
+ import { catalog as catalog2 } from "virtual:storybook-docs/catalog";
1582
+
1583
+ // src/search-match.ts
1584
+ var MAX_COMPONENTS = 10;
1585
+ var MAX_STORIES_PER_COMPONENT = 2;
1586
+ function highlightSegments(text, needle) {
1587
+ const term = needle.trim().toLowerCase();
1588
+ const lower = text.toLowerCase();
1589
+ const start2 = term && lower.length === text.length ? lower.indexOf(term) : -1;
1590
+ if (start2 < 0) return [{ text, match: false }];
1591
+ const end = start2 + term.length;
1592
+ return [
1593
+ { text: text.slice(0, start2), match: false },
1594
+ { text: text.slice(start2, end), match: true },
1595
+ { text: text.slice(end), match: false }
1596
+ ].filter((segment) => segment.text);
1597
+ }
1598
+ function scoreEntry(entry, needle) {
1599
+ const name = entry.name.toLowerCase();
1600
+ if (name === needle) return 100;
1601
+ if (name.startsWith(needle)) return 80;
1602
+ if (name.includes(needle)) return 60;
1603
+ if (entry.group.toLowerCase().includes(needle)) return 40;
1604
+ if (entry.storybookTitle.toLowerCase().includes(needle)) return 30;
1605
+ return -1;
1606
+ }
1607
+ function searchCatalog(catalog4, query) {
1608
+ const needle = query.trim().toLowerCase();
1609
+ if (!needle) return [];
1610
+ return catalog4.map((entry) => {
1611
+ const stories = entry.stories.filter((story) => story.toLowerCase().includes(needle)).slice(0, MAX_STORIES_PER_COMPONENT);
1612
+ const score = scoreEntry(entry, needle);
1613
+ return { entry, stories, score: score >= 0 ? score : stories.length ? 20 : -1, componentHit: score >= 0 };
1614
+ }).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 }) => [
1615
+ ...componentHit ? [{ entry }] : [],
1616
+ ...stories.map((story) => ({ entry, story }))
1617
+ ]);
1618
+ }
1619
+ var rowKey = (row) => row.story ? `${row.entry.slug}--${row.story}` : row.entry.slug;
1620
+ var rowPath = (row) => `/components/${row.entry.slug}${row.story ? `?story=${encodeURIComponent(row.story)}` : ""}`;
1621
+
1622
+ // src/search.tsx
1623
+ import { Fragment as Fragment10, jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
1624
+ function renderHighlighted(text, query) {
1625
+ const segments = highlightSegments(text, query);
1626
+ return segments.map(
1627
+ (segment, index) => segment.match ? /* @__PURE__ */ jsx15("mark", { children: segment.text }, index) : segment.text
1628
+ );
1629
+ }
1630
+ function SearchBox() {
1631
+ const [query, setQuery] = useState7("");
1632
+ const [open, setOpen] = useState7(false);
1633
+ const [active, setActive] = useState7(0);
1634
+ const inputRef = useRef4(null);
1635
+ const listId = "storybook-docs-search-results";
1636
+ const optionId = (key) => `${listId}-${key}`;
1637
+ const results = useMemo4(() => {
1638
+ return searchCatalog(catalog2, query);
1639
+ }, [query]);
1640
+ useEffect6(() => {
1641
+ setActive(0);
1642
+ }, [query]);
1643
+ useEffect6(() => {
1644
+ const onGlobalKeyDown = (event) => {
1645
+ if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
1646
+ event.preventDefault();
1647
+ inputRef.current?.focus();
1648
+ inputRef.current?.select();
1649
+ setOpen(true);
1650
+ }
1651
+ };
1652
+ window.addEventListener("keydown", onGlobalKeyDown);
1653
+ return () => window.removeEventListener("keydown", onGlobalKeyDown);
1654
+ }, []);
1655
+ const go = (row) => {
1656
+ window.location.hash = hrefFor(rowPath(row));
1657
+ setOpen(false);
1658
+ setQuery("");
1659
+ inputRef.current?.blur();
1660
+ };
1661
+ const hasQuery = query.trim().length > 0;
1662
+ const hasResults = results.length > 0;
1663
+ const showDropdown = open && (hasResults || hasQuery);
1664
+ const activeRow = hasResults && results[active] ? results[active] : void 0;
1665
+ const activeOptionId = activeRow ? optionId(rowKey(activeRow)) : void 0;
1666
+ useEffect6(() => {
1667
+ if (showDropdown && activeOptionId) {
1668
+ const el = document.getElementById(activeOptionId);
1669
+ el?.scrollIntoView({ block: "nearest" });
1670
+ }
1671
+ }, [activeOptionId, showDropdown]);
1672
+ const onKeyDown = (event) => {
1673
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
1674
+ event.preventDefault();
1675
+ if (!open) {
1676
+ setOpen(true);
1677
+ return;
1678
+ }
1679
+ if (results.length === 0) return;
1680
+ setActive((current) => {
1681
+ const next = event.key === "ArrowDown" ? current + 1 : current - 1;
1682
+ return (next + results.length) % results.length;
1683
+ });
1684
+ return;
1685
+ }
1686
+ if (event.key === "Enter") {
1687
+ if (activeRow) {
1688
+ event.preventDefault();
1689
+ go(activeRow);
1690
+ }
1691
+ return;
1692
+ }
1693
+ if (event.key === "Escape") {
1694
+ event.preventDefault();
1695
+ setOpen(false);
1696
+ setQuery("");
1697
+ inputRef.current?.blur();
1698
+ }
1699
+ };
1700
+ return /* @__PURE__ */ jsxs12("div", { className: "search", children: [
1701
+ /* @__PURE__ */ jsx15(
1702
+ "input",
1703
+ {
1704
+ ref: inputRef,
1705
+ type: "text",
1706
+ role: "combobox",
1707
+ "aria-expanded": showDropdown,
1708
+ "aria-controls": hasResults ? listId : void 0,
1709
+ "aria-activedescendant": showDropdown ? activeOptionId : void 0,
1710
+ "aria-autocomplete": "list",
1711
+ "aria-label": `Search ${catalog2.length} components`,
1712
+ placeholder: `Search ${catalog2.length} components\u2026 \u2318K`,
1713
+ value: query,
1714
+ onChange: (event) => {
1715
+ setQuery(event.target.value);
1716
+ setOpen(true);
1717
+ },
1718
+ onFocus: () => setOpen(true),
1719
+ onBlur: () => window.setTimeout(() => setOpen(false), 150),
1720
+ onKeyDown
1721
+ }
1722
+ ),
1723
+ showDropdown ? /* @__PURE__ */ jsxs12("div", { className: "search-dropdown", children: [
1724
+ hasResults ? /* @__PURE__ */ jsx15("ul", { id: listId, role: "listbox", "aria-label": "Components", className: "search-results", children: results.map((row, index) => {
1725
+ const key = rowKey(row);
1726
+ const optId = optionId(key);
1727
+ return /* @__PURE__ */ jsxs12(
1728
+ "li",
1729
+ {
1730
+ id: optId,
1731
+ role: "option",
1732
+ "aria-selected": index === active,
1733
+ onMouseEnter: () => {
1734
+ setActive(index);
1735
+ void row.entry.load();
1736
+ },
1737
+ onFocus: () => {
1738
+ setActive(index);
1739
+ void row.entry.load();
1740
+ },
1741
+ onMouseDown: (event) => {
1742
+ event.preventDefault();
1743
+ go(row);
1744
+ },
1745
+ children: [
1746
+ /* @__PURE__ */ jsxs12("span", { className: "search-result-main", children: [
1747
+ /* @__PURE__ */ jsx15("b", { className: "search-result-name", children: renderHighlighted(row.entry.name, query) }),
1748
+ row.story ? /* @__PURE__ */ jsxs12(Fragment10, { children: [
1749
+ /* @__PURE__ */ jsx15("span", { className: "search-result-sep", "aria-hidden": "true", children: " \u203A " }),
1750
+ /* @__PURE__ */ jsx15("span", { className: "search-result-story", children: renderHighlighted(row.story, query) })
1751
+ ] }) : null
1752
+ ] }),
1753
+ /* @__PURE__ */ jsx15("span", { className: "search-result-meta", children: row.story ? row.entry.group : `${row.entry.group} \xB7 ${row.entry.stories.length} stories` })
1754
+ ]
1755
+ },
1756
+ key
1757
+ );
1758
+ }) }) : /* @__PURE__ */ jsxs12("div", { className: "search-empty", role: "status", children: [
1759
+ "No components match \u2018",
1760
+ query.trim(),
1761
+ "\u2019"
1762
+ ] }),
1763
+ /* @__PURE__ */ jsxs12("div", { className: "search-footer", "aria-hidden": "true", children: [
1764
+ /* @__PURE__ */ jsxs12("span", { className: "search-footer-item", children: [
1765
+ /* @__PURE__ */ jsx15("kbd", { children: "\u2191" }),
1766
+ /* @__PURE__ */ jsx15("kbd", { children: "\u2193" }),
1767
+ " navigate"
1768
+ ] }),
1769
+ /* @__PURE__ */ jsx15("span", { className: "search-footer-sep", children: "\xB7" }),
1770
+ /* @__PURE__ */ jsxs12("span", { className: "search-footer-item", children: [
1771
+ /* @__PURE__ */ jsx15("kbd", { children: "Enter" }),
1772
+ " open"
1773
+ ] }),
1774
+ /* @__PURE__ */ jsx15("span", { className: "search-footer-sep", children: "\xB7" }),
1775
+ /* @__PURE__ */ jsxs12("span", { className: "search-footer-item", children: [
1776
+ /* @__PURE__ */ jsx15("kbd", { children: "Esc" }),
1777
+ " close"
1778
+ ] })
1779
+ ] })
1780
+ ] }) : null
1781
+ ] });
1782
+ }
1783
+
1784
+ // src/app.tsx
1785
+ import { releases as releases2 } from "virtual:storybook-docs/releases";
1786
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
1787
+ var routeHref = (path) => `#${hrefFor(path)}`;
1788
+ function parseRoute(hash) {
1789
+ const path = hashPath(hash).replace(new RegExp(`^#?\\/?${STORYBOOK_DOCS_BASE}`), "").replace(/^\/+/, "");
1790
+ if (path.startsWith("components/")) {
1791
+ const slug = path.slice("components/".length);
1792
+ if (catalog3.some((entry) => entry.slug === slug)) return { kind: "component", slug };
1793
+ }
1794
+ if (path === "releases" && releases2.changelog) return { kind: "releases" };
1795
+ if (path === "tokens/color") return { kind: "color" };
1796
+ if (path === "tokens/typography") return { kind: "typography" };
1797
+ if (path === "tokens/spacing") return { kind: "spacing" };
1798
+ if (path === "tokens/effects") return { kind: "effects" };
1799
+ return { kind: "overview" };
1800
+ }
1801
+ function DocsApp() {
1802
+ const [route, setRoute] = useState8(() => parseRoute(window.location.hash));
1803
+ const [mode, setMode] = useState8(theme.values?.[0] ?? "dark");
1804
+ const [navOpen, setNavOpen] = useState8(false);
1805
+ const navRef = useRef5(null);
1806
+ useRailFollow(navRef);
1807
+ const headerRef = useRef5(null);
1808
+ const mainRef = useRef5(null);
1809
+ useEffect7(() => {
1810
+ const header = headerRef.current;
1811
+ if (!header) return;
1812
+ const root = document.documentElement;
1813
+ const previousHeight = root.style.getPropertyValue("--sd-header-height");
1814
+ const measure = () => root.style.setProperty("--sd-header-height", `${header.getBoundingClientRect().height}px`);
1815
+ measure();
1816
+ const observer = new ResizeObserver(measure);
1817
+ observer.observe(header);
1818
+ return () => {
1819
+ observer.disconnect();
1820
+ if (previousHeight) root.style.setProperty("--sd-header-height", previousHeight);
1821
+ else root.style.removeProperty("--sd-header-height");
1822
+ };
1823
+ }, []);
1824
+ useEffect7(() => {
1825
+ const onHash = () => {
1826
+ setRoute(parseRoute(window.location.hash));
1827
+ setNavOpen(false);
1828
+ window.scrollTo(0, 0);
1829
+ mainRef.current?.focus({ preventScroll: true });
1830
+ };
1831
+ window.addEventListener("hashchange", onHash);
1832
+ return () => window.removeEventListener("hashchange", onHash);
1833
+ }, []);
1834
+ useEffect7(() => {
1835
+ document.documentElement.setAttribute(theme.attribute ?? "data-theme", mode);
1836
+ }, [mode]);
1837
+ const [darkMode, lightMode] = theme.values ?? ["dark", "light"];
1838
+ const activeSlug = route.kind === "component" ? route.slug : null;
1839
+ const foundations = [
1840
+ ...pages.color ? [{ href: routeHref(`/tokens/color`), label: "Color", kind: "color" }] : [],
1841
+ ...pages.typography ? [{ href: routeHref(`/tokens/typography`), label: "Typography", kind: "typography" }] : [],
1842
+ ...pages.spacing ? [{ href: routeHref(`/tokens/spacing`), label: "Spacing & shape", kind: "spacing" }] : [],
1843
+ ...pages.effects ? [{ href: routeHref(`/tokens/effects`), label: "Elevation & motion", kind: "effects" }] : []
1844
+ ];
1845
+ return /* @__PURE__ */ jsxs13("div", { className: route.kind === "overview" ? "app" : "app has-toc", children: [
1846
+ /* @__PURE__ */ jsx16(
1847
+ "a",
1848
+ {
1849
+ className: "skip",
1850
+ href: "#main",
1851
+ onClick: (event) => {
1852
+ event.preventDefault();
1853
+ mainRef.current?.focus();
1854
+ },
1855
+ children: "Skip to content"
1856
+ }
1857
+ ),
1858
+ /* @__PURE__ */ jsxs13("header", { className: "top", ref: headerRef, children: [
1859
+ /* @__PURE__ */ jsx16(
1860
+ "button",
1861
+ {
1862
+ type: "button",
1863
+ className: "tool nav-toggle",
1864
+ "aria-expanded": navOpen,
1865
+ "aria-controls": "docs-nav",
1866
+ onClick: () => setNavOpen(!navOpen),
1867
+ children: "Menu"
1868
+ }
1869
+ ),
1870
+ /* @__PURE__ */ jsxs13("a", { className: "brand-link", href: routeHref("/"), children: [
1871
+ /* @__PURE__ */ jsx16("span", { className: "mark", "aria-hidden": "true", children: site2.mark ?? site2.title.slice(0, 1).toUpperCase() }),
1872
+ /* @__PURE__ */ jsx16("span", { className: "brand", children: site2.title })
1873
+ ] }),
1874
+ /* @__PURE__ */ jsxs13("span", { className: "chip", children: [
1875
+ "docs",
1876
+ releases2.version ? ` \xB7 v${releases2.version}` : ""
1877
+ ] }),
1878
+ /* @__PURE__ */ jsx16(SearchBox, {}),
1879
+ /* @__PURE__ */ jsx16("span", { className: "spacer" }),
1880
+ /* @__PURE__ */ jsx16(
1881
+ "button",
1882
+ {
1883
+ type: "button",
1884
+ className: "tool",
1885
+ "aria-label": `Switch to ${mode === darkMode ? lightMode : darkMode} theme`,
1886
+ onClick: () => setMode(mode === darkMode ? lightMode : darkMode),
1887
+ children: mode === darkMode ? lightMode : darkMode
1888
+ }
1889
+ ),
1890
+ (site2.links ?? []).map((link) => /* @__PURE__ */ jsxs13("a", { className: "tool", href: link.href, children: [
1891
+ link.label,
1892
+ " ",
1893
+ /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", children: "\u2197" })
1894
+ ] }, link.href))
1895
+ ] }),
1896
+ /* @__PURE__ */ jsxs13("nav", { id: "docs-nav", className: navOpen ? "nav open" : "nav", "aria-label": "Documentation", ref: navRef, children: [
1897
+ /* @__PURE__ */ jsx16("a", { href: routeHref("/"), className: route.kind === "overview" ? "on" : void 0, "aria-current": route.kind === "overview" ? "page" : void 0, children: "Overview" }),
1898
+ releases2.changelog ? /* @__PURE__ */ jsxs13(
1899
+ "a",
1900
+ {
1901
+ href: routeHref("/releases"),
1902
+ className: route.kind === "releases" ? "on" : void 0,
1903
+ "aria-current": route.kind === "releases" ? "page" : void 0,
1904
+ children: [
1905
+ "Releases",
1906
+ releases2.version ? /* @__PURE__ */ jsxs13("span", { className: "nav-count", children: [
1907
+ "v",
1908
+ releases2.version
1909
+ ] }) : null
1910
+ ]
1911
+ }
1912
+ ) : null,
1913
+ foundations.length > 0 ? /* @__PURE__ */ jsxs13("div", { role: "group", "aria-labelledby": "nav-grp-foundations", children: [
1914
+ /* @__PURE__ */ jsx16("div", { className: "grp", id: "nav-grp-foundations", children: "Foundations" }),
1915
+ foundations.map((item) => /* @__PURE__ */ jsx16(
1916
+ "a",
1917
+ {
1918
+ href: item.href,
1919
+ className: route.kind === item.kind ? "on" : void 0,
1920
+ "aria-current": route.kind === item.kind ? "page" : void 0,
1921
+ children: item.label
1922
+ },
1923
+ item.href
1924
+ ))
1925
+ ] }) : null,
1926
+ groups2.map((group, index) => /* @__PURE__ */ jsxs13("div", { role: "group", "aria-labelledby": `nav-grp-${index}`, children: [
1927
+ /* @__PURE__ */ jsx16("div", { className: "grp", id: `nav-grp-${index}`, children: group }),
1928
+ catalog3.filter((entry) => entry.group === group).map((entry) => /* @__PURE__ */ jsx16(
1929
+ "a",
1930
+ {
1931
+ href: routeHref(`/components/${entry.slug}`),
1932
+ className: activeSlug === entry.slug ? "on" : void 0,
1933
+ "aria-current": activeSlug === entry.slug ? "page" : void 0,
1934
+ onMouseEnter: () => void entry.load(),
1935
+ onFocus: () => void entry.load(),
1936
+ children: entry.name
1937
+ },
1938
+ entry.slug
1939
+ ))
1940
+ ] }, group))
1941
+ ] }),
1942
+ /* @__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, {}) }),
1943
+ route.kind !== "overview" ? /* @__PURE__ */ jsx16(PageRail, { pageKey: activeSlug ?? route.kind }) : null
1944
+ ] });
1945
+ }
1946
+
1947
+ // src/start.tsx
1948
+ import { jsx as jsx17 } from "react/jsx-runtime";
1949
+ function start() {
1950
+ let container = document.getElementById("root");
1951
+ if (!container) {
1952
+ container = document.createElement("div");
1953
+ container.id = "root";
1954
+ document.body.append(container);
1955
+ }
1956
+ const attribute = theme2.attribute ?? "data-theme";
1957
+ document.documentElement.setAttribute(attribute, theme2.values?.[0] ?? "dark");
1958
+ if (themeCss) {
1959
+ const style = document.createElement("style");
1960
+ style.dataset.storybookDocs = "theme";
1961
+ style.textContent = themeCss;
1962
+ document.head.append(style);
1963
+ }
1964
+ document.title = site3.title;
1965
+ createRoot(container).render(/* @__PURE__ */ jsx17(StrictMode, { children: createElement3(DocsApp) }));
1966
+ }
1967
+ export {
1968
+ ComponentDemo,
1969
+ start
1970
+ };
1971
+ import './index.css';