@astryxdesign/cli 0.1.0 → 0.1.1-canary.080d887
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 +20 -9
- package/src/api/discover.mjs +78 -26
- package/src/api/doctor.mjs +3 -3
- package/src/api/layout.mjs +301 -0
- package/src/api/layout.test.mjs +238 -0
- package/src/api/search.mjs +207 -13
- package/src/api/template.mjs +193 -51
- 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/gap-report.mjs +17 -9
- package/src/commands/gap-report.test.mjs +21 -16
- 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/layout.mjs +139 -0
- package/src/commands/swizzle-gap-safety.test.mjs +1 -1
- package/src/commands/swizzle.mjs +51 -23
- 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 +292 -177
- package/src/commands/upgrade.test.mjs +41 -27
- package/src/config.mjs +31 -0
- package/src/config.test.mjs +24 -0
- package/src/index.mjs +5 -0
- package/src/lib/config-schema.mjs +119 -0
- package/src/lib/config.mjs +45 -6
- package/src/lib/config.test.mjs +91 -0
- package/src/lib/error-codes.mjs +11 -0
- package/src/lib/integrations.mjs +155 -0
- package/src/lib/integrations.test.mjs +154 -0
- package/src/lib/levenshtein.mjs +29 -0
- package/src/lib/manifest.mjs +6 -0
- package/src/lib/package-scanner.mjs +31 -7
- package/src/lib/string-utils.mjs +5 -14
- package/src/lib/xle/browser.d.ts +91 -0
- package/src/lib/xle/browser.mjs +120 -0
- package/src/lib/xle/expand.mjs +622 -0
- package/src/lib/xle/parse.mjs +581 -0
- package/src/lib/xle/print.mjs +174 -0
- package/src/lib/xle/registry-core.mjs +170 -0
- package/src/lib/xle/registry.mjs +237 -0
- package/src/lib/xle/splice.mjs +137 -0
- package/src/lib/xle/validate.mjs +356 -0
- package/src/lib/xle/xle.test.mjs +333 -0
- package/src/types/config.d.ts +99 -0
- package/src/types/error-codes.d.ts +1 -0
- package/src/utils/github.mjs +12 -27
- 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/DateInput/DateInputDateRange.doc.mjs +2 -2
- 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/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/Slider/SliderShowcase.tsx +10 -1
- package/templates/blocks/components/ToggleButton/ToggleButtonGroup.doc.mjs +1 -1
- 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
- package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.doc.mjs +0 -14
- package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.tsx +0 -67
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
-
import {useRef, useState} from 'react';
|
|
6
|
-
import * as stylex from '@stylexjs/stylex';
|
|
7
|
-
import {spacingVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
5
|
+
import {useRef, useState, type CSSProperties} from 'react';
|
|
8
6
|
|
|
9
7
|
import {
|
|
10
8
|
HStack,
|
|
@@ -55,56 +53,66 @@ import {
|
|
|
55
53
|
// Below this width the split-pane collapses to a single chat column. Shared by
|
|
56
54
|
// the CSS container query and the JS check in openArtifact so they can't drift.
|
|
57
55
|
const MOBILE_MAX_WIDTH = 767;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
})
|
|
56
|
+
|
|
57
|
+
const root: CSSProperties = {
|
|
58
|
+
height: '100dvh',
|
|
59
|
+
width: '100%',
|
|
60
|
+
containerType: 'inline-size',
|
|
61
|
+
containerName: 'artifact',
|
|
62
|
+
};
|
|
63
|
+
const chatColumn: CSSProperties = {
|
|
64
|
+
flex: 1,
|
|
65
|
+
width: '100%',
|
|
66
|
+
minWidth: 0,
|
|
67
|
+
height: '100%',
|
|
68
|
+
};
|
|
69
|
+
const chatLayout: CSSProperties = {
|
|
70
|
+
flex: 1,
|
|
71
|
+
minHeight: 0,
|
|
72
|
+
};
|
|
73
|
+
const artifactCard: CSSProperties = {
|
|
74
|
+
marginBlockStart: 'var(--spacing-2)',
|
|
75
|
+
};
|
|
76
|
+
const artifactScroll: CSSProperties = {
|
|
77
|
+
flex: 1,
|
|
78
|
+
overflowY: 'auto',
|
|
79
|
+
};
|
|
80
|
+
const articleBody: CSSProperties = {
|
|
81
|
+
maxWidth: 720,
|
|
82
|
+
marginInline: 'auto',
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Runtime width for the artifact panel, passed in via the --artifact-panel-width
|
|
86
|
+
// custom property so the MOBILE container query can still override it to 100%
|
|
87
|
+
// (an inline `width` would beat the class rule). The container query lives in a
|
|
88
|
+
// plain <style> tag below so it needs NO CSS compiler.
|
|
89
|
+
const artifactPanelWidthVar = (size: number | string): CSSProperties =>
|
|
90
|
+
({
|
|
91
|
+
'--artifact-panel-width': typeof size === 'number' ? `${size}px` : size,
|
|
92
|
+
}) as CSSProperties;
|
|
93
|
+
|
|
94
|
+
const AI_CHAT_CSS = `
|
|
95
|
+
.ai-chat-resize-handle {
|
|
96
|
+
display: flex;
|
|
97
|
+
}
|
|
98
|
+
.ai-chat-artifact-panel {
|
|
99
|
+
overflow: hidden;
|
|
100
|
+
display: flex;
|
|
101
|
+
flex-direction: column;
|
|
102
|
+
width: var(--artifact-panel-width);
|
|
103
|
+
flex-shrink: 0;
|
|
104
|
+
}
|
|
105
|
+
@container artifact (max-width: ${MOBILE_MAX_WIDTH}px) {
|
|
106
|
+
.ai-chat-resize-handle {
|
|
107
|
+
display: none;
|
|
108
|
+
}
|
|
109
|
+
.ai-chat-artifact-panel {
|
|
110
|
+
display: none;
|
|
111
|
+
width: 100%;
|
|
112
|
+
flex-shrink: 1;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
`;
|
|
108
116
|
|
|
109
117
|
// Artifact content
|
|
110
118
|
|
|
@@ -225,8 +233,8 @@ function MobileArtifactActions() {
|
|
|
225
233
|
// Scrollable artifact body — the formatted document.
|
|
226
234
|
function ArtifactBody() {
|
|
227
235
|
return (
|
|
228
|
-
<Section variant="transparent"
|
|
229
|
-
<VStack gap={2}
|
|
236
|
+
<Section variant="transparent" style={artifactScroll}>
|
|
237
|
+
<VStack gap={2} style={articleBody}>
|
|
230
238
|
<Heading level={1}>{ARTIFACT_TITLE}</Heading>
|
|
231
239
|
<Markdown>{ARTIFACT_CONTENT}</Markdown>
|
|
232
240
|
</VStack>
|
|
@@ -243,7 +251,7 @@ function ArtifactCard({onOpen}: {onOpen: () => void}) {
|
|
|
243
251
|
variant="muted"
|
|
244
252
|
padding={3}
|
|
245
253
|
maxWidth={360}
|
|
246
|
-
|
|
254
|
+
style={artifactCard}>
|
|
247
255
|
<HStack gap={3} vAlign="center" width="100%">
|
|
248
256
|
<Icon icon={DocumentTextIcon} size="md" color="secondary" />
|
|
249
257
|
<StackItem size="fill">
|
|
@@ -288,17 +296,18 @@ export default function AIChatConversationTemplate() {
|
|
|
288
296
|
};
|
|
289
297
|
|
|
290
298
|
return (
|
|
291
|
-
<VStack ref={rootRef}
|
|
299
|
+
<VStack ref={rootRef} style={root}>
|
|
300
|
+
<style>{AI_CHAT_CSS}</style>
|
|
292
301
|
<Layout
|
|
293
302
|
height="fill"
|
|
294
303
|
content={
|
|
295
304
|
<LayoutContent padding={0}>
|
|
296
305
|
<HStack height="100%">
|
|
297
306
|
{/* Chat column — flexes to fill the space the artifact leaves */}
|
|
298
|
-
<VStack
|
|
307
|
+
<VStack style={chatColumn}>
|
|
299
308
|
<ChatLayout
|
|
300
309
|
density="spacious"
|
|
301
|
-
|
|
310
|
+
style={chatLayout}
|
|
302
311
|
composer={
|
|
303
312
|
<ChatComposer
|
|
304
313
|
onSubmit={() => {}}
|
|
@@ -677,17 +686,15 @@ The fix is to catch \`TokenExpiredError\` specifically and attempt a refresh bef
|
|
|
677
686
|
pillPlacement="start"
|
|
678
687
|
hasDivider
|
|
679
688
|
label="Resize artifact panel"
|
|
680
|
-
|
|
689
|
+
className="ai-chat-resize-handle"
|
|
681
690
|
/>
|
|
682
691
|
|
|
683
692
|
{/* Toolbar as the card header, body below */}
|
|
684
693
|
<Card
|
|
685
694
|
variant="transparent"
|
|
686
695
|
height="100%"
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
dynamicStyles.artifactPanelWidth(artifactResize.size),
|
|
690
|
-
]}>
|
|
696
|
+
className="ai-chat-artifact-panel"
|
|
697
|
+
style={artifactPanelWidthVar(artifactResize.size)}>
|
|
691
698
|
<Toolbar
|
|
692
699
|
label="Artifact actions"
|
|
693
700
|
dividers={['bottom']}
|
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
-
import {useRef, useState} from 'react';
|
|
6
|
-
import * as stylex from '@stylexjs/stylex';
|
|
7
|
-
import {spacingVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
5
|
+
import {useRef, useState, type CSSProperties} from 'react';
|
|
8
6
|
|
|
9
7
|
import {Layout, LayoutContent, VStack, HStack} from '@astryxdesign/core/Layout';
|
|
10
8
|
import {Text, Heading} from '@astryxdesign/core/Text';
|
|
@@ -40,12 +38,10 @@ import {
|
|
|
40
38
|
LightBulbIcon,
|
|
41
39
|
} from '@heroicons/react/24/outline';
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
categories: {paddingInline: spacingVars['--spacing-3']},
|
|
48
|
-
});
|
|
41
|
+
// Fill the content area so the greeting and composer stay vertically centered.
|
|
42
|
+
const pageStyle: CSSProperties = {minHeight: '100%'};
|
|
43
|
+
const composerInput: CSSProperties = {minHeight: 84};
|
|
44
|
+
const categories: CSSProperties = {paddingInline: 'var(--spacing-3)'};
|
|
49
45
|
|
|
50
46
|
// Suggestion cards shown once a category is selected.
|
|
51
47
|
const CATEGORY_SUGGESTIONS: Record<
|
|
@@ -311,7 +307,7 @@ export default function AIChatTemplate() {
|
|
|
311
307
|
padding={6}
|
|
312
308
|
content={
|
|
313
309
|
<LayoutContent>
|
|
314
|
-
<VStack gap={8} vAlign="center"
|
|
310
|
+
<VStack gap={8} vAlign="center" style={pageStyle}>
|
|
315
311
|
{/* Greeting */}
|
|
316
312
|
<VStack gap={1}>
|
|
317
313
|
<HStack gap={2} vAlign="center">
|
|
@@ -333,7 +329,7 @@ export default function AIChatTemplate() {
|
|
|
333
329
|
<ChatComposerInput
|
|
334
330
|
handleRef={composerInputRef}
|
|
335
331
|
triggers={composerTriggers}
|
|
336
|
-
|
|
332
|
+
style={composerInput}
|
|
337
333
|
onFiles={files =>
|
|
338
334
|
setAttachments(prev => [...prev, ...files.map(f => f.name)])
|
|
339
335
|
}
|
|
@@ -435,7 +431,7 @@ export default function AIChatTemplate() {
|
|
|
435
431
|
/>
|
|
436
432
|
|
|
437
433
|
{/* Category filters + suggestion cards */}
|
|
438
|
-
<VStack gap={6}
|
|
434
|
+
<VStack gap={6} style={categories}>
|
|
439
435
|
<ToggleButtonGroup
|
|
440
436
|
label="Category"
|
|
441
437
|
value={category}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import type {CSSProperties} from 'react';
|
|
6
6
|
import {
|
|
7
7
|
VStack,
|
|
8
8
|
HStack,
|
|
@@ -19,18 +19,16 @@ import {ArrowRightIcon} from '@heroicons/react/20/solid';
|
|
|
19
19
|
const IMAGE_URL =
|
|
20
20
|
'https://lookaside.facebook.com/assets/astryx/light-scene-horizontal-1.png';
|
|
21
21
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
},
|
|
33
|
-
});
|
|
22
|
+
const heroImage: CSSProperties = {
|
|
23
|
+
width: '100%',
|
|
24
|
+
height: '100%',
|
|
25
|
+
objectFit: 'cover',
|
|
26
|
+
};
|
|
27
|
+
const heroFrame: CSSProperties = {
|
|
28
|
+
maxWidth: 1200,
|
|
29
|
+
marginInline: 'auto',
|
|
30
|
+
borderRadius: 'var(--radius-page)',
|
|
31
|
+
};
|
|
34
32
|
|
|
35
33
|
export default function CenteredHero() {
|
|
36
34
|
return (
|
|
@@ -68,9 +66,9 @@ export default function CenteredHero() {
|
|
|
68
66
|
</HStack>
|
|
69
67
|
</VStack>
|
|
70
68
|
<Section variant="transparent" padding={0}>
|
|
71
|
-
<AspectRatio ratio={16 / 9}
|
|
69
|
+
<AspectRatio ratio={16 / 9} style={heroFrame}>
|
|
72
70
|
<img
|
|
73
|
-
{
|
|
71
|
+
style={heroImage}
|
|
74
72
|
src={IMAGE_URL}
|
|
75
73
|
alt="A bright, colorful lifestyle scene"
|
|
76
74
|
/>
|
|
@@ -2,41 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
-
import {useState} from 'react';
|
|
5
|
+
import {useState, type CSSProperties} from 'react';
|
|
6
6
|
import {VStack, Layout, LayoutContent} from '@astryxdesign/core/Layout';
|
|
7
7
|
import {Center} from '@astryxdesign/core/Center';
|
|
8
8
|
import {Text, Heading} from '@astryxdesign/core/Text';
|
|
9
9
|
import {Grid} from '@astryxdesign/core/Grid';
|
|
10
10
|
import {Section} from '@astryxdesign/core/Section';
|
|
11
11
|
import {TabList, Tab} from '@astryxdesign/core/TabList';
|
|
12
|
-
import * as stylex from '@stylexjs/stylex';
|
|
13
12
|
|
|
14
13
|
// ─── Styles ─────────────────────────────────────────────────────────────────
|
|
15
14
|
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
},
|
|
39
|
-
});
|
|
15
|
+
const outer: CSSProperties = {
|
|
16
|
+
maxWidth: 1200,
|
|
17
|
+
width: '100%',
|
|
18
|
+
paddingInline: 'var(--spacing-6)',
|
|
19
|
+
paddingBlock: 'var(--spacing-8)',
|
|
20
|
+
};
|
|
21
|
+
const imageWrapper: CSSProperties = {
|
|
22
|
+
position: 'relative',
|
|
23
|
+
aspectRatio: '3/2',
|
|
24
|
+
borderRadius: 'var(--radius-container)',
|
|
25
|
+
overflow: 'clip',
|
|
26
|
+
};
|
|
27
|
+
const textCenter: CSSProperties = {
|
|
28
|
+
textAlign: 'center',
|
|
29
|
+
};
|
|
30
|
+
const imgFill: CSSProperties = {
|
|
31
|
+
position: 'absolute',
|
|
32
|
+
inset: 0,
|
|
33
|
+
width: '100%',
|
|
34
|
+
height: '100%',
|
|
35
|
+
objectFit: 'cover',
|
|
36
|
+
};
|
|
40
37
|
|
|
41
38
|
// ─── Gallery Data ───────────────────────────────────────────────────────────
|
|
42
39
|
|
|
@@ -117,11 +114,11 @@ export default function ClassicGalleryTemplate() {
|
|
|
117
114
|
content={
|
|
118
115
|
<LayoutContent padding={0}>
|
|
119
116
|
<Center axis="horizontal">
|
|
120
|
-
<VStack gap={8}
|
|
117
|
+
<VStack gap={8} style={outer}>
|
|
121
118
|
{/* Header */}
|
|
122
119
|
<Center axis="horizontal">
|
|
123
120
|
<Section variant="transparent" maxWidth={680} padding={0}>
|
|
124
|
-
<VStack gap={4} hAlign="center"
|
|
121
|
+
<VStack gap={4} hAlign="center" style={textCenter}>
|
|
125
122
|
<VStack gap={2} hAlign="center">
|
|
126
123
|
<Heading level={1}>
|
|
127
124
|
Make every day a little more delightful, one detail at a
|
|
@@ -150,12 +147,8 @@ export default function ClassicGalleryTemplate() {
|
|
|
150
147
|
{/* Gallery Grid */}
|
|
151
148
|
<Grid columns={{minWidth: 260, repeat: 'fit'}} gap={4}>
|
|
152
149
|
{filteredImages.map((image, i) => (
|
|
153
|
-
<div key={i} {
|
|
154
|
-
<img
|
|
155
|
-
src={image.src}
|
|
156
|
-
alt={image.alt}
|
|
157
|
-
{...stylex.props(styles.imgFill)}
|
|
158
|
-
/>
|
|
150
|
+
<div key={i} style={imageWrapper}>
|
|
151
|
+
<img src={image.src} alt={image.alt} style={imgFill} />
|
|
159
152
|
</div>
|
|
160
153
|
))}
|
|
161
154
|
</Grid>
|
|
@@ -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>
|