@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.
Files changed (144) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +117 -75
  3. package/bin/astryx.mjs +22 -7
  4. package/docs/getting-started.doc.mjs +11 -11
  5. package/docs/icons.doc.mjs +1 -1
  6. package/docs/migration.doc.mjs +2 -2
  7. package/docs/shape.doc.mjs +1 -1
  8. package/docs/styling.doc.mjs +3 -4
  9. package/docs/theme.doc.dense.mjs +2 -2
  10. package/docs/theme.doc.mjs +14 -0
  11. package/docs/theme.doc.zh.mjs +2 -2
  12. package/docs/working-with-ai.doc.mjs +4 -4
  13. package/package.json +8 -8
  14. package/src/api/doctor.mjs +3 -3
  15. package/src/api/search.mjs +207 -13
  16. package/src/api/template.mjs +62 -11
  17. package/src/api/template.test.mjs +2 -0
  18. package/src/codemods/__tests__/registry.test.mjs +1 -0
  19. package/src/codemods/registry.mjs +1 -0
  20. package/src/codemods/runner.mjs +105 -51
  21. package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-config-surfaces.test.mjs +116 -0
  22. package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +51 -0
  23. package/src/codemods/transforms/v0.1.0/index.mjs +28 -0
  24. package/src/codemods/transforms/v0.1.0/migrate-xds-config-surfaces.mjs +230 -0
  25. package/src/codemods/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +84 -0
  26. package/src/commands/agent-docs.mjs +119 -66
  27. package/src/commands/agent-docs.path-safety.test.mjs +1 -1
  28. package/src/commands/agent-docs.test.mjs +87 -31
  29. package/src/commands/build-theme.import-path.test.mjs +1 -1
  30. package/src/commands/build-theme.path-safety.test.mjs +1 -1
  31. package/src/commands/build-theme.prose.test.mjs +1 -1
  32. package/src/commands/build.mjs +196 -0
  33. package/src/commands/component-package.test.mjs +1 -1
  34. package/src/commands/component.test.mjs +1 -1
  35. package/src/commands/docs.test.mjs +1 -1
  36. package/src/commands/doctor.test.mjs +1 -1
  37. package/src/commands/external-showcase.test.mjs +1 -1
  38. package/src/commands/init.mjs +43 -9
  39. package/src/commands/init.next-steps.test.mjs +46 -0
  40. package/src/commands/interactive-guard.test.mjs +1 -1
  41. package/src/commands/json-contract.test.mjs +10 -3
  42. package/src/commands/swizzle-gap-safety.test.mjs +1 -1
  43. package/src/commands/swizzle.path-safety.test.mjs +1 -1
  44. package/src/commands/template.path-safety.test.mjs +1 -1
  45. package/src/commands/template.test.mjs +1 -1
  46. package/src/commands/upgrade.mjs +353 -169
  47. package/src/commands/upgrade.test.mjs +41 -27
  48. package/src/index.mjs +1 -0
  49. package/src/lib/config.mjs +12 -0
  50. package/src/lib/config.test.mjs +42 -0
  51. package/src/lib/error-codes.mjs +3 -0
  52. package/src/types/error-codes.d.ts +1 -0
  53. package/src/utils/interactive.mjs +1 -1
  54. package/src/utils/interactive.test.mjs +2 -0
  55. package/src/utils/package-manager.mjs +1 -1
  56. package/src/utils/package-manager.test.mjs +1 -1
  57. package/src/utils/path-safety.test.mjs +1 -1
  58. package/src/utils/paths.test.mjs +8 -8
  59. package/src/utils/update-check.mjs +4 -26
  60. package/src/utils/update-check.test.mjs +2 -64
  61. package/templates/blocks/components/AppShell/AppShellContentOnly.tsx +1 -9
  62. package/templates/blocks/components/AppShell/AppShellShowcase.tsx +1 -10
  63. package/templates/blocks/components/AppShell/AppShellSideNavOnly.tsx +1 -9
  64. package/templates/blocks/components/AppShell/AppShellTopNavOnly.tsx +1 -9
  65. package/templates/blocks/components/AppShell/AppShellTopNavWithSideNav.tsx +1 -9
  66. package/templates/blocks/components/AppShell/AppShellWithBanner.tsx +1 -9
  67. package/templates/blocks/components/AspectRatio/AspectRatioShowcase.tsx +12 -19
  68. package/templates/blocks/components/Banner/BannerShowcase.tsx +1 -8
  69. package/templates/blocks/components/Blockquote/BlockquoteShowcase.tsx +1 -8
  70. package/templates/blocks/components/Carousel/CarouselShowcase.tsx +2 -12
  71. package/templates/blocks/components/ChatComposerDrawer/ChatComposerDrawerShowcase.tsx +6 -9
  72. package/templates/blocks/components/ChatLayout/ChatLayoutPanelChat.tsx +10 -12
  73. package/templates/blocks/components/ChatMessageList/ChatMessageListDensity.tsx +1 -9
  74. package/templates/blocks/components/ChatMessageList/ChatMessageListFullFeatured.tsx +1 -9
  75. package/templates/blocks/components/ChatMessageList/ChatMessageListShowcase.tsx +1 -9
  76. package/templates/blocks/components/ChatMessageMetadata/ChatMessageMetadataShowcase.tsx +1 -8
  77. package/templates/blocks/components/ChatSendButton/ChatSendButtonInComposer.tsx +1 -8
  78. package/templates/blocks/components/Citation/CitationInlineText.tsx +4 -4
  79. package/templates/blocks/components/Code/CodeInlineInParagraph.tsx +1 -8
  80. package/templates/blocks/components/CodeBlock/CodeBlockBashCommand.tsx +1 -1
  81. package/templates/blocks/components/CodeBlock/CodeBlockJSONConfig.tsx +1 -1
  82. package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.doc.mjs +15 -0
  83. package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.tsx +26 -0
  84. package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemShowcase.tsx +9 -12
  85. package/templates/blocks/components/ContextMenu/ContextMenuShowcase.tsx +13 -15
  86. package/templates/blocks/components/Divider/DividerShowcase.tsx +1 -8
  87. package/templates/blocks/components/Divider/DividerVertical.tsx +7 -9
  88. package/templates/blocks/components/Field/FieldShowcase.tsx +1 -8
  89. package/templates/blocks/components/FormLayout/FormLayoutHorizontal.tsx +1 -6
  90. package/templates/blocks/components/Grid/GridResponsiveAutoFit.tsx +1 -9
  91. package/templates/blocks/components/HoverCard/HoverCardInlineTextHoverCard.tsx +4 -6
  92. package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.tsx +1 -6
  93. package/templates/blocks/components/HoverCard/HoverCardProfileHoverCard.tsx +2 -8
  94. package/templates/blocks/components/HoverCard/HoverCardShowcase.tsx +1 -8
  95. package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.tsx +2 -12
  96. package/templates/blocks/components/OverflowList/OverflowListOverflowBadges.tsx +8 -11
  97. package/templates/blocks/components/OverflowList/OverflowListOverflowDropdownActions.tsx +9 -12
  98. package/templates/blocks/components/Overlay/OverlayBottomStrip.tsx +4 -17
  99. package/templates/blocks/components/Overlay/OverlayHoverReveal.tsx +15 -16
  100. package/templates/blocks/components/Overlay/OverlayShowcase.tsx +5 -21
  101. package/templates/blocks/components/Pagination/PaginationDotsCarousel.tsx +2 -14
  102. package/templates/blocks/components/Pagination/PaginationPageSize.tsx +12 -14
  103. package/templates/blocks/components/Pagination/PaginationVariants.tsx +1 -8
  104. package/templates/blocks/components/Pagination/PaginationWithTable.tsx +2 -14
  105. package/templates/blocks/components/Tokenizer/TokenizerClear.tsx +1 -6
  106. package/templates/blocks/components/Tokenizer/TokenizerCreatable.tsx +2 -7
  107. package/templates/blocks/components/Tokenizer/TokenizerEndContent.tsx +1 -6
  108. package/templates/blocks/components/Tokenizer/TokenizerIcon.tsx +1 -6
  109. package/templates/blocks/components/Tokenizer/TokenizerMaxEntries.tsx +1 -6
  110. package/templates/blocks/components/Tokenizer/TokenizerOverflow.tsx +2 -7
  111. package/templates/blocks/components/Tokenizer/TokenizerShowcase.tsx +1 -6
  112. package/templates/blocks/components/Tokenizer/TokenizerStates.tsx +4 -9
  113. package/templates/blocks/components/Toolbar/ToolbarCardHeader.tsx +1 -10
  114. package/templates/blocks/components/Toolbar/ToolbarSizes.tsx +1 -8
  115. package/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +1 -8
  116. package/templates/blocks/components/Toolbar/ToolbarThreeSlot.tsx +1 -10
  117. package/templates/blocks/components/Toolbar/ToolbarWithTabs.tsx +8 -11
  118. package/templates/pages/ai-chat/page.tsx +71 -64
  119. package/templates/pages/ai-chat-landing/page.tsx +8 -12
  120. package/templates/pages/centered-hero/page.tsx +13 -15
  121. package/templates/pages/classic-gallery/page.tsx +27 -34
  122. package/templates/pages/detail-page/page.tsx +18 -18
  123. package/templates/pages/documentation/page.tsx +42 -58
  124. package/templates/pages/documentation-design/page.tsx +82 -60
  125. package/templates/pages/documentation-technical/page.tsx +101 -60
  126. package/templates/pages/editor/page.tsx +42 -54
  127. package/templates/pages/file-explorer/page.tsx +13 -16
  128. package/templates/pages/form-two-column/page.tsx +13 -17
  129. package/templates/pages/gallery-hero/page.tsx +13 -15
  130. package/templates/pages/ide/page.tsx +188 -264
  131. package/templates/pages/library/page.tsx +16 -23
  132. package/templates/pages/login/page.tsx +14 -18
  133. package/templates/pages/login-card/page.tsx +14 -18
  134. package/templates/pages/login-split/page.tsx +50 -48
  135. package/templates/pages/login-sso/page.tsx +9 -13
  136. package/templates/pages/mixed-gallery/page.tsx +51 -45
  137. package/templates/pages/payment-form/page.tsx +56 -70
  138. package/templates/pages/product-detail/page.tsx +27 -33
  139. package/templates/pages/product-gallery/page.tsx +7 -13
  140. package/templates/pages/settings-dialog/page.tsx +35 -43
  141. package/templates/pages/settings-sidebar/page.tsx +39 -47
  142. package/templates/pages/side-gallery/page.tsx +6 -9
  143. package/templates/pages/table-grouped/page.tsx +11 -15
  144. 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 * as stylex from '@stylexjs/stylex';
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
- const pageStyles = stylex.create({
50
- // Bleed the tab bar to the header's content edges so the active-tab underline
51
- // meets the header divider. No edge-dock prop on TabList (#2622).
52
- tabsRow: {
53
- marginInline: -12,
54
- marginBottom: -16,
55
- marginTop: 12,
56
- },
57
- // Pull the list items' inner padding back so their content optically aligns
58
- // with the section heading above (ListItem insets content by ~8px). No
59
- // edge/inset prop on List (#2626).
60
- itemsList: {
61
- marginInline: -8,
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" xstyle={pageStyles.tabsRow}>
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" xstyle={pageStyles.itemsList}>
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 * as stylex from '@stylexjs/stylex';
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, LayoutPanel} from '@astryxdesign/core/Layout';
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 styles = stylex.create({
21
- previewCard: {
22
- borderRadius: radiusVars['--radius-container'],
23
- cursor: 'pointer',
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="fill"
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="cyan" padding={10}>
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
- <Text type="display-2">{category.label}</Text>
264
- <Grid columns={{minWidth: 260}} gap={8}>
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
- <VStack key={item.key} gap={3}>
267
- <Card
268
- variant="muted"
269
- padding={0}
270
- minHeight={160}
271
- xstyle={styles.previewCard}
272
- />
273
- <VStack gap={0.5}>
274
- <Text type="body" weight="bold">
275
- {item.name}
276
- </Text>
277
- <Text type="body" color="secondary">
278
- {item.desc}
279
- </Text>
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
- </VStack>
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 styles = stylex.create({
39
- tabListFlush: {marginInlineStart: '-12px'},
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="fill"
577
+ height="auto"
560
578
  contentWidth={960}
561
- start={
562
- <LayoutPanel hasDivider padding={0}>
563
- {nav}
564
- </LayoutPanel>
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}>Usage</Heading>
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}>Best practices</Heading>
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}>Examples</Heading>
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 => ({...prev, [tabKey]: value}))
719
+ setExampleTabs(prev => ({
720
+ ...prev,
721
+ [tabKey]: value,
722
+ }))
679
723
  }
680
724
  size="sm"
681
- xstyle={styles.tabListFlush}>
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 code={example.code} language="tsx" />
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
- const [activePage, setActivePage] = useState<string>('button');
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
  }