@astryxdesign/cli 0.0.15 → 0.1.0-canary.0b5b49f

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.
@@ -32,8 +32,8 @@ describe('generateCompressedIndex', () => {
32
32
  it('includes the version number', () => {
33
33
  const result = generateCompressedIndex('1.2.3');
34
34
  expect(result).toContain('Astryx v1.2.3');
35
- expect(result).toContain('<!-- XDS:START -->');
36
- expect(result).toContain('<!-- XDS:END -->');
35
+ expect(result).toContain('<!-- ASTRYX:START -->');
36
+ expect(result).toContain('<!-- ASTRYX:END -->');
37
37
  });
38
38
 
39
39
  it('includes theme nudge rule', () => {
@@ -82,19 +82,19 @@ describe('injectXdsBlock', () => {
82
82
  const filePath = path.join(tmpDir, 'test.md');
83
83
  fs.writeFileSync(filePath, '# Existing content\n');
84
84
 
85
- const result = injectXdsBlock(filePath, '<!-- XDS:START -->\nnew\n<!-- XDS:END -->');
85
+ const result = injectXdsBlock(filePath, '<!-- ASTRYX:START -->\nnew\n<!-- ASTRYX:END -->');
86
86
 
87
87
  expect(result).toBe(true);
88
88
  const content = fs.readFileSync(filePath, 'utf-8');
89
89
  expect(content).toContain('# Existing content');
90
- expect(content).toContain('<!-- XDS:START -->');
90
+ expect(content).toContain('<!-- ASTRYX:START -->');
91
91
  });
92
92
 
93
93
  it('replaces existing markers', () => {
94
94
  const filePath = path.join(tmpDir, 'test.md');
95
95
  fs.writeFileSync(filePath, 'before\n<!-- XDS:START -->\nold\n<!-- XDS:END -->\nafter\n');
96
96
 
97
- injectXdsBlock(filePath, '<!-- XDS:START -->\nnew\n<!-- XDS:END -->');
97
+ injectXdsBlock(filePath, '<!-- ASTRYX:START -->\nnew\n<!-- ASTRYX:END -->');
98
98
 
99
99
  const content = fs.readFileSync(filePath, 'utf-8');
100
100
  expect(content).toContain('new');
@@ -106,7 +106,7 @@ describe('injectXdsBlock', () => {
106
106
  it('returns false and does not create file when createIfMissing is false', () => {
107
107
  const filePath = path.join(tmpDir, 'nonexistent.md');
108
108
 
109
- const result = injectXdsBlock(filePath, '<!-- XDS:START -->\ncontent\n<!-- XDS:END -->');
109
+ const result = injectXdsBlock(filePath, '<!-- ASTRYX:START -->\ncontent\n<!-- ASTRYX:END -->');
110
110
 
111
111
  expect(result).toBe(false);
112
112
  expect(fs.existsSync(filePath)).toBe(false);
@@ -116,11 +116,11 @@ describe('injectXdsBlock', () => {
116
116
  const filePath = path.join(tmpDir, 'test.md');
117
117
  fs.writeFileSync(filePath, '# Existing content\n\nNo XDS markers here.\n');
118
118
 
119
- const result = injectXdsBlock(filePath, '<!-- XDS:START -->\nnew\n<!-- XDS:END -->', {onlyReplace: true});
119
+ const result = injectXdsBlock(filePath, '<!-- ASTRYX:START -->\nnew\n<!-- ASTRYX:END -->', {onlyReplace: true});
120
120
 
121
121
  expect(result).toBe(false);
122
122
  const content = fs.readFileSync(filePath, 'utf-8');
123
- expect(content).not.toContain('<!-- XDS:START -->');
123
+ expect(content).not.toContain('<!-- ASTRYX:START -->');
124
124
  expect(content).toBe('# Existing content\n\nNo XDS markers here.\n');
125
125
  });
126
126
 
@@ -128,7 +128,7 @@ describe('injectXdsBlock', () => {
128
128
  const filePath = path.join(tmpDir, 'test.md');
129
129
  fs.writeFileSync(filePath, 'before\n<!-- XDS:START -->\nold\n<!-- XDS:END -->\nafter\n');
130
130
 
131
- const result = injectXdsBlock(filePath, '<!-- XDS:START -->\nnew\n<!-- XDS:END -->', {onlyReplace: true});
131
+ const result = injectXdsBlock(filePath, '<!-- ASTRYX:START -->\nnew\n<!-- ASTRYX:END -->', {onlyReplace: true});
132
132
 
133
133
  expect(result).toBe(true);
134
134
  const content = fs.readFileSync(filePath, 'utf-8');
@@ -139,7 +139,7 @@ describe('injectXdsBlock', () => {
139
139
  it('creates file when createIfMissing is true', () => {
140
140
  const filePath = path.join(tmpDir, 'new.md');
141
141
 
142
- const result = injectXdsBlock(filePath, '<!-- XDS:START -->\ncontent\n<!-- XDS:END -->', {
142
+ const result = injectXdsBlock(filePath, '<!-- ASTRYX:START -->\ncontent\n<!-- ASTRYX:END -->', {
143
143
  createIfMissing: true,
144
144
  header: '# Header',
145
145
  });
@@ -147,7 +147,7 @@ describe('injectXdsBlock', () => {
147
147
  expect(result).toBe(true);
148
148
  const content = fs.readFileSync(filePath, 'utf-8');
149
149
  expect(content).toContain('# Header');
150
- expect(content).toContain('<!-- XDS:START -->');
150
+ expect(content).toContain('<!-- ASTRYX:START -->');
151
151
  });
152
152
  });
153
153
 
@@ -157,9 +157,9 @@ describe('injectAgentsMd', () => {
157
157
 
158
158
  const content = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
159
159
  expect(content).toContain('# AGENTS.md');
160
- expect(content).toContain('<!-- XDS:START -->');
160
+ expect(content).toContain('<!-- ASTRYX:START -->');
161
161
  expect(content).toContain('Astryx v1.0.0');
162
- expect(content).toContain('<!-- XDS:END -->');
162
+ expect(content).toContain('<!-- ASTRYX:END -->');
163
163
  });
164
164
 
165
165
  it('updates existing AGENTS.md by replacing XDS markers', () => {
@@ -195,7 +195,7 @@ Existing agent docs.
195
195
 
196
196
  const content = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
197
197
  expect(content).toContain('Existing agent docs.');
198
- expect(content).toContain('<!-- XDS:START -->');
198
+ expect(content).toContain('<!-- ASTRYX:START -->');
199
199
  expect(content).toContain('Astryx v1.0.0');
200
200
  });
201
201
  });
@@ -210,7 +210,7 @@ describe('injectClaudeMd', () => {
210
210
  const content = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
211
211
  expect(content).toContain('# Claude Config');
212
212
  expect(content).toContain('Existing rules.');
213
- expect(content).toContain('<!-- XDS:START -->');
213
+ expect(content).toContain('<!-- ASTRYX:START -->');
214
214
  expect(content).toContain('Astryx v1.0.0');
215
215
  });
216
216
 
@@ -322,7 +322,7 @@ describe('installAgentDocs', () => {
322
322
  expect(fs.existsSync(path.join(tmpDir, '.claude', 'CLAUDE.md'))).toBe(true);
323
323
  expect(fs.existsSync(path.join(tmpDir, 'AGENTS.md'))).toBe(false);
324
324
  const content = fs.readFileSync(path.join(tmpDir, '.claude', 'CLAUDE.md'), 'utf-8');
325
- expect(content).toContain('<!-- XDS:START -->');
325
+ expect(content).toContain('<!-- ASTRYX:START -->');
326
326
  });
327
327
 
328
328
  it('injects into CLAUDE.md at root when it exists', () => {
@@ -334,7 +334,7 @@ describe('installAgentDocs', () => {
334
334
  expect(written).toEqual(['CLAUDE.md']);
335
335
  expect(fs.existsSync(path.join(tmpDir, 'AGENTS.md'))).toBe(false);
336
336
  const claudeContent = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
337
- expect(claudeContent).toContain('<!-- XDS:START -->');
337
+ expect(claudeContent).toContain('<!-- ASTRYX:START -->');
338
338
  expect(claudeContent).toContain('Project rules.');
339
339
  });
340
340
 
@@ -349,8 +349,8 @@ describe('installAgentDocs', () => {
349
349
  expect(written).toContain('CLAUDE.md');
350
350
  const agentsContent = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
351
351
  const claudeContent = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
352
- expect(agentsContent).toContain('<!-- XDS:START -->');
353
- expect(claudeContent).toContain('<!-- XDS:START -->');
352
+ expect(agentsContent).toContain('<!-- ASTRYX:START -->');
353
+ expect(claudeContent).toContain('<!-- ASTRYX:START -->');
354
354
  });
355
355
 
356
356
  it('updates existing .claude/CLAUDE.md', () => {
@@ -363,7 +363,7 @@ describe('installAgentDocs', () => {
363
363
  expect(written).toEqual(['.claude/CLAUDE.md']);
364
364
  const content = fs.readFileSync(path.join(tmpDir, '.claude', 'CLAUDE.md'), 'utf-8');
365
365
  expect(content).toContain('Existing content.');
366
- expect(content).toContain('<!-- XDS:START -->');
366
+ expect(content).toContain('<!-- ASTRYX:START -->');
367
367
  });
368
368
 
369
369
  it('respects --agent claude preset: finds existing CLAUDE.md', () => {
@@ -410,7 +410,7 @@ describe('installAgentDocs', () => {
410
410
 
411
411
  expect(written).toEqual([]);
412
412
  const content = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
413
- expect(content).not.toContain('<!-- XDS:START -->');
413
+ expect(content).not.toContain('<!-- ASTRYX:START -->');
414
414
  expect(content).toBe('# Claude\n\nProject rules only.\n');
415
415
  });
416
416
 
@@ -106,14 +106,14 @@ describe('doctor — individual checks', () => {
106
106
  });
107
107
 
108
108
  it('themes: WARN when theme installed but not wired', () => {
109
- installPkg('@astryxdesign/theme-default', '0.0.14');
109
+ installPkg('@astryxdesign/theme-neutral', '0.0.14');
110
110
  const res = checkThemes({cwd: tmpDir, configTheme: null});
111
111
  expect(res.status).toBe('warn');
112
- expect(res.message).toContain('@astryxdesign/theme-default');
112
+ expect(res.message).toContain('@astryxdesign/theme-neutral');
113
113
  });
114
114
 
115
115
  it('themes: PASS when theme installed and wired via config', () => {
116
- installPkg('@astryxdesign/theme-default', '0.0.14');
116
+ installPkg('@astryxdesign/theme-neutral', '0.0.14');
117
117
  const res = checkThemes({cwd: tmpDir, configTheme: 'default'});
118
118
  expect(res.status).toBe('pass');
119
119
  });
@@ -246,9 +246,9 @@ export function registerInit(program) {
246
246
  humanLog(' Next steps:');
247
247
  humanLog(" 1. Import components: import { Button } from '@astryxdesign/core'");
248
248
  humanLog(' 2. Optionally add a theme:');
249
- humanLog(" import { defaultTheme } from '@astryxdesign/theme-default'");
250
- humanLog(' <Theme theme={defaultTheme}>...</Theme>');
251
- humanLog(` 3. ${run} xds --help for all commands`);
249
+ humanLog(" import { neutralTheme } from '@astryxdesign/theme-neutral'");
250
+ humanLog(' <Theme theme={neutralTheme}>...</Theme>');
251
+ humanLog(` 3. ${run} astryx --help for all commands`);
252
252
  humanLog('');
253
253
  });
254
254
  }
@@ -4,7 +4,7 @@
4
4
  * @file Detect the project's package manager from lockfiles.
5
5
  *
6
6
  * Returns the correct command prefix for running package binaries
7
- * (e.g. 'npx xds', 'yarn xds', 'pnpm exec xds').
7
+ * (e.g. 'npx astryx', 'yarn astryx', 'pnpm exec astryx').
8
8
  */
9
9
 
10
10
  import * as fs from 'node:fs';
@@ -3,24 +3,23 @@
3
3
  'use client';
4
4
 
5
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';
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
13
  import {radiusVars} from '@astryxdesign/core/theme/tokens.stylex';
19
14
 
20
15
  const styles = stylex.create({
21
16
  previewCard: {
22
- borderRadius: radiusVars['--radius-container'],
23
- cursor: 'pointer',
17
+ borderRadius: radiusVars['--radius-element'],
18
+ },
19
+ // Negative margin offsets each card's 8px padding so the grid content stays
20
+ // visually aligned while giving every card a padded hover/click target.
21
+ cardGrid: {
22
+ margin: -8,
24
23
  },
25
24
  });
26
25
 
@@ -213,30 +212,12 @@ const COMPONENT_CATEGORIES = [
213
212
  export default function DocumentationOverviewPage() {
214
213
  return (
215
214
  <Layout
216
- height="fill"
215
+ height="auto"
217
216
  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
217
  content={
237
218
  <LayoutContent padding={8}>
238
219
  <VStack gap={10}>
239
- <Card variant="cyan" padding={10}>
220
+ <Card variant="gray" padding={10}>
240
221
  <HStack gap={8} vAlign="center">
241
222
  <StackItem size="fill">
242
223
  <VStack gap={4}>
@@ -246,11 +227,7 @@ export default function DocumentationOverviewPage() {
246
227
  beautiful, accessible products.
247
228
  </Text>
248
229
  <HStack>
249
- <Button
250
- label="Get started"
251
- variant="primary"
252
- size="lg"
253
- />
230
+ <Button label="Get started" variant="primary" size="lg" />
254
231
  </HStack>
255
232
  </VStack>
256
233
  </StackItem>
@@ -260,25 +237,35 @@ export default function DocumentationOverviewPage() {
260
237
 
261
238
  {COMPONENT_CATEGORIES.map(category => (
262
239
  <VStack key={category.label} gap={4}>
263
- <Text type="display-2">{category.label}</Text>
264
- <Grid columns={{minWidth: 260}} gap={8}>
240
+ <Heading level={2}>{category.label}</Heading>
241
+ <Grid
242
+ columns={{minWidth: 260}}
243
+ gap={2}
244
+ xstyle={styles.cardGrid}>
265
245
  {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>
246
+ <ClickableCard
247
+ key={item.key}
248
+ label={`Open ${item.name}`}
249
+ onClick={() => {}}
250
+ variant="transparent"
251
+ padding={2}>
252
+ <VStack gap={3}>
253
+ <Card
254
+ variant="muted"
255
+ padding={0}
256
+ minHeight={160}
257
+ xstyle={styles.previewCard}
258
+ />
259
+ <VStack gap={0.5}>
260
+ <Text type="body" weight="bold">
261
+ {item.name}
262
+ </Text>
263
+ <Text type="body" color="secondary" maxLines={3}>
264
+ {item.desc}
265
+ </Text>
266
+ </VStack>
280
267
  </VStack>
281
- </VStack>
268
+ </ClickableCard>
282
269
  ))}
283
270
  </Grid>
284
271
  </VStack>
@@ -2,14 +2,8 @@
2
2
 
3
3
  'use client';
4
4
 
5
- import {useState, useMemo} from 'react';
5
+ import {useCallback, useState, useMemo} from 'react';
6
6
  import * as stylex from '@stylexjs/stylex';
7
- import {
8
- SideNav,
9
- SideNavHeading,
10
- SideNavItem,
11
- SideNavSection,
12
- } from '@astryxdesign/core/SideNav';
13
7
  import {Heading, Text} from '@astryxdesign/core/Text';
14
8
  import {Button} from '@astryxdesign/core/Button';
15
9
  import {IconButton} from '@astryxdesign/core/IconButton';
@@ -20,8 +14,10 @@ import {Token} from '@astryxdesign/core/Token';
20
14
  import {Banner} from '@astryxdesign/core/Banner';
21
15
  import {CodeBlock} from '@astryxdesign/core/CodeBlock';
22
16
  import {TabList, Tab} from '@astryxdesign/core/TabList';
17
+ import {Selector} from '@astryxdesign/core/Selector';
23
18
  import {HStack, VStack, StackItem} from '@astryxdesign/core/Stack';
24
19
  import {Layout, LayoutContent, LayoutPanel} from '@astryxdesign/core/Layout';
20
+ import {useMediaQuery} from '@astryxdesign/core/hooks';
25
21
  import {Dialog, DialogHeader} from '@astryxdesign/core/Dialog';
26
22
  import {Divider} from '@astryxdesign/core/Divider';
27
23
  import {Tooltip} from '@astryxdesign/core/Tooltip';
@@ -29,6 +25,7 @@ import {Table, pixel} from '@astryxdesign/core/Table';
29
25
  import {Icon} from '@astryxdesign/core/Icon';
30
26
  import {Section} from '@astryxdesign/core/Section';
31
27
  import {Center} from '@astryxdesign/core/Center';
28
+ import {Outline, type OutlineItem} from '@astryxdesign/core/Outline';
32
29
  import {
33
30
  ArrowTopRightOnSquareIcon,
34
31
  ArrowsPointingOutIcon,
@@ -37,8 +34,25 @@ import {
37
34
 
38
35
  const styles = stylex.create({
39
36
  tabListFlush: {marginInlineStart: '-12px'},
37
+ outlinePanel: {
38
+ position: 'sticky',
39
+ top: 24,
40
+ alignSelf: 'start',
41
+ paddingBlockStart: 120,
42
+ },
40
43
  });
41
44
 
45
+ const COMPONENT_OUTLINE_ITEMS: OutlineItem[] = [
46
+ {id: 'usage', label: 'Usage', level: 2},
47
+ {id: 'best-practices', label: 'Best practices', level: 3},
48
+ {id: 'examples', label: 'Examples', level: 2},
49
+ ];
50
+
51
+ const COMPONENT_OUTLINE_OPTIONS = COMPONENT_OUTLINE_ITEMS.map(item => ({
52
+ value: item.id,
53
+ label: item.label,
54
+ }));
55
+
42
56
  // ---------------------------------------------------------------------------
43
57
  // DialogPreview — stateful dialog preview for component previews
44
58
  // ---------------------------------------------------------------------------
@@ -493,14 +507,21 @@ function getComponentDocs(key: string) {
493
507
  // ComponentDetailView
494
508
  // ---------------------------------------------------------------------------
495
509
 
496
- function ComponentDetailView({
497
- activeNav,
498
- nav,
499
- }: {
500
- activeNav: string;
501
- nav: React.ReactNode;
502
- }) {
510
+ function ComponentDetailView({activeNav}: {activeNav: string}) {
503
511
  const [exampleTabs, setExampleTabs] = useState<Record<string, string>>({});
512
+ const [activeId, setActiveId] = useState<string | undefined>(
513
+ COMPONENT_OUTLINE_ITEMS[0]?.id,
514
+ );
515
+ const isMobile = useMediaQuery('(max-width: 768px)');
516
+
517
+ const scrollToId = useCallback((id: string) => {
518
+ setActiveId(id);
519
+ const target = document.getElementById(id);
520
+ if (target != null) {
521
+ target.scrollIntoView({behavior: 'smooth', block: 'start'});
522
+ window.history.pushState(null, '', `#${id}`);
523
+ }
524
+ }, []);
504
525
 
505
526
  const EXAMPLE_PREVIEWS: Record<string, React.ReactNode[]> = {
506
527
  button: [
@@ -556,25 +577,42 @@ function ComponentDetailView({
556
577
 
557
578
  return (
558
579
  <Layout
559
- height="fill"
580
+ height="auto"
560
581
  contentWidth={960}
561
- start={
562
- <LayoutPanel hasDivider padding={0}>
563
- {nav}
564
- </LayoutPanel>
582
+ end={
583
+ isMobile ? undefined : (
584
+ <LayoutPanel
585
+ isScrollable={false}
586
+ label="On this page"
587
+ role="complementary"
588
+ xstyle={styles.outlinePanel}>
589
+ <Outline
590
+ items={COMPONENT_OUTLINE_ITEMS}
591
+ onActiveIdChange={setActiveId}
592
+ />
593
+ </LayoutPanel>
594
+ )
565
595
  }
566
596
  content={
567
- <LayoutContent padding={8}>
597
+ <LayoutContent isScrollable={false} padding={8}>
568
598
  <VStack gap={8}>
569
599
  <VStack gap={2}>
570
600
  <Text type="display-1">{getComponentName(activeNav)}</Text>
571
601
  <Text type="supporting" color="secondary">
572
602
  March 30, 2026 · Updated 5:40 p.m. PST
573
603
  </Text>
604
+ {isMobile && (
605
+ <Selector
606
+ label="On this page"
607
+ isLabelHidden
608
+ options={COMPONENT_OUTLINE_OPTIONS}
609
+ value={activeId}
610
+ onChange={scrollToId}
611
+ width="100%"
612
+ />
613
+ )}
574
614
  </VStack>
575
615
 
576
- <Divider />
577
-
578
616
  <Card variant="muted" padding={0}>
579
617
  <Center height={360}>
580
618
  {COMPONENT_PREVIEWS[activeNav] ?? (
@@ -586,13 +624,18 @@ function ComponentDetailView({
586
624
  </Card>
587
625
 
588
626
  <VStack gap={4}>
589
- <Heading level={2}>Usage</Heading>
627
+ <Heading id="usage" level={2}>
628
+ Usage
629
+ </Heading>
590
630
  <Text type="large" weight="normal">
591
631
  {docs.usage}
592
632
  </Text>
593
- <Heading level={3}>Best practices</Heading>
633
+ <Heading id="best-practices" level={3}>
634
+ Best practices
635
+ </Heading>
594
636
  <Table
595
637
  data={docs.bestPractices as Record<string, unknown>[]}
638
+ dividers="none"
596
639
  columns={[
597
640
  {
598
641
  key: 'type',
@@ -616,14 +659,15 @@ function ComponentDetailView({
616
659
  },
617
660
  ]}
618
661
  density="spacious"
619
- dividers="rows"
620
662
  />
621
663
  </VStack>
622
664
 
623
665
  <Divider />
624
666
 
625
667
  <VStack gap={4}>
626
- <Heading level={2}>Examples</Heading>
668
+ <Heading id="examples" level={2}>
669
+ Examples
670
+ </Heading>
627
671
  <Text type="large" weight="normal">
628
672
  Explore common configurations, variations, and states for this
629
673
  component.
@@ -675,7 +719,10 @@ function ComponentDetailView({
675
719
  <TabList
676
720
  value={activeTab}
677
721
  onChange={value =>
678
- setExampleTabs(prev => ({...prev, [tabKey]: value}))
722
+ setExampleTabs(prev => ({
723
+ ...prev,
724
+ [tabKey]: value,
725
+ }))
679
726
  }
680
727
  size="sm"
681
728
  xstyle={styles.tabListFlush}>
@@ -685,7 +732,11 @@ function ComponentDetailView({
685
732
  {activeTab === 'description' ? (
686
733
  <Text type="body">{example.description}</Text>
687
734
  ) : (
688
- <CodeBlock code={example.code} language="tsx" />
735
+ <CodeBlock
736
+ code={example.code}
737
+ language="tsx"
738
+ width="100%"
739
+ />
689
740
  )}
690
741
  </VStack>
691
742
  </Section>
@@ -705,31 +756,5 @@ function ComponentDetailView({
705
756
  // ---------------------------------------------------------------------------
706
757
 
707
758
  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
- );
759
+ return <ComponentDetailView activeNav="button" />;
735
760
  }