astryx-dracula 0.5.0 → 0.6.2

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 (129) hide show
  1. package/BRAND.md +3 -3
  2. package/README.md +7 -4
  3. package/USAGE.md +49 -49
  4. package/astryx-dracula.d.ts +2 -2
  5. package/astryx-dracula.js +25 -9
  6. package/astryx-dracula.variants.d.ts +2 -2
  7. package/astryx.integration.mjs +1 -1
  8. package/icons.mjs +21 -17
  9. package/icons.tsx +69 -62
  10. package/package.json +125 -120
  11. package/shared/auth-chrome-config.ts +6 -6
  12. package/shared/auth-chrome.tsx +143 -144
  13. package/shared/auth-copy.ts +14 -14
  14. package/shared/chaptered-doc-config.ts +48 -51
  15. package/shared/chaptered-doc.tsx +267 -289
  16. package/shared/chart-hues.ts +25 -10
  17. package/shared/chart-labels.tsx +31 -30
  18. package/shared/chart-legend.tsx +55 -56
  19. package/shared/chart-panel-style.ts +3 -3
  20. package/shared/data-bar.tsx +97 -102
  21. package/shared/format-money.ts +1 -1
  22. package/shared/gallery-image.ts +6 -6
  23. package/shared/login-demo.ts +1 -1
  24. package/shared/metric-card.tsx +101 -105
  25. package/shared/metric-delta.tsx +28 -27
  26. package/shared/order-desk.tsx +205 -216
  27. package/shared/revenue-chart.tsx +145 -165
  28. package/shared/scene-castle.tsx +206 -291
  29. package/shared/scene-frame.tsx +33 -32
  30. package/shared/scene-hues.ts +17 -17
  31. package/shared/scene-tile.tsx +88 -92
  32. package/shared/settings-data.ts +119 -125
  33. package/shared/settings-rows.tsx +122 -159
  34. package/shared/sparkline.tsx +75 -88
  35. package/shared/sso-icons.tsx +10 -22
  36. package/shared/stars.tsx +16 -25
  37. package/templates/ai-chat-landing.template.mjs +5 -4
  38. package/templates/ai-chat-landing.tsx +473 -460
  39. package/templates/ai-chat.template.mjs +5 -4
  40. package/templates/ai-chat.tsx +543 -612
  41. package/templates/blank.template.mjs +5 -4
  42. package/templates/blank.tsx +18 -14
  43. package/templates/centered-hero.template.mjs +5 -4
  44. package/templates/centered-hero.tsx +55 -68
  45. package/templates/classic-gallery.template.mjs +5 -4
  46. package/templates/classic-gallery.tsx +97 -104
  47. package/templates/contact-form.template.mjs +5 -4
  48. package/templates/contact-form.tsx +247 -282
  49. package/templates/dashboard-portfolio.template.mjs +5 -4
  50. package/templates/dashboard-portfolio.tsx +717 -548
  51. package/templates/dashboard.template.mjs +5 -4
  52. package/templates/dashboard.tsx +596 -567
  53. package/templates/detail-page.template.mjs +5 -4
  54. package/templates/detail-page.tsx +546 -603
  55. package/templates/documentation-design.template.mjs +5 -4
  56. package/templates/documentation-design.tsx +231 -243
  57. package/templates/documentation-technical.template.mjs +5 -4
  58. package/templates/documentation-technical.tsx +236 -239
  59. package/templates/documentation.template.mjs +5 -4
  60. package/templates/documentation.tsx +267 -279
  61. package/templates/editor.template.mjs +5 -4
  62. package/templates/editor.tsx +844 -877
  63. package/templates/file-explorer.template.mjs +5 -4
  64. package/templates/file-explorer.tsx +566 -590
  65. package/templates/form-two-column.template.mjs +5 -4
  66. package/templates/form-two-column.tsx +195 -210
  67. package/templates/gallery-hero.template.mjs +5 -4
  68. package/templates/gallery-hero.tsx +93 -114
  69. package/templates/ide.template.mjs +5 -4
  70. package/templates/ide.tsx +407 -453
  71. package/templates/incident-console.template.mjs +5 -4
  72. package/templates/incident-console.tsx +593 -575
  73. package/templates/kanban-board.template.mjs +5 -4
  74. package/templates/kanban-board.tsx +665 -683
  75. package/templates/library.template.mjs +5 -4
  76. package/templates/library.tsx +409 -430
  77. package/templates/login-card.template.mjs +5 -4
  78. package/templates/login-card.tsx +63 -72
  79. package/templates/login-split.template.mjs +5 -4
  80. package/templates/login-split.tsx +192 -193
  81. package/templates/login-sso.template.mjs +5 -4
  82. package/templates/login-sso.tsx +257 -258
  83. package/templates/login.template.mjs +5 -4
  84. package/templates/login.tsx +53 -49
  85. package/templates/messaging-shell.template.mjs +5 -4
  86. package/templates/messaging-shell.tsx +556 -574
  87. package/templates/mixed-gallery.template.mjs +5 -4
  88. package/templates/mixed-gallery.tsx +60 -58
  89. package/templates/payment-form.template.mjs +5 -4
  90. package/templates/payment-form.tsx +882 -991
  91. package/templates/product-detail.template.mjs +5 -4
  92. package/templates/product-detail.tsx +261 -272
  93. package/templates/product-gallery.template.mjs +5 -4
  94. package/templates/product-gallery.tsx +126 -137
  95. package/templates/product-tour.template.mjs +5 -4
  96. package/templates/product-tour.tsx +741 -773
  97. package/templates/settings-dialog.template.mjs +5 -4
  98. package/templates/settings-dialog.tsx +688 -717
  99. package/templates/settings-sidebar.template.mjs +5 -4
  100. package/templates/settings-sidebar.tsx +762 -807
  101. package/templates/settings.template.mjs +5 -4
  102. package/templates/settings.tsx +289 -304
  103. package/templates/shell-nav.template.mjs +5 -4
  104. package/templates/shell-nav.tsx +212 -219
  105. package/templates/shell-side-nav.template.mjs +5 -4
  106. package/templates/shell-side-nav.tsx +135 -157
  107. package/templates/shell-top-nav.template.mjs +5 -4
  108. package/templates/shell-top-nav.tsx +182 -203
  109. package/templates/side-gallery.template.mjs +5 -4
  110. package/templates/side-gallery.tsx +85 -90
  111. package/templates/table-grouped.template.mjs +5 -4
  112. package/templates/table-grouped.tsx +1000 -1053
  113. package/templates/table-page-chart.template.mjs +5 -4
  114. package/templates/table-page-chart.tsx +400 -398
  115. package/templates/table-page-heatmap-status.template.mjs +5 -4
  116. package/templates/table-page-heatmap-status.tsx +483 -512
  117. package/templates/table-page-shoe-store-heatmap.template.mjs +5 -4
  118. package/templates/table-page-shoe-store-heatmap.tsx +748 -746
  119. package/templates/table-page.template.mjs +5 -4
  120. package/templates/table-page.tsx +396 -405
  121. package/templates/table.template.mjs +5 -4
  122. package/templates/table.tsx +92 -93
  123. package/templates/tech-report.template.mjs +5 -4
  124. package/templates/tech-report.tsx +1316 -1304
  125. package/templates/theme-showcase.template.mjs +5 -4
  126. package/templates/theme-showcase.tsx +871 -951
  127. package/theme.css +35 -77
  128. package/theme.css.d.ts +9 -0
  129. package/tokens.css +373 -380
@@ -1,6 +1,7 @@
1
1
  export default {
2
- type: 'page',
3
- name: 'Design Documentation',
4
- description: 'Live preview, usage guide, and code examples',
5
- category: 'docs',
2
+ type: "page",
3
+ name: "Design Documentation",
4
+ description: "Live preview, usage guide, and code examples",
5
+ keywords: ["documentation", "docs", "design system", "reference", "guide", "spec"],
6
+ category: "docs",
6
7
  };
@@ -1,45 +1,42 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
- // XLE (canonical structure, validated with `bunx astryx layout check`):
3
- // L > (LC > V[g=8] > (V[g=2] > Hd"Button"[level=1] + Tx"March 30, 2026"[t=supporting]) + (C.muted[p=0] > Ctr[h=360]) + (V[g=4] > Hd"Usage"[level=2] + Tx"Usage"[t=body] + Hd"Best practices"[level=3] + T) + D + (V[g=4] > Hd"Examples"[level=2] + Tx"Explore"[t=body]) + (V[g=8] > (C[p=0] > (S[p=3] > Tx"Semantics"[t=body]) + Ctr[h=280] + (S.muted[p=3] > V[g=3] > (TL > Tab"Description"! + Tab"Code") + Tx"We have four"[t=body])) + (C[p=0] > (S[p=3] > Tx"Default button with badge"[t=body]) + Ctr[h=280] + (S.muted[p=3] > V[g=3] > (TL > Tab"Description"! + Tab"Code") + Tx"Buttons can include"[t=body])))) + (LP > Outline)
2
+ // XLE (canonical structure of the tree below; the CLI had no XLE validator
3
+ // after `astryx layout` was removed in 0.7.0, so this is a reading aid and a
4
+ // human drift check — update it with the file, never alone):
5
+ // L[h=auto mw=960] > (LC[p=8 !scroll] > V[g=8] > (V[g=2] > Hd"Button"[level=1 t=display-2] + Tx"March 30, 2026"[t=supporting] + SE{Selector}"On this page") + (C.muted[p=0] > Ctr[h=360]) + (V[g=4] > Hd"Usage"[level=2] + Tx"Usage"[t=body] + Hd"Best practices"[level=3] + T[hover density=spacious]) + D + (V[g=4] > Hd"Examples"[level=2] + Tx"Explore"[t=body]) + (V[g=8] > (C[p=0] > (S.transparent[p=3] > Tx"Semantics"[t=body]) + Ctr[h=280] + (S.muted[p=3 dv=[top]] > V[g=3] > (TL[size=sm] > (Tab"Description"! + Tab"Code")) + Tx"We have four"[t=body])) + (C[p=0] > (S.transparent[p=3] > Tx"Default button with badge"[t=body]) + Ctr[h=280] + (S.muted[p=3 dv=[top]] > V[g=3] > (TL[size=sm] > (Tab"Description"! + Tab"Code")) + Tx"Buttons can include"[t=body])))) + (LP[!scroll] > Outline)
4
6
 
5
7
  /**
6
8
  * Documentation detail — one component, its usage, its guidance and its live examples. (Frame/responsive/container: see XLE header above.)
7
9
  */
8
10
 
9
- import {
10
- useCallback,
11
- useState,
12
- type ReactNode,
13
- } from 'react';
14
- import {Heading, Text} from '@astryxdesign/core/Text';
15
- import {Button} from '@astryxdesign/core/Button';
16
- import {Card} from '@astryxdesign/core/Card';
17
- import {Badge} from '@astryxdesign/core/Badge';
18
- import {CodeBlock} from '@astryxdesign/core/CodeBlock';
19
- import {TabList, Tab} from '@astryxdesign/core/TabList';
20
- import {Selector} from '@astryxdesign/core/Selector';
21
- import {HStack, VStack} from '@astryxdesign/core/Stack';
22
- import {Layout, LayoutContent, LayoutPanel} from '@astryxdesign/core/Layout';
23
- import {useMediaQuery} from '@astryxdesign/core/hooks';
24
- import {Divider} from '@astryxdesign/core/Divider';
25
- import {Table, pixel, proportional} from '@astryxdesign/core/Table';
26
- import {Icon} from '@astryxdesign/core/Icon';
27
- import {Section} from '@astryxdesign/core/Section';
28
- import {Center} from '@astryxdesign/core/Center';
29
- import {Outline, type OutlineItem} from '@astryxdesign/core/Outline';
30
- import {Plus} from 'lucide-react';
31
- import {outlinePanel} from 'astryx-dracula/shared/chaptered-doc-config';
32
-
11
+ import { Badge } from "@astryxdesign/core/Badge";
12
+ import { Button } from "@astryxdesign/core/Button";
13
+ import { Card } from "@astryxdesign/core/Card";
14
+ import { Center } from "@astryxdesign/core/Center";
15
+ import { CodeBlock } from "@astryxdesign/core/CodeBlock";
16
+ import { Divider } from "@astryxdesign/core/Divider";
17
+ import { useMediaQuery } from "@astryxdesign/core/hooks";
18
+ import { Icon } from "@astryxdesign/core/Icon";
19
+ import { Layout, LayoutContent, LayoutPanel } from "@astryxdesign/core/Layout";
20
+ import { Outline, type OutlineItem } from "@astryxdesign/core/Outline";
21
+ import { Section } from "@astryxdesign/core/Section";
22
+ import { Selector } from "@astryxdesign/core/Selector";
23
+ import { HStack, VStack } from "@astryxdesign/core/Stack";
24
+ import { Tab, TabList } from "@astryxdesign/core/TabList";
25
+ import { pixel, proportional, Table } from "@astryxdesign/core/Table";
26
+ import { Heading, Text } from "@astryxdesign/core/Text";
27
+ import { outlinePanel } from "astryx-dracula/shared/chaptered-doc-config";
28
+ import { Plus } from "lucide-react";
29
+ import { type ReactNode, useCallback, useState } from "react";
33
30
 
34
31
  const COMPONENT_OUTLINE_ITEMS: OutlineItem[] = [
35
- {id: 'usage', label: 'Usage', level: 2},
36
- {id: 'best-practices', label: 'Best practices', level: 3},
37
- {id: 'examples', label: 'Examples', level: 2},
32
+ { id: "usage", label: "Usage", level: 2 },
33
+ { id: "best-practices", label: "Best practices", level: 3 },
34
+ { id: "examples", label: "Examples", level: 2 },
38
35
  ];
39
36
 
40
- const COMPONENT_OUTLINE_OPTIONS = COMPONENT_OUTLINE_ITEMS.map(item => ({
41
- value: item.id,
42
- label: item.label,
37
+ const COMPONENT_OUTLINE_OPTIONS = COMPONENT_OUTLINE_ITEMS.map((item) => ({
38
+ value: item.id,
39
+ label: item.label,
43
40
  }));
44
41
 
45
42
  // ---------------------------------------------------------------------------
@@ -51,51 +48,50 @@ const COMPONENT_OUTLINE_OPTIONS = COMPONENT_OUTLINE_ITEMS.map(item => ({
51
48
  // the name/docs/previews below index it directly instead of threading a
52
49
  // parameter that can never vary.
53
50
  // The only caller ever passed 'button': the component name is a literal, not a lookup.
54
- const ACTIVE_COMPONENT_NAME = 'Button';
51
+ const ACTIVE_COMPONENT_NAME = "Button";
55
52
 
56
53
  const COMPONENT_DOCS: Record<
57
- string,
58
- {
59
- usage: string;
60
- bestPractices: {type: 'do' | 'dont'; text: string}[];
61
- examples: {title: string; description: string; code: string}[];
62
- }
54
+ string,
55
+ {
56
+ usage: string;
57
+ bestPractices: { type: "do" | "dont"; text: string }[];
58
+ examples: { title: string; description: string; code: string }[];
59
+ }
63
60
  > = {
64
- button: {
65
- usage:
66
- 'Buttons provide visual cues for actions and events. These fundamental components allow users to commit actions and navigate a page flow. Use a Button when a user needs to submit a form, start a new task or action, or trigger a new UI element to appear on the page.',
67
- bestPractices: [
68
- {
69
- type: 'do',
70
- text: 'Convey clear action hierarchy: Each surface should only have 1 primary button. A majority of buttons should be in default or flat style.',
71
- },
72
- {
73
- type: 'do',
74
- text: 'Promote clarity: Consider labels alongside icons where appropriate.',
75
- },
76
- {
77
- type: 'dont',
78
- text: 'Overuse primary or special buttons: Overusing colored buttons will result in a page with less intentionality, create visual confusion and a lack of page hierarchy.',
79
- },
80
- ],
81
- examples: [
82
- {
83
- title: 'Semantics',
84
- description:
85
- 'We have four semantic buttons types: flat, default, primary, and destructive. Flat buttons are used to limit visual prominence, whereas primary emphasizes a single action. Use destructive for deletions that trigger dialog confirmations.',
86
- code: `<Button label="Flat" variant="ghost" />\n<Button label="Default" variant="secondary" />\n<Button label="Primary" variant="primary" />\n<Button label="Destructive" variant="destructive" />`,
87
- },
88
- {
89
- title: 'Default button with badge',
90
- description:
91
- 'Buttons can include a badge to highlight new or updated actions.',
92
- code: `<Button\n label="Button"\n variant="secondary"\n/>`,
93
- },
94
- ],
95
- },
61
+ button: {
62
+ usage:
63
+ "Buttons provide visual cues for actions and events. These fundamental components allow users to commit actions and navigate a page flow. Use a Button when a user needs to submit a form, start a new task or action, or trigger a new UI element to appear on the page.",
64
+ bestPractices: [
65
+ {
66
+ type: "do",
67
+ text: "Convey clear action hierarchy: Each surface should only have 1 primary button. A majority of buttons should be in default or flat style.",
68
+ },
69
+ {
70
+ type: "do",
71
+ text: "Promote clarity: Consider labels alongside icons where appropriate.",
72
+ },
73
+ {
74
+ type: "dont",
75
+ text: "Overuse primary or special buttons: Overusing colored buttons will result in a page with less intentionality, create visual confusion and a lack of page hierarchy.",
76
+ },
77
+ ],
78
+ examples: [
79
+ {
80
+ title: "Semantics",
81
+ description:
82
+ "We have four semantic buttons types: flat, default, primary, and destructive. Flat buttons are used to limit visual prominence, whereas primary emphasizes a single action. Use destructive for deletions that trigger dialog confirmations.",
83
+ code: `<Button label="Flat" variant="ghost" />\n<Button label="Default" variant="secondary" />\n<Button label="Primary" variant="primary" />\n<Button label="Destructive" variant="destructive" />`,
84
+ },
85
+ {
86
+ title: "Default button with badge",
87
+ description: "Buttons can include a badge to highlight new or updated actions.",
88
+ code: `<Button\n label="Button"\n variant="secondary"\n/>`,
89
+ },
90
+ ],
91
+ },
96
92
  };
97
93
 
98
- const ACTIVE_DOCS = COMPONENT_DOCS['button'];
94
+ const ACTIVE_DOCS = COMPONENT_DOCS.button;
99
95
 
100
96
  // One preview node per example in ACTIVE_DOCS.examples, index-aligned. The
101
97
  // old EXAMPLE_PREVIEWS record carried only this key, so the record wrapper
@@ -103,22 +99,22 @@ const ACTIVE_DOCS = COMPONENT_DOCS['button'];
103
99
  // tooltip entries in the old COMPONENT_PREVIEWS map were reachable only
104
100
  // through nav keys this page never renders, so they are gone.
105
101
  const EXAMPLE_PREVIEW_NODES: ReactNode[] = [
106
- <HStack key="semantics" gap={3} vAlign="center" wrap="wrap">
107
- <Button label="Flat" variant="ghost" />
108
- <Button label="Default" variant="secondary" />
109
- <Button label="Primary" variant="primary" />
110
- <Button label="Destructive" variant="destructive" />
111
- </HStack>,
112
- <Button key="badge" label="Button" variant="secondary" />,
102
+ <HStack key="semantics" gap={3} vAlign="center" wrap="wrap">
103
+ <Button label="Flat" variant="ghost" />
104
+ <Button label="Default" variant="secondary" />
105
+ <Button label="Primary" variant="primary" />
106
+ <Button label="Destructive" variant="destructive" />
107
+ </HStack>,
108
+ <Button key="badge" label="Button" variant="secondary" />,
113
109
  ];
114
110
 
115
111
  const HERO_PREVIEW = (
116
- <Button
117
- label="Button"
118
- variant="secondary"
119
- icon={<Icon icon={Plus} />}
120
- endContent={<Badge label="New" variant="cyan" />}
121
- />
112
+ <Button
113
+ label="Button"
114
+ variant="secondary"
115
+ icon={<Icon icon={Plus} />}
116
+ endContent={<Badge label="New" variant="cyan" />}
117
+ />
122
118
  );
123
119
 
124
120
  // ---------------------------------------------------------------------------
@@ -126,170 +122,162 @@ const HERO_PREVIEW = (
126
122
  // ---------------------------------------------------------------------------
127
123
 
128
124
  function ComponentDetailView() {
129
- const [exampleTabs, setExampleTabs] = useState<Record<string, string>>({});
130
- const [activeId, setActiveId] = useState<string | undefined>(
131
- COMPONENT_OUTLINE_ITEMS[0]?.id,
132
- );
133
- const isMobile = useMediaQuery('(max-width: 768px)');
125
+ const [exampleTabs, setExampleTabs] = useState<Record<string, string>>({});
126
+ const [activeId, setActiveId] = useState<string | undefined>(COMPONENT_OUTLINE_ITEMS[0]?.id);
127
+ const isMobile = useMediaQuery("(max-width: 768px)");
134
128
 
135
- const scrollToId = useCallback((id: string) => {
136
- setActiveId(id);
137
- const target = document.getElementById(id);
138
- if (target != null) {
139
- target.scrollIntoView({behavior: 'smooth', block: 'start'});
140
- window.history.pushState(null, '', `#${id}`);
141
- }
142
- }, []);
129
+ const scrollToId = useCallback((id: string) => {
130
+ setActiveId(id);
131
+ const target = document.getElementById(id);
132
+ if (target != null) {
133
+ target.scrollIntoView({ behavior: "smooth", block: "start" });
134
+ window.history.pushState(null, "", `#${id}`);
135
+ }
136
+ }, []);
143
137
 
144
- const docs = ACTIVE_DOCS;
145
- const previews = EXAMPLE_PREVIEW_NODES;
138
+ const docs = ACTIVE_DOCS;
139
+ const previews = EXAMPLE_PREVIEW_NODES;
146
140
 
147
- return (
148
- <Layout
149
- height="auto"
150
- contentWidth={960}
151
- end={
152
- isMobile ? undefined : (
153
- <LayoutPanel
154
- isScrollable={false}
155
- label="On this page"
156
- role="complementary"
157
- style={outlinePanel}>
158
- <Outline
159
- items={COMPONENT_OUTLINE_ITEMS}
160
- onActiveIdChange={setActiveId}
161
- />
162
- </LayoutPanel>
163
- )
164
- }
165
- content={
166
- <LayoutContent isScrollable={false} padding={8}>
167
- <VStack gap={8}>
168
- <VStack gap={2}>
169
- <Heading level={1} type="display-2">{ACTIVE_COMPONENT_NAME}</Heading>
170
- <Text type="supporting" color="secondary" hasTabularNumbers>
171
- March 30, 2026 · Updated 5:40 p.m. PST
172
- </Text>
173
- {isMobile && (
174
- <Selector
175
- label="On this page"
176
- isLabelHidden
177
- options={COMPONENT_OUTLINE_OPTIONS}
178
- value={activeId}
179
- onChange={scrollToId}
180
- width="100%"
181
- />
182
- )}
183
- </VStack>
141
+ return (
142
+ <Layout
143
+ height="auto"
144
+ contentWidth={960}
145
+ end={
146
+ isMobile ? undefined : (
147
+ <LayoutPanel
148
+ isScrollable={false}
149
+ label="On this page"
150
+ role="complementary"
151
+ style={outlinePanel}
152
+ >
153
+ <Outline items={COMPONENT_OUTLINE_ITEMS} onActiveIdChange={setActiveId} />
154
+ </LayoutPanel>
155
+ )
156
+ }
157
+ content={
158
+ <LayoutContent isScrollable={false} padding={8}>
159
+ <VStack gap={8}>
160
+ <VStack gap={2}>
161
+ <Heading level={1} type="display-2">
162
+ {ACTIVE_COMPONENT_NAME}
163
+ </Heading>
164
+ <Text type="supporting" color="secondary" hasTabularNumbers>
165
+ March 30, 2026 · Updated 5:40 p.m. PST
166
+ </Text>
167
+ {isMobile && (
168
+ <Selector
169
+ label="On this page"
170
+ isLabelHidden
171
+ options={COMPONENT_OUTLINE_OPTIONS}
172
+ value={activeId}
173
+ onChange={scrollToId}
174
+ width="100%"
175
+ />
176
+ )}
177
+ </VStack>
184
178
 
185
- <Card variant="muted" padding={0}>
186
- <Center height={360}>
187
- {HERO_PREVIEW}
188
- </Center>
189
- </Card>
179
+ <Card variant="muted" padding={0}>
180
+ <Center height={360}>{HERO_PREVIEW}</Center>
181
+ </Card>
190
182
 
191
- <VStack gap={4}>
192
- <Heading id="usage" level={2}>
193
- Usage
194
- </Heading>
195
- <Text type="body">{docs.usage}</Text>
196
- <Heading id="best-practices" level={3}>
197
- Best practices
198
- </Heading>
199
- <Table
200
- data={docs.bestPractices as Record<string, unknown>[]}
201
- dividers="none"
202
- hasHover
203
- columns={[
204
- {
205
- key: 'type',
206
- header: 'Guidance',
207
- width: pixel(125),
208
- renderCell: (item: Record<string, unknown>) => (
209
- <Badge
210
- label={item.type === 'do' ? 'Do' : "Don't"}
211
- variant={item.type === 'do' ? 'green' : 'red'}
212
- />
213
- ),
214
- },
215
- {
216
- key: 'text',
217
- header: 'Practices',
218
- width: proportional(1),
219
- renderCell: (item: Record<string, unknown>) => (
220
- <Text type="body" textWrap="wrap">
221
- {item.text as string}
222
- </Text>
223
- ),
224
- },
225
- ]}
226
- density="spacious"
227
- />
228
- </VStack>
183
+ <VStack gap={4}>
184
+ <Heading id="usage" level={2}>
185
+ Usage
186
+ </Heading>
187
+ <Text type="body">{docs.usage}</Text>
188
+ <Heading id="best-practices" level={3}>
189
+ Best practices
190
+ </Heading>
191
+ <Table
192
+ data={docs.bestPractices as Record<string, unknown>[]}
193
+ dividers="none"
194
+ hasHover
195
+ columns={[
196
+ {
197
+ key: "type",
198
+ header: "Guidance",
199
+ width: pixel(125),
200
+ renderCell: (item: Record<string, unknown>) => (
201
+ <Badge
202
+ label={item.type === "do" ? "Do" : "Don't"}
203
+ variant={item.type === "do" ? "green" : "red"}
204
+ />
205
+ ),
206
+ },
207
+ {
208
+ key: "text",
209
+ header: "Practices",
210
+ width: proportional(1),
211
+ renderCell: (item: Record<string, unknown>) => (
212
+ <Text type="body" textWrap="wrap">
213
+ {item.text as string}
214
+ </Text>
215
+ ),
216
+ },
217
+ ]}
218
+ density="spacious"
219
+ />
220
+ </VStack>
229
221
 
230
- <Divider />
222
+ <Divider />
231
223
 
232
- <VStack gap={4}>
233
- <Heading id="examples" level={2}>
234
- Examples
235
- </Heading>
236
- <Text type="body">
237
- Explore common configurations, variations, and states for this
238
- component.
239
- </Text>
240
- </VStack>
241
- <VStack gap={8}>
242
- {docs.examples.map((example, i) => {
243
- const tabKey = `example-${i}`;
244
- const activeTab = exampleTabs[tabKey] ?? 'description';
245
- return (
246
- <Card key={example.title} padding={0}>
247
- <Section padding={3} variant="transparent">
248
- <Text type="body" weight="semibold">
249
- {example.title}
250
- </Text>
251
- </Section>
252
- <Center height={280}>
253
- {previews[i] ?? (
254
- <Text type="supporting" color="secondary">
255
- Quiet in the crypt — no preview haunts this shelf yet.
256
- </Text>
257
- )}
258
- </Center>
259
- <Section variant="muted" padding={3} dividers={['top']}>
260
- <VStack gap={3}>
261
- <TabList
262
- value={activeTab}
263
- onChange={value =>
264
- setExampleTabs(prev => ({
265
- ...prev,
266
- [tabKey]: value,
267
- }))
268
- }
269
- size="sm">
270
- <Tab value="description" label="Description" />
271
- <Tab value="code" label="Code" />
272
- </TabList>
273
- {activeTab === 'description' ? (
274
- <Text type="body">{example.description}</Text>
275
- ) : (
276
- <CodeBlock
277
- code={example.code}
278
- language="tsx"
279
- width="100%"
280
- />
281
- )}
282
- </VStack>
283
- </Section>
284
- </Card>
285
- );
286
- })}
287
- </VStack>
288
- </VStack>
289
- </LayoutContent>
290
- }
291
- />
292
- );
224
+ <VStack gap={4}>
225
+ <Heading id="examples" level={2}>
226
+ Examples
227
+ </Heading>
228
+ <Text type="body">
229
+ Explore common configurations, variations, and states for this component.
230
+ </Text>
231
+ </VStack>
232
+ <VStack gap={8}>
233
+ {docs.examples.map((example, i) => {
234
+ const tabKey = `example-${i}`;
235
+ const activeTab = exampleTabs[tabKey] ?? "description";
236
+ return (
237
+ <Card key={example.title} padding={0}>
238
+ <Section padding={3} variant="transparent">
239
+ <Text type="body" weight="semibold">
240
+ {example.title}
241
+ </Text>
242
+ </Section>
243
+ <Center height={280}>
244
+ {previews[i] ?? (
245
+ <Text type="supporting" color="secondary">
246
+ Quiet in the crypt — no preview haunts this shelf yet.
247
+ </Text>
248
+ )}
249
+ </Center>
250
+ <Section variant="muted" padding={3} dividers={["top"]}>
251
+ <VStack gap={3}>
252
+ <TabList
253
+ value={activeTab}
254
+ onChange={(value) =>
255
+ setExampleTabs((prev) => ({
256
+ ...prev,
257
+ [tabKey]: value,
258
+ }))
259
+ }
260
+ size="sm"
261
+ >
262
+ <Tab value="description" label="Description" />
263
+ <Tab value="code" label="Code" />
264
+ </TabList>
265
+ {activeTab === "description" ? (
266
+ <Text type="body">{example.description}</Text>
267
+ ) : (
268
+ <CodeBlock code={example.code} language="tsx" width="100%" />
269
+ )}
270
+ </VStack>
271
+ </Section>
272
+ </Card>
273
+ );
274
+ })}
275
+ </VStack>
276
+ </VStack>
277
+ </LayoutContent>
278
+ }
279
+ />
280
+ );
293
281
  }
294
282
 
295
283
  // ---------------------------------------------------------------------------
@@ -297,5 +285,5 @@ function ComponentDetailView() {
297
285
  // ---------------------------------------------------------------------------
298
286
 
299
287
  export default function DocumentationDesign() {
300
- return <ComponentDetailView />;
288
+ return <ComponentDetailView />;
301
289
  }
@@ -1,6 +1,7 @@
1
1
  export default {
2
- type: 'page',
3
- name: 'Technical Documentation',
4
- description: 'Install steps, theming setup, and next steps',
5
- category: 'docs',
2
+ type: "page",
3
+ name: "Technical Documentation",
4
+ description: "Install steps, theming setup, and next steps",
5
+ keywords: ["documentation", "technical", "api reference", "spec", "manual", "reference"],
6
+ category: "docs",
6
7
  };