@astryxdesign/cli 0.1.0 → 0.1.1
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 +2 -2
- package/src/api/doctor.mjs +3 -3
- package/src/api/search.mjs +207 -13
- package/src/api/template.mjs +2 -1
- 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 +10 -2
- 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/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
|
@@ -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
|
}
|
|
@@ -2,22 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
SideNav,
|
|
7
|
-
SideNavHeading,
|
|
8
|
-
SideNavItem,
|
|
9
|
-
SideNavSection,
|
|
10
|
-
} from '@astryxdesign/core/SideNav';
|
|
5
|
+
import {useCallback, useState, type CSSProperties} from 'react';
|
|
11
6
|
import {Heading, Text} from '@astryxdesign/core/Text';
|
|
12
7
|
import {Button} from '@astryxdesign/core/Button';
|
|
13
8
|
import {Card} from '@astryxdesign/core/Card';
|
|
14
9
|
import {DropdownMenu} from '@astryxdesign/core/DropdownMenu';
|
|
15
10
|
import {List, ListItem} from '@astryxdesign/core/List';
|
|
16
11
|
import {CodeBlock} from '@astryxdesign/core/CodeBlock';
|
|
12
|
+
import {Selector} from '@astryxdesign/core/Selector';
|
|
17
13
|
import {HStack, VStack, StackItem} from '@astryxdesign/core/Stack';
|
|
18
14
|
import {Layout, LayoutContent, LayoutPanel} from '@astryxdesign/core/Layout';
|
|
19
15
|
import {Divider} from '@astryxdesign/core/Divider';
|
|
20
16
|
import {Icon} from '@astryxdesign/core/Icon';
|
|
17
|
+
import {Outline, type OutlineItem} from '@astryxdesign/core/Outline';
|
|
18
|
+
import {useMediaQuery} from '@astryxdesign/core/hooks';
|
|
21
19
|
import {
|
|
22
20
|
SparklesIcon,
|
|
23
21
|
ClipboardDocumentIcon,
|
|
@@ -28,35 +26,73 @@ import {
|
|
|
28
26
|
// Main component
|
|
29
27
|
// ---------------------------------------------------------------------------
|
|
30
28
|
|
|
29
|
+
const OUTLINE_ITEMS: OutlineItem[] = [
|
|
30
|
+
{id: 'prerequisites', label: 'Prerequisites', level: 2},
|
|
31
|
+
{id: 'install-package', label: 'Install the package', level: 2},
|
|
32
|
+
{id: 'configure-theming', label: 'Configure theming', level: 2},
|
|
33
|
+
{id: 'next-steps', label: 'Next steps', level: 2},
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
const OUTLINE_OPTIONS = OUTLINE_ITEMS.map(item => ({
|
|
37
|
+
value: item.id,
|
|
38
|
+
label: item.label,
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
const outlinePanel: CSSProperties = {
|
|
42
|
+
position: 'sticky',
|
|
43
|
+
top: 24,
|
|
44
|
+
alignSelf: 'start',
|
|
45
|
+
paddingBlockStart: 120,
|
|
46
|
+
};
|
|
47
|
+
|
|
31
48
|
export default function TechnicalDocumentationPage() {
|
|
49
|
+
const [activeId, setActiveId] = useState<string | undefined>(
|
|
50
|
+
OUTLINE_ITEMS[0]?.id,
|
|
51
|
+
);
|
|
52
|
+
const isMobile = useMediaQuery('(max-width: 768px)');
|
|
53
|
+
|
|
54
|
+
const scrollToId = useCallback((id: string) => {
|
|
55
|
+
setActiveId(id);
|
|
56
|
+
const target = document.getElementById(id);
|
|
57
|
+
if (target != null) {
|
|
58
|
+
target.scrollIntoView({behavior: 'smooth', block: 'start'});
|
|
59
|
+
window.history.pushState(null, '', `#${id}`);
|
|
60
|
+
}
|
|
61
|
+
}, []);
|
|
62
|
+
|
|
32
63
|
return (
|
|
33
64
|
<Layout
|
|
34
|
-
height="
|
|
65
|
+
height="auto"
|
|
35
66
|
contentWidth={960}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
67
|
+
end={
|
|
68
|
+
isMobile ? undefined : (
|
|
69
|
+
<LayoutPanel
|
|
70
|
+
isScrollable={false}
|
|
71
|
+
label="On this page"
|
|
72
|
+
role="complementary"
|
|
73
|
+
style={outlinePanel}>
|
|
74
|
+
<Outline items={OUTLINE_ITEMS} onActiveIdChange={setActiveId} />
|
|
75
|
+
</LayoutPanel>
|
|
76
|
+
)
|
|
45
77
|
}
|
|
46
78
|
content={
|
|
47
|
-
<LayoutContent padding={8}>
|
|
79
|
+
<LayoutContent isScrollable={false} padding={8}>
|
|
48
80
|
<VStack gap={8}>
|
|
49
81
|
<VStack gap={2}>
|
|
50
|
-
<Text type="display-1">
|
|
51
|
-
Getting started with Product Name
|
|
52
|
-
</Text>
|
|
82
|
+
<Text type="display-1">Getting started with Product Name</Text>
|
|
53
83
|
<Text type="supporting" color="secondary">
|
|
54
84
|
Last updated March 30, 2026
|
|
55
85
|
</Text>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
86
|
+
{isMobile && (
|
|
87
|
+
<Selector
|
|
88
|
+
label="On this page"
|
|
89
|
+
isLabelHidden
|
|
90
|
+
options={OUTLINE_OPTIONS}
|
|
91
|
+
value={activeId}
|
|
92
|
+
onChange={scrollToId}
|
|
93
|
+
width="100%"
|
|
94
|
+
/>
|
|
95
|
+
)}
|
|
60
96
|
</VStack>
|
|
61
97
|
|
|
62
98
|
<Card>
|
|
@@ -64,11 +100,7 @@ export default function TechnicalDocumentationPage() {
|
|
|
64
100
|
<HStack gap={2} vAlign="center">
|
|
65
101
|
<StackItem size="fill">
|
|
66
102
|
<HStack gap={2} vAlign="center">
|
|
67
|
-
<Icon
|
|
68
|
-
icon={SparklesIcon}
|
|
69
|
-
size="sm"
|
|
70
|
-
color="secondary"
|
|
71
|
-
/>
|
|
103
|
+
<Icon icon={SparklesIcon} size="sm" color="secondary" />
|
|
72
104
|
<Text type="body" weight="semibold">
|
|
73
105
|
AI Assistance
|
|
74
106
|
</Text>
|
|
@@ -103,15 +135,17 @@ export default function TechnicalDocumentationPage() {
|
|
|
103
135
|
</HStack>
|
|
104
136
|
<Text type="body" color="secondary">
|
|
105
137
|
Help me get set up with Product Name. Based on my project, do
|
|
106
|
-
the following: 1. Install @astryxdesign/core and the StyleX
|
|
107
|
-
2. Wrap my app in ThemeProvider. 3. Replace one
|
|
108
|
-
component with an Astryx equivalent.
|
|
138
|
+
the following: 1. Install @astryxdesign/core and the StyleX
|
|
139
|
+
compiler. 2. Wrap my app in ThemeProvider. 3. Replace one
|
|
140
|
+
existing component with an Astryx equivalent.
|
|
109
141
|
</Text>
|
|
110
142
|
</VStack>
|
|
111
143
|
</Card>
|
|
112
144
|
|
|
113
145
|
<VStack gap={4}>
|
|
114
|
-
<Heading level={2}>
|
|
146
|
+
<Heading id="prerequisites" level={2}>
|
|
147
|
+
Prerequisites
|
|
148
|
+
</Heading>
|
|
115
149
|
<List density="compact" listStyle="disc">
|
|
116
150
|
<ListItem label="Node.js 18+" />
|
|
117
151
|
<ListItem label="React 18 or 19" />
|
|
@@ -122,7 +156,9 @@ export default function TechnicalDocumentationPage() {
|
|
|
122
156
|
<Divider />
|
|
123
157
|
|
|
124
158
|
<VStack gap={4}>
|
|
125
|
-
<Heading level={2}>
|
|
159
|
+
<Heading id="install-package" level={2}>
|
|
160
|
+
Install the package
|
|
161
|
+
</Heading>
|
|
126
162
|
<Text type="body">
|
|
127
163
|
Every project starts with installing the core package. This
|
|
128
164
|
gives you access to all components, tokens, and utilities.
|
|
@@ -131,54 +167,57 @@ export default function TechnicalDocumentationPage() {
|
|
|
131
167
|
<Text type="body" weight="bold">
|
|
132
168
|
Step 1: Install the core package
|
|
133
169
|
</Text>
|
|
134
|
-
<
|
|
135
|
-
|
|
136
|
-
|
|
170
|
+
<CodeBlock
|
|
171
|
+
code="npm install @astryxdesign/core"
|
|
172
|
+
language="bash"
|
|
173
|
+
width="100%"
|
|
174
|
+
/>
|
|
137
175
|
</VStack>
|
|
138
176
|
<VStack gap={2}>
|
|
139
177
|
<Text type="body" weight="bold">
|
|
140
|
-
Step 2:
|
|
178
|
+
Step 2: Import the precompiled styles
|
|
141
179
|
</Text>
|
|
142
180
|
<Text type="body" color="secondary">
|
|
143
|
-
Astryx
|
|
144
|
-
|
|
181
|
+
Astryx ships precompiled CSS, so there is no build plugin to
|
|
182
|
+
configure. Import the reset and component stylesheets once at
|
|
183
|
+
your app entry point.
|
|
145
184
|
</Text>
|
|
146
|
-
<
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
185
|
+
<CodeBlock
|
|
186
|
+
code={`import '@astryxdesign/core/reset.css';
|
|
187
|
+
import '@astryxdesign/core/astryx.css';`}
|
|
188
|
+
language="tsx"
|
|
189
|
+
width="100%"
|
|
190
|
+
/>
|
|
152
191
|
</VStack>
|
|
153
192
|
<VStack gap={2}>
|
|
154
193
|
<Text type="body" weight="bold">
|
|
155
194
|
Step 3: Import your first component
|
|
156
195
|
</Text>
|
|
157
|
-
<
|
|
158
|
-
|
|
159
|
-
code={`import { Button } from '@astryxdesign/core/Button';
|
|
196
|
+
<CodeBlock
|
|
197
|
+
code={`import { Button } from '@astryxdesign/core/Button';
|
|
160
198
|
|
|
161
199
|
export default function App() {
|
|
162
200
|
return <Button label="Hello Astryx" variant="primary" />;
|
|
163
201
|
}`}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
202
|
+
language="tsx"
|
|
203
|
+
width="100%"
|
|
204
|
+
/>
|
|
167
205
|
</VStack>
|
|
168
206
|
</VStack>
|
|
169
207
|
|
|
170
208
|
<Divider />
|
|
171
209
|
|
|
172
210
|
<VStack gap={4}>
|
|
173
|
-
<Heading level={2}>
|
|
211
|
+
<Heading id="configure-theming" level={2}>
|
|
212
|
+
Configure theming
|
|
213
|
+
</Heading>
|
|
174
214
|
<Text type="body">
|
|
175
215
|
Astryx ships with a default theme that works out of the box. To
|
|
176
216
|
customize colors, typography, and spacing, wrap your app in a
|
|
177
217
|
theme provider.
|
|
178
218
|
</Text>
|
|
179
|
-
<
|
|
180
|
-
|
|
181
|
-
code={`import { ThemeProvider } from '@astryxdesign/core/Theme';
|
|
219
|
+
<CodeBlock
|
|
220
|
+
code={`import { ThemeProvider } from '@astryxdesign/core/Theme';
|
|
182
221
|
|
|
183
222
|
export default function App({ children }) {
|
|
184
223
|
return (
|
|
@@ -187,9 +226,9 @@ export default function App({ children }) {
|
|
|
187
226
|
</ThemeProvider>
|
|
188
227
|
);
|
|
189
228
|
}`}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
229
|
+
language="tsx"
|
|
230
|
+
width="100%"
|
|
231
|
+
/>
|
|
193
232
|
<Text type="body" color="secondary">
|
|
194
233
|
See the theming guide for the full list of customizable tokens.
|
|
195
234
|
</Text>
|
|
@@ -198,7 +237,9 @@ export default function App({ children }) {
|
|
|
198
237
|
<Divider />
|
|
199
238
|
|
|
200
239
|
<VStack gap={4}>
|
|
201
|
-
<Heading level={2}>
|
|
240
|
+
<Heading id="next-steps" level={2}>
|
|
241
|
+
Next steps
|
|
242
|
+
</Heading>
|
|
202
243
|
<List density="compact" listStyle="disc">
|
|
203
244
|
<ListItem label="Fundamental concepts — How theming, layout, and composition work" />
|
|
204
245
|
<ListItem label="Component API reference — Props, variants, and examples for every component" />
|