@astryxdesign/cli 0.1.0 → 0.1.1-canary.129bf0e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +68 -0
- package/README.md +117 -75
- package/bin/astryx.mjs +22 -7
- package/docs/getting-started.doc.mjs +11 -11
- package/docs/icons.doc.mjs +1 -1
- package/docs/migration.doc.mjs +2 -2
- package/docs/shape.doc.mjs +1 -1
- package/docs/styling.doc.mjs +3 -4
- package/docs/theme.doc.dense.mjs +2 -2
- package/docs/theme.doc.mjs +14 -0
- package/docs/theme.doc.zh.mjs +2 -2
- package/docs/working-with-ai.doc.mjs +4 -4
- package/package.json +8 -8
- package/src/api/doctor.mjs +3 -3
- package/src/api/search.mjs +207 -13
- package/src/api/template.mjs +62 -11
- package/src/api/template.test.mjs +2 -0
- package/src/codemods/__tests__/registry.test.mjs +1 -0
- package/src/codemods/registry.mjs +1 -0
- package/src/codemods/runner.mjs +105 -51
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-config-surfaces.test.mjs +116 -0
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +51 -0
- package/src/codemods/transforms/v0.1.0/index.mjs +28 -0
- package/src/codemods/transforms/v0.1.0/migrate-xds-config-surfaces.mjs +230 -0
- package/src/codemods/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +84 -0
- package/src/commands/agent-docs.mjs +119 -66
- package/src/commands/agent-docs.path-safety.test.mjs +1 -1
- package/src/commands/agent-docs.test.mjs +87 -31
- package/src/commands/build-theme.import-path.test.mjs +1 -1
- package/src/commands/build-theme.path-safety.test.mjs +1 -1
- package/src/commands/build-theme.prose.test.mjs +1 -1
- package/src/commands/build.mjs +196 -0
- package/src/commands/component-package.test.mjs +1 -1
- package/src/commands/component.test.mjs +1 -1
- package/src/commands/docs.test.mjs +1 -1
- package/src/commands/doctor.test.mjs +1 -1
- package/src/commands/external-showcase.test.mjs +1 -1
- package/src/commands/init.mjs +43 -9
- package/src/commands/init.next-steps.test.mjs +46 -0
- package/src/commands/interactive-guard.test.mjs +1 -1
- package/src/commands/json-contract.test.mjs +10 -3
- package/src/commands/swizzle-gap-safety.test.mjs +1 -1
- package/src/commands/swizzle.path-safety.test.mjs +1 -1
- package/src/commands/template.path-safety.test.mjs +1 -1
- package/src/commands/template.test.mjs +1 -1
- package/src/commands/upgrade.mjs +353 -169
- package/src/commands/upgrade.test.mjs +41 -27
- package/src/index.mjs +1 -0
- package/src/lib/config.mjs +12 -0
- package/src/lib/config.test.mjs +42 -0
- package/src/lib/error-codes.mjs +3 -0
- package/src/types/error-codes.d.ts +1 -0
- package/src/utils/interactive.mjs +1 -1
- package/src/utils/interactive.test.mjs +2 -0
- package/src/utils/package-manager.mjs +1 -1
- package/src/utils/package-manager.test.mjs +1 -1
- package/src/utils/path-safety.test.mjs +1 -1
- package/src/utils/paths.test.mjs +8 -8
- package/src/utils/update-check.mjs +4 -26
- package/src/utils/update-check.test.mjs +2 -64
- package/templates/blocks/components/AppShell/AppShellContentOnly.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellShowcase.tsx +1 -10
- package/templates/blocks/components/AppShell/AppShellSideNavOnly.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellTopNavOnly.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellTopNavWithSideNav.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellWithBanner.tsx +1 -9
- package/templates/blocks/components/AspectRatio/AspectRatioShowcase.tsx +12 -19
- package/templates/blocks/components/Banner/BannerShowcase.tsx +1 -8
- package/templates/blocks/components/Blockquote/BlockquoteShowcase.tsx +1 -8
- package/templates/blocks/components/Carousel/CarouselShowcase.tsx +2 -12
- package/templates/blocks/components/ChatComposerDrawer/ChatComposerDrawerShowcase.tsx +6 -9
- package/templates/blocks/components/ChatLayout/ChatLayoutPanelChat.tsx +10 -12
- package/templates/blocks/components/ChatMessageList/ChatMessageListDensity.tsx +1 -9
- package/templates/blocks/components/ChatMessageList/ChatMessageListFullFeatured.tsx +1 -9
- package/templates/blocks/components/ChatMessageList/ChatMessageListShowcase.tsx +1 -9
- package/templates/blocks/components/ChatMessageMetadata/ChatMessageMetadataShowcase.tsx +1 -8
- package/templates/blocks/components/ChatSendButton/ChatSendButtonInComposer.tsx +1 -8
- package/templates/blocks/components/Citation/CitationInlineText.tsx +4 -4
- package/templates/blocks/components/Code/CodeInlineInParagraph.tsx +1 -8
- package/templates/blocks/components/CodeBlock/CodeBlockBashCommand.tsx +1 -1
- package/templates/blocks/components/CodeBlock/CodeBlockJSONConfig.tsx +1 -1
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.doc.mjs +15 -0
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.tsx +26 -0
- package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemShowcase.tsx +9 -12
- package/templates/blocks/components/ContextMenu/ContextMenuShowcase.tsx +13 -15
- package/templates/blocks/components/Divider/DividerShowcase.tsx +1 -8
- package/templates/blocks/components/Divider/DividerVertical.tsx +7 -9
- package/templates/blocks/components/Field/FieldShowcase.tsx +1 -8
- package/templates/blocks/components/FormLayout/FormLayoutHorizontal.tsx +1 -6
- package/templates/blocks/components/Grid/GridResponsiveAutoFit.tsx +1 -9
- package/templates/blocks/components/HoverCard/HoverCardInlineTextHoverCard.tsx +4 -6
- package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.tsx +1 -6
- package/templates/blocks/components/HoverCard/HoverCardProfileHoverCard.tsx +2 -8
- package/templates/blocks/components/HoverCard/HoverCardShowcase.tsx +1 -8
- package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.tsx +2 -12
- package/templates/blocks/components/OverflowList/OverflowListOverflowBadges.tsx +8 -11
- package/templates/blocks/components/OverflowList/OverflowListOverflowDropdownActions.tsx +9 -12
- package/templates/blocks/components/Overlay/OverlayBottomStrip.tsx +4 -17
- package/templates/blocks/components/Overlay/OverlayHoverReveal.tsx +15 -16
- package/templates/blocks/components/Overlay/OverlayShowcase.tsx +5 -21
- package/templates/blocks/components/Pagination/PaginationDotsCarousel.tsx +2 -14
- package/templates/blocks/components/Pagination/PaginationPageSize.tsx +12 -14
- package/templates/blocks/components/Pagination/PaginationVariants.tsx +1 -8
- package/templates/blocks/components/Pagination/PaginationWithTable.tsx +2 -14
- package/templates/blocks/components/Tokenizer/TokenizerClear.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerCreatable.tsx +2 -7
- package/templates/blocks/components/Tokenizer/TokenizerEndContent.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerIcon.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerMaxEntries.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerOverflow.tsx +2 -7
- package/templates/blocks/components/Tokenizer/TokenizerShowcase.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerStates.tsx +4 -9
- package/templates/blocks/components/Toolbar/ToolbarCardHeader.tsx +1 -10
- package/templates/blocks/components/Toolbar/ToolbarSizes.tsx +1 -8
- package/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +1 -8
- package/templates/blocks/components/Toolbar/ToolbarThreeSlot.tsx +1 -10
- package/templates/blocks/components/Toolbar/ToolbarWithTabs.tsx +8 -11
- package/templates/pages/ai-chat/page.tsx +71 -64
- package/templates/pages/ai-chat-landing/page.tsx +8 -12
- package/templates/pages/centered-hero/page.tsx +13 -15
- package/templates/pages/classic-gallery/page.tsx +27 -34
- package/templates/pages/detail-page/page.tsx +18 -18
- package/templates/pages/documentation/page.tsx +42 -58
- package/templates/pages/documentation-design/page.tsx +82 -60
- package/templates/pages/documentation-technical/page.tsx +101 -60
- package/templates/pages/editor/page.tsx +42 -54
- package/templates/pages/file-explorer/page.tsx +13 -16
- package/templates/pages/form-two-column/page.tsx +13 -17
- package/templates/pages/gallery-hero/page.tsx +13 -15
- package/templates/pages/ide/page.tsx +188 -264
- package/templates/pages/library/page.tsx +16 -23
- package/templates/pages/login/page.tsx +14 -18
- package/templates/pages/login-card/page.tsx +14 -18
- package/templates/pages/login-split/page.tsx +50 -48
- package/templates/pages/login-sso/page.tsx +9 -13
- package/templates/pages/mixed-gallery/page.tsx +51 -45
- package/templates/pages/payment-form/page.tsx +56 -70
- package/templates/pages/product-detail/page.tsx +27 -33
- package/templates/pages/product-gallery/page.tsx +7 -13
- package/templates/pages/settings-dialog/page.tsx +35 -43
- package/templates/pages/settings-sidebar/page.tsx +39 -47
- package/templates/pages/side-gallery/page.tsx +6 -9
- package/templates/pages/table-grouped/page.tsx +11 -15
- package/templates/pages/theme-showcase/page.tsx +33 -37
|
@@ -41,26 +41,26 @@ import {
|
|
|
41
41
|
} from '@heroicons/react/24/outline';
|
|
42
42
|
|
|
43
43
|
// ─── Styles ─────────────────────────────────────────────────────────────────
|
|
44
|
-
import
|
|
44
|
+
import type {CSSProperties} from 'react';
|
|
45
45
|
|
|
46
46
|
// The only custom CSS in this template is small optical-alignment negative
|
|
47
47
|
// margins: LayoutHeader/TabList have no edge-dock prop (#2622) and List
|
|
48
48
|
// has no "bleed to container edge" prop (#2626). Everything else uses props.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
49
|
+
// Plain inline styles — no StyleX compiler required.
|
|
50
|
+
|
|
51
|
+
// Bleed the tab bar to the header's content edges so the active-tab underline
|
|
52
|
+
// meets the header divider. No edge-dock prop on TabList (#2622).
|
|
53
|
+
const tabsRow: CSSProperties = {
|
|
54
|
+
marginInline: -12,
|
|
55
|
+
marginBottom: -16,
|
|
56
|
+
marginTop: 12,
|
|
57
|
+
};
|
|
58
|
+
// Pull the list items' inner padding back so their content optically aligns
|
|
59
|
+
// with the section heading above (ListItem insets content by ~8px). No
|
|
60
|
+
// edge/inset prop on List (#2626).
|
|
61
|
+
const itemsList: CSSProperties = {
|
|
62
|
+
marginInline: -8,
|
|
63
|
+
};
|
|
64
64
|
|
|
65
65
|
// ─── Product data ───────────────────────────────────────────────────────────
|
|
66
66
|
const PRODUCT_IMAGES = [
|
|
@@ -258,7 +258,7 @@ function PageHeader({
|
|
|
258
258
|
</HStack>
|
|
259
259
|
)}
|
|
260
260
|
|
|
261
|
-
<HStack vAlign="center"
|
|
261
|
+
<HStack vAlign="center" style={tabsRow}>
|
|
262
262
|
<StackItem size="fill">
|
|
263
263
|
<TabList value={activeTab} onChange={onTabChange} size="lg">
|
|
264
264
|
<Tab value="details" label="Details" />
|
|
@@ -305,7 +305,7 @@ function ItemsCard() {
|
|
|
305
305
|
</HStack>
|
|
306
306
|
</HStack>
|
|
307
307
|
|
|
308
|
-
<List density="spacious"
|
|
308
|
+
<List density="spacious" style={itemsList}>
|
|
309
309
|
{PRODUCTS.map((product, i) => (
|
|
310
310
|
<ListItem
|
|
311
311
|
key={i}
|
|
@@ -2,27 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
SideNav,
|
|
8
|
-
SideNavHeading,
|
|
9
|
-
SideNavItem,
|
|
10
|
-
SideNavSection,
|
|
11
|
-
} from '@astryxdesign/core/SideNav';
|
|
12
|
-
import {Text} from '@astryxdesign/core/Text';
|
|
5
|
+
import type {CSSProperties} from 'react';
|
|
6
|
+
import {Heading, Text} from '@astryxdesign/core/Text';
|
|
13
7
|
import {Button} from '@astryxdesign/core/Button';
|
|
14
8
|
import {Card} from '@astryxdesign/core/Card';
|
|
9
|
+
import {ClickableCard} from '@astryxdesign/core/ClickableCard';
|
|
15
10
|
import {HStack, VStack, StackItem} from '@astryxdesign/core/Stack';
|
|
16
|
-
import {Layout, LayoutContent
|
|
11
|
+
import {Layout, LayoutContent} from '@astryxdesign/core/Layout';
|
|
17
12
|
import {Grid} from '@astryxdesign/core/Grid';
|
|
18
|
-
import {radiusVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
19
13
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
const previewCard: CSSProperties = {
|
|
15
|
+
borderRadius: 'var(--radius-element)',
|
|
16
|
+
};
|
|
17
|
+
// Negative margin offsets each card's 8px padding so the grid content stays
|
|
18
|
+
// visually aligned while giving every card a padded hover/click target.
|
|
19
|
+
const cardGrid: CSSProperties = {
|
|
20
|
+
margin: -8,
|
|
21
|
+
};
|
|
26
22
|
|
|
27
23
|
// ---------------------------------------------------------------------------
|
|
28
24
|
// Data
|
|
@@ -213,30 +209,12 @@ const COMPONENT_CATEGORIES = [
|
|
|
213
209
|
export default function DocumentationOverviewPage() {
|
|
214
210
|
return (
|
|
215
211
|
<Layout
|
|
216
|
-
height="
|
|
212
|
+
height="auto"
|
|
217
213
|
contentWidth={1200}
|
|
218
|
-
start={
|
|
219
|
-
<LayoutPanel hasDivider padding={0}>
|
|
220
|
-
<SideNav header={<SideNavHeading heading="Product Name" />}>
|
|
221
|
-
<SideNavSection title="Navigation" isHeaderHidden>
|
|
222
|
-
<SideNavItem label="Home" isSelected />
|
|
223
|
-
<SideNavItem label="Getting started" />
|
|
224
|
-
</SideNavSection>
|
|
225
|
-
|
|
226
|
-
{COMPONENT_CATEGORIES.map(category => (
|
|
227
|
-
<SideNavSection key={category.label} title={category.label}>
|
|
228
|
-
{category.items.map(item => (
|
|
229
|
-
<SideNavItem key={item.key} label={item.name} />
|
|
230
|
-
))}
|
|
231
|
-
</SideNavSection>
|
|
232
|
-
))}
|
|
233
|
-
</SideNav>
|
|
234
|
-
</LayoutPanel>
|
|
235
|
-
}
|
|
236
214
|
content={
|
|
237
215
|
<LayoutContent padding={8}>
|
|
238
216
|
<VStack gap={10}>
|
|
239
|
-
<Card variant="
|
|
217
|
+
<Card variant="gray" padding={10}>
|
|
240
218
|
<HStack gap={8} vAlign="center">
|
|
241
219
|
<StackItem size="fill">
|
|
242
220
|
<VStack gap={4}>
|
|
@@ -246,11 +224,7 @@ export default function DocumentationOverviewPage() {
|
|
|
246
224
|
beautiful, accessible products.
|
|
247
225
|
</Text>
|
|
248
226
|
<HStack>
|
|
249
|
-
<Button
|
|
250
|
-
label="Get started"
|
|
251
|
-
variant="primary"
|
|
252
|
-
size="lg"
|
|
253
|
-
/>
|
|
227
|
+
<Button label="Get started" variant="primary" size="lg" />
|
|
254
228
|
</HStack>
|
|
255
229
|
</VStack>
|
|
256
230
|
</StackItem>
|
|
@@ -260,25 +234,35 @@ export default function DocumentationOverviewPage() {
|
|
|
260
234
|
|
|
261
235
|
{COMPONENT_CATEGORIES.map(category => (
|
|
262
236
|
<VStack key={category.label} gap={4}>
|
|
263
|
-
<
|
|
264
|
-
<Grid
|
|
237
|
+
<Heading level={2}>{category.label}</Heading>
|
|
238
|
+
<Grid
|
|
239
|
+
columns={{minWidth: 260}}
|
|
240
|
+
gap={2}
|
|
241
|
+
style={cardGrid}>
|
|
265
242
|
{category.items.map(item => (
|
|
266
|
-
<
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
{
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
243
|
+
<ClickableCard
|
|
244
|
+
key={item.key}
|
|
245
|
+
label={`Open ${item.name}`}
|
|
246
|
+
onClick={() => {}}
|
|
247
|
+
variant="transparent"
|
|
248
|
+
padding={2}>
|
|
249
|
+
<VStack gap={3}>
|
|
250
|
+
<Card
|
|
251
|
+
variant="muted"
|
|
252
|
+
padding={0}
|
|
253
|
+
minHeight={160}
|
|
254
|
+
style={previewCard}
|
|
255
|
+
/>
|
|
256
|
+
<VStack gap={0.5}>
|
|
257
|
+
<Text type="body" weight="bold">
|
|
258
|
+
{item.name}
|
|
259
|
+
</Text>
|
|
260
|
+
<Text type="body" color="secondary" maxLines={3}>
|
|
261
|
+
{item.desc}
|
|
262
|
+
</Text>
|
|
263
|
+
</VStack>
|
|
280
264
|
</VStack>
|
|
281
|
-
</
|
|
265
|
+
</ClickableCard>
|
|
282
266
|
))}
|
|
283
267
|
</Grid>
|
|
284
268
|
</VStack>
|
|
@@ -2,14 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
-
import {useState, useMemo} from 'react';
|
|
6
|
-
import * as stylex from '@stylexjs/stylex';
|
|
7
|
-
import {
|
|
8
|
-
SideNav,
|
|
9
|
-
SideNavHeading,
|
|
10
|
-
SideNavItem,
|
|
11
|
-
SideNavSection,
|
|
12
|
-
} from '@astryxdesign/core/SideNav';
|
|
5
|
+
import {useCallback, useState, useMemo, type CSSProperties} from 'react';
|
|
13
6
|
import {Heading, Text} from '@astryxdesign/core/Text';
|
|
14
7
|
import {Button} from '@astryxdesign/core/Button';
|
|
15
8
|
import {IconButton} from '@astryxdesign/core/IconButton';
|
|
@@ -20,8 +13,10 @@ import {Token} from '@astryxdesign/core/Token';
|
|
|
20
13
|
import {Banner} from '@astryxdesign/core/Banner';
|
|
21
14
|
import {CodeBlock} from '@astryxdesign/core/CodeBlock';
|
|
22
15
|
import {TabList, Tab} from '@astryxdesign/core/TabList';
|
|
16
|
+
import {Selector} from '@astryxdesign/core/Selector';
|
|
23
17
|
import {HStack, VStack, StackItem} from '@astryxdesign/core/Stack';
|
|
24
18
|
import {Layout, LayoutContent, LayoutPanel} from '@astryxdesign/core/Layout';
|
|
19
|
+
import {useMediaQuery} from '@astryxdesign/core/hooks';
|
|
25
20
|
import {Dialog, DialogHeader} from '@astryxdesign/core/Dialog';
|
|
26
21
|
import {Divider} from '@astryxdesign/core/Divider';
|
|
27
22
|
import {Tooltip} from '@astryxdesign/core/Tooltip';
|
|
@@ -29,15 +24,31 @@ import {Table, pixel} from '@astryxdesign/core/Table';
|
|
|
29
24
|
import {Icon} from '@astryxdesign/core/Icon';
|
|
30
25
|
import {Section} from '@astryxdesign/core/Section';
|
|
31
26
|
import {Center} from '@astryxdesign/core/Center';
|
|
27
|
+
import {Outline, type OutlineItem} from '@astryxdesign/core/Outline';
|
|
32
28
|
import {
|
|
33
29
|
ArrowTopRightOnSquareIcon,
|
|
34
30
|
ArrowsPointingOutIcon,
|
|
35
31
|
PlusIcon,
|
|
36
32
|
} from '@heroicons/react/24/outline';
|
|
37
33
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
const tabListFlush: CSSProperties = {marginInlineStart: '-12px'};
|
|
35
|
+
const outlinePanel: CSSProperties = {
|
|
36
|
+
position: 'sticky',
|
|
37
|
+
top: 24,
|
|
38
|
+
alignSelf: 'start',
|
|
39
|
+
paddingBlockStart: 120,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const COMPONENT_OUTLINE_ITEMS: OutlineItem[] = [
|
|
43
|
+
{id: 'usage', label: 'Usage', level: 2},
|
|
44
|
+
{id: 'best-practices', label: 'Best practices', level: 3},
|
|
45
|
+
{id: 'examples', label: 'Examples', level: 2},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const COMPONENT_OUTLINE_OPTIONS = COMPONENT_OUTLINE_ITEMS.map(item => ({
|
|
49
|
+
value: item.id,
|
|
50
|
+
label: item.label,
|
|
51
|
+
}));
|
|
41
52
|
|
|
42
53
|
// ---------------------------------------------------------------------------
|
|
43
54
|
// DialogPreview — stateful dialog preview for component previews
|
|
@@ -493,14 +504,21 @@ function getComponentDocs(key: string) {
|
|
|
493
504
|
// ComponentDetailView
|
|
494
505
|
// ---------------------------------------------------------------------------
|
|
495
506
|
|
|
496
|
-
function ComponentDetailView({
|
|
497
|
-
activeNav,
|
|
498
|
-
nav,
|
|
499
|
-
}: {
|
|
500
|
-
activeNav: string;
|
|
501
|
-
nav: React.ReactNode;
|
|
502
|
-
}) {
|
|
507
|
+
function ComponentDetailView({activeNav}: {activeNav: string}) {
|
|
503
508
|
const [exampleTabs, setExampleTabs] = useState<Record<string, string>>({});
|
|
509
|
+
const [activeId, setActiveId] = useState<string | undefined>(
|
|
510
|
+
COMPONENT_OUTLINE_ITEMS[0]?.id,
|
|
511
|
+
);
|
|
512
|
+
const isMobile = useMediaQuery('(max-width: 768px)');
|
|
513
|
+
|
|
514
|
+
const scrollToId = useCallback((id: string) => {
|
|
515
|
+
setActiveId(id);
|
|
516
|
+
const target = document.getElementById(id);
|
|
517
|
+
if (target != null) {
|
|
518
|
+
target.scrollIntoView({behavior: 'smooth', block: 'start'});
|
|
519
|
+
window.history.pushState(null, '', `#${id}`);
|
|
520
|
+
}
|
|
521
|
+
}, []);
|
|
504
522
|
|
|
505
523
|
const EXAMPLE_PREVIEWS: Record<string, React.ReactNode[]> = {
|
|
506
524
|
button: [
|
|
@@ -556,25 +574,42 @@ function ComponentDetailView({
|
|
|
556
574
|
|
|
557
575
|
return (
|
|
558
576
|
<Layout
|
|
559
|
-
height="
|
|
577
|
+
height="auto"
|
|
560
578
|
contentWidth={960}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
579
|
+
end={
|
|
580
|
+
isMobile ? undefined : (
|
|
581
|
+
<LayoutPanel
|
|
582
|
+
isScrollable={false}
|
|
583
|
+
label="On this page"
|
|
584
|
+
role="complementary"
|
|
585
|
+
style={outlinePanel}>
|
|
586
|
+
<Outline
|
|
587
|
+
items={COMPONENT_OUTLINE_ITEMS}
|
|
588
|
+
onActiveIdChange={setActiveId}
|
|
589
|
+
/>
|
|
590
|
+
</LayoutPanel>
|
|
591
|
+
)
|
|
565
592
|
}
|
|
566
593
|
content={
|
|
567
|
-
<LayoutContent padding={8}>
|
|
594
|
+
<LayoutContent isScrollable={false} padding={8}>
|
|
568
595
|
<VStack gap={8}>
|
|
569
596
|
<VStack gap={2}>
|
|
570
597
|
<Text type="display-1">{getComponentName(activeNav)}</Text>
|
|
571
598
|
<Text type="supporting" color="secondary">
|
|
572
599
|
March 30, 2026 · Updated 5:40 p.m. PST
|
|
573
600
|
</Text>
|
|
601
|
+
{isMobile && (
|
|
602
|
+
<Selector
|
|
603
|
+
label="On this page"
|
|
604
|
+
isLabelHidden
|
|
605
|
+
options={COMPONENT_OUTLINE_OPTIONS}
|
|
606
|
+
value={activeId}
|
|
607
|
+
onChange={scrollToId}
|
|
608
|
+
width="100%"
|
|
609
|
+
/>
|
|
610
|
+
)}
|
|
574
611
|
</VStack>
|
|
575
612
|
|
|
576
|
-
<Divider />
|
|
577
|
-
|
|
578
613
|
<Card variant="muted" padding={0}>
|
|
579
614
|
<Center height={360}>
|
|
580
615
|
{COMPONENT_PREVIEWS[activeNav] ?? (
|
|
@@ -586,13 +621,18 @@ function ComponentDetailView({
|
|
|
586
621
|
</Card>
|
|
587
622
|
|
|
588
623
|
<VStack gap={4}>
|
|
589
|
-
<Heading level={2}>
|
|
624
|
+
<Heading id="usage" level={2}>
|
|
625
|
+
Usage
|
|
626
|
+
</Heading>
|
|
590
627
|
<Text type="large" weight="normal">
|
|
591
628
|
{docs.usage}
|
|
592
629
|
</Text>
|
|
593
|
-
<Heading level={3}>
|
|
630
|
+
<Heading id="best-practices" level={3}>
|
|
631
|
+
Best practices
|
|
632
|
+
</Heading>
|
|
594
633
|
<Table
|
|
595
634
|
data={docs.bestPractices as Record<string, unknown>[]}
|
|
635
|
+
dividers="none"
|
|
596
636
|
columns={[
|
|
597
637
|
{
|
|
598
638
|
key: 'type',
|
|
@@ -616,14 +656,15 @@ function ComponentDetailView({
|
|
|
616
656
|
},
|
|
617
657
|
]}
|
|
618
658
|
density="spacious"
|
|
619
|
-
dividers="rows"
|
|
620
659
|
/>
|
|
621
660
|
</VStack>
|
|
622
661
|
|
|
623
662
|
<Divider />
|
|
624
663
|
|
|
625
664
|
<VStack gap={4}>
|
|
626
|
-
<Heading level={2}>
|
|
665
|
+
<Heading id="examples" level={2}>
|
|
666
|
+
Examples
|
|
667
|
+
</Heading>
|
|
627
668
|
<Text type="large" weight="normal">
|
|
628
669
|
Explore common configurations, variations, and states for this
|
|
629
670
|
component.
|
|
@@ -675,17 +716,24 @@ function ComponentDetailView({
|
|
|
675
716
|
<TabList
|
|
676
717
|
value={activeTab}
|
|
677
718
|
onChange={value =>
|
|
678
|
-
setExampleTabs(prev => ({
|
|
719
|
+
setExampleTabs(prev => ({
|
|
720
|
+
...prev,
|
|
721
|
+
[tabKey]: value,
|
|
722
|
+
}))
|
|
679
723
|
}
|
|
680
724
|
size="sm"
|
|
681
|
-
|
|
725
|
+
style={tabListFlush}>
|
|
682
726
|
<Tab value="description" label="Description" />
|
|
683
727
|
<Tab value="code" label="Code" />
|
|
684
728
|
</TabList>
|
|
685
729
|
{activeTab === 'description' ? (
|
|
686
730
|
<Text type="body">{example.description}</Text>
|
|
687
731
|
) : (
|
|
688
|
-
<CodeBlock
|
|
732
|
+
<CodeBlock
|
|
733
|
+
code={example.code}
|
|
734
|
+
language="tsx"
|
|
735
|
+
width="100%"
|
|
736
|
+
/>
|
|
689
737
|
)}
|
|
690
738
|
</VStack>
|
|
691
739
|
</Section>
|
|
@@ -705,31 +753,5 @@ function ComponentDetailView({
|
|
|
705
753
|
// ---------------------------------------------------------------------------
|
|
706
754
|
|
|
707
755
|
export default function DesignDocumentationPage() {
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
return (
|
|
711
|
-
<ComponentDetailView
|
|
712
|
-
activeNav={activePage}
|
|
713
|
-
nav={
|
|
714
|
-
<SideNav header={<SideNavHeading heading="Product Name" />}>
|
|
715
|
-
{COMPONENT_CATEGORIES.map(category => (
|
|
716
|
-
<SideNavSection key={category.label} title={category.label}>
|
|
717
|
-
{category.items.map(item => (
|
|
718
|
-
<SideNavItem
|
|
719
|
-
key={item.key}
|
|
720
|
-
label={item.name}
|
|
721
|
-
isSelected={activePage === item.key}
|
|
722
|
-
onClick={
|
|
723
|
-
item.key === 'button'
|
|
724
|
-
? () => setActivePage(item.key)
|
|
725
|
-
: undefined
|
|
726
|
-
}
|
|
727
|
-
/>
|
|
728
|
-
))}
|
|
729
|
-
</SideNavSection>
|
|
730
|
-
))}
|
|
731
|
-
</SideNav>
|
|
732
|
-
}
|
|
733
|
-
/>
|
|
734
|
-
);
|
|
756
|
+
return <ComponentDetailView activeNav="button" />;
|
|
735
757
|
}
|