@astryxdesign/cli 0.1.0 → 0.1.1-canary.129bf0e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +68 -0
- package/README.md +117 -75
- package/bin/astryx.mjs +22 -7
- package/docs/getting-started.doc.mjs +11 -11
- package/docs/icons.doc.mjs +1 -1
- package/docs/migration.doc.mjs +2 -2
- package/docs/shape.doc.mjs +1 -1
- package/docs/styling.doc.mjs +3 -4
- package/docs/theme.doc.dense.mjs +2 -2
- package/docs/theme.doc.mjs +14 -0
- package/docs/theme.doc.zh.mjs +2 -2
- package/docs/working-with-ai.doc.mjs +4 -4
- package/package.json +8 -8
- package/src/api/doctor.mjs +3 -3
- package/src/api/search.mjs +207 -13
- package/src/api/template.mjs +62 -11
- package/src/api/template.test.mjs +2 -0
- package/src/codemods/__tests__/registry.test.mjs +1 -0
- package/src/codemods/registry.mjs +1 -0
- package/src/codemods/runner.mjs +105 -51
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-config-surfaces.test.mjs +116 -0
- package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +51 -0
- package/src/codemods/transforms/v0.1.0/index.mjs +28 -0
- package/src/codemods/transforms/v0.1.0/migrate-xds-config-surfaces.mjs +230 -0
- package/src/codemods/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +84 -0
- package/src/commands/agent-docs.mjs +119 -66
- package/src/commands/agent-docs.path-safety.test.mjs +1 -1
- package/src/commands/agent-docs.test.mjs +87 -31
- package/src/commands/build-theme.import-path.test.mjs +1 -1
- package/src/commands/build-theme.path-safety.test.mjs +1 -1
- package/src/commands/build-theme.prose.test.mjs +1 -1
- package/src/commands/build.mjs +196 -0
- package/src/commands/component-package.test.mjs +1 -1
- package/src/commands/component.test.mjs +1 -1
- package/src/commands/docs.test.mjs +1 -1
- package/src/commands/doctor.test.mjs +1 -1
- package/src/commands/external-showcase.test.mjs +1 -1
- package/src/commands/init.mjs +43 -9
- package/src/commands/init.next-steps.test.mjs +46 -0
- package/src/commands/interactive-guard.test.mjs +1 -1
- package/src/commands/json-contract.test.mjs +10 -3
- package/src/commands/swizzle-gap-safety.test.mjs +1 -1
- package/src/commands/swizzle.path-safety.test.mjs +1 -1
- package/src/commands/template.path-safety.test.mjs +1 -1
- package/src/commands/template.test.mjs +1 -1
- package/src/commands/upgrade.mjs +353 -169
- package/src/commands/upgrade.test.mjs +41 -27
- package/src/index.mjs +1 -0
- package/src/lib/config.mjs +12 -0
- package/src/lib/config.test.mjs +42 -0
- package/src/lib/error-codes.mjs +3 -0
- package/src/types/error-codes.d.ts +1 -0
- package/src/utils/interactive.mjs +1 -1
- package/src/utils/interactive.test.mjs +2 -0
- package/src/utils/package-manager.mjs +1 -1
- package/src/utils/package-manager.test.mjs +1 -1
- package/src/utils/path-safety.test.mjs +1 -1
- package/src/utils/paths.test.mjs +8 -8
- package/src/utils/update-check.mjs +4 -26
- package/src/utils/update-check.test.mjs +2 -64
- package/templates/blocks/components/AppShell/AppShellContentOnly.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellShowcase.tsx +1 -10
- package/templates/blocks/components/AppShell/AppShellSideNavOnly.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellTopNavOnly.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellTopNavWithSideNav.tsx +1 -9
- package/templates/blocks/components/AppShell/AppShellWithBanner.tsx +1 -9
- package/templates/blocks/components/AspectRatio/AspectRatioShowcase.tsx +12 -19
- package/templates/blocks/components/Banner/BannerShowcase.tsx +1 -8
- package/templates/blocks/components/Blockquote/BlockquoteShowcase.tsx +1 -8
- package/templates/blocks/components/Carousel/CarouselShowcase.tsx +2 -12
- package/templates/blocks/components/ChatComposerDrawer/ChatComposerDrawerShowcase.tsx +6 -9
- package/templates/blocks/components/ChatLayout/ChatLayoutPanelChat.tsx +10 -12
- package/templates/blocks/components/ChatMessageList/ChatMessageListDensity.tsx +1 -9
- package/templates/blocks/components/ChatMessageList/ChatMessageListFullFeatured.tsx +1 -9
- package/templates/blocks/components/ChatMessageList/ChatMessageListShowcase.tsx +1 -9
- package/templates/blocks/components/ChatMessageMetadata/ChatMessageMetadataShowcase.tsx +1 -8
- package/templates/blocks/components/ChatSendButton/ChatSendButtonInComposer.tsx +1 -8
- package/templates/blocks/components/Citation/CitationInlineText.tsx +4 -4
- package/templates/blocks/components/Code/CodeInlineInParagraph.tsx +1 -8
- package/templates/blocks/components/CodeBlock/CodeBlockBashCommand.tsx +1 -1
- package/templates/blocks/components/CodeBlock/CodeBlockJSONConfig.tsx +1 -1
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.doc.mjs +15 -0
- package/templates/blocks/components/CommandPaletteEmpty/CommandPaletteEmptyShowcase.tsx +26 -0
- package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemShowcase.tsx +9 -12
- package/templates/blocks/components/ContextMenu/ContextMenuShowcase.tsx +13 -15
- package/templates/blocks/components/Divider/DividerShowcase.tsx +1 -8
- package/templates/blocks/components/Divider/DividerVertical.tsx +7 -9
- package/templates/blocks/components/Field/FieldShowcase.tsx +1 -8
- package/templates/blocks/components/FormLayout/FormLayoutHorizontal.tsx +1 -6
- package/templates/blocks/components/Grid/GridResponsiveAutoFit.tsx +1 -9
- package/templates/blocks/components/HoverCard/HoverCardInlineTextHoverCard.tsx +4 -6
- package/templates/blocks/components/HoverCard/HoverCardInteractiveContent.tsx +1 -6
- package/templates/blocks/components/HoverCard/HoverCardProfileHoverCard.tsx +2 -8
- package/templates/blocks/components/HoverCard/HoverCardShowcase.tsx +1 -8
- package/templates/blocks/components/MoreMenu/MoreMenuInToolbar.tsx +2 -12
- package/templates/blocks/components/OverflowList/OverflowListOverflowBadges.tsx +8 -11
- package/templates/blocks/components/OverflowList/OverflowListOverflowDropdownActions.tsx +9 -12
- package/templates/blocks/components/Overlay/OverlayBottomStrip.tsx +4 -17
- package/templates/blocks/components/Overlay/OverlayHoverReveal.tsx +15 -16
- package/templates/blocks/components/Overlay/OverlayShowcase.tsx +5 -21
- package/templates/blocks/components/Pagination/PaginationDotsCarousel.tsx +2 -14
- package/templates/blocks/components/Pagination/PaginationPageSize.tsx +12 -14
- package/templates/blocks/components/Pagination/PaginationVariants.tsx +1 -8
- package/templates/blocks/components/Pagination/PaginationWithTable.tsx +2 -14
- package/templates/blocks/components/Tokenizer/TokenizerClear.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerCreatable.tsx +2 -7
- package/templates/blocks/components/Tokenizer/TokenizerEndContent.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerIcon.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerMaxEntries.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerOverflow.tsx +2 -7
- package/templates/blocks/components/Tokenizer/TokenizerShowcase.tsx +1 -6
- package/templates/blocks/components/Tokenizer/TokenizerStates.tsx +4 -9
- package/templates/blocks/components/Toolbar/ToolbarCardHeader.tsx +1 -10
- package/templates/blocks/components/Toolbar/ToolbarSizes.tsx +1 -8
- package/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +1 -8
- package/templates/blocks/components/Toolbar/ToolbarThreeSlot.tsx +1 -10
- package/templates/blocks/components/Toolbar/ToolbarWithTabs.tsx +8 -11
- package/templates/pages/ai-chat/page.tsx +71 -64
- package/templates/pages/ai-chat-landing/page.tsx +8 -12
- package/templates/pages/centered-hero/page.tsx +13 -15
- package/templates/pages/classic-gallery/page.tsx +27 -34
- package/templates/pages/detail-page/page.tsx +18 -18
- package/templates/pages/documentation/page.tsx +42 -58
- package/templates/pages/documentation-design/page.tsx +82 -60
- package/templates/pages/documentation-technical/page.tsx +101 -60
- package/templates/pages/editor/page.tsx +42 -54
- package/templates/pages/file-explorer/page.tsx +13 -16
- package/templates/pages/form-two-column/page.tsx +13 -17
- package/templates/pages/gallery-hero/page.tsx +13 -15
- package/templates/pages/ide/page.tsx +188 -264
- package/templates/pages/library/page.tsx +16 -23
- package/templates/pages/login/page.tsx +14 -18
- package/templates/pages/login-card/page.tsx +14 -18
- package/templates/pages/login-split/page.tsx +50 -48
- package/templates/pages/login-sso/page.tsx +9 -13
- package/templates/pages/mixed-gallery/page.tsx +51 -45
- package/templates/pages/payment-form/page.tsx +56 -70
- package/templates/pages/product-detail/page.tsx +27 -33
- package/templates/pages/product-gallery/page.tsx +7 -13
- package/templates/pages/settings-dialog/page.tsx +35 -43
- package/templates/pages/settings-sidebar/page.tsx +39 -47
- package/templates/pages/side-gallery/page.tsx +6 -9
- package/templates/pages/table-grouped/page.tsx +11 -15
- package/templates/pages/theme-showcase/page.tsx +33 -37
|
@@ -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" />
|
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
-
import {useState, useCallback} from 'react';
|
|
6
|
-
import * as stylex from '@stylexjs/stylex';
|
|
7
|
-
import {colorVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
5
|
+
import {useState, useCallback, type CSSProperties} from 'react';
|
|
8
6
|
import {useMediaQuery} from '@astryxdesign/core/hooks';
|
|
9
7
|
import {Button} from '@astryxdesign/core/Button';
|
|
10
8
|
import {Card} from '@astryxdesign/core/Card';
|
|
@@ -307,42 +305,32 @@ function defaultProps(type: BlockType): Record<string, unknown> {
|
|
|
307
305
|
// the responsive canvas max-width, a selection ring on the active block card,
|
|
308
306
|
// and the circular icon chip's surface.
|
|
309
307
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
panelWidth: {
|
|
321
|
-
width: {default: 320, '@media (max-width: 768px)': '100%'},
|
|
322
|
-
flexShrink: 0,
|
|
323
|
-
},
|
|
324
|
-
// Canvas reflows to the chosen viewport width; VStack has no maxWidth prop.
|
|
325
|
-
canvas: (maxWidth: number) => ({
|
|
326
|
-
maxWidth,
|
|
327
|
-
width: '100%',
|
|
328
|
-
marginInline: 'auto',
|
|
329
|
-
}),
|
|
330
|
-
clickable: {
|
|
331
|
-
cursor: 'pointer',
|
|
332
|
-
},
|
|
333
|
-
// Selection ring on the active block — Card has no `isSelected` state.
|
|
334
|
-
selectedCard: {
|
|
335
|
-
outline: '2px solid',
|
|
336
|
-
outlineColor: colorVars['--color-border-blue'],
|
|
337
|
-
outlineOffset: -2,
|
|
338
|
-
},
|
|
339
|
-
// Circular muted chip behind the CTA icon — Center handles the centering
|
|
340
|
-
// and sizing; only the surface (radius + fill) needs custom CSS.
|
|
341
|
-
iconCircle: {
|
|
342
|
-
borderRadius: '50%',
|
|
343
|
-
backgroundColor: colorVars['--color-background-muted'],
|
|
344
|
-
},
|
|
308
|
+
// Fill the window. Layout height="fill" is height:100%, which only resolves
|
|
309
|
+
// against a definite height — and the host's <html>/<body> don't set one, so
|
|
310
|
+
// the layout anchors a definite viewport height itself. No background; the
|
|
311
|
+
// host owns the page surface.
|
|
312
|
+
const pageStyle: CSSProperties = {height: '100dvh'};
|
|
313
|
+
// Canvas reflows to the chosen viewport width; VStack has no maxWidth prop.
|
|
314
|
+
const canvasStyle = (maxWidth: number): CSSProperties => ({
|
|
315
|
+
maxWidth,
|
|
316
|
+
width: '100%',
|
|
317
|
+
marginInline: 'auto',
|
|
345
318
|
});
|
|
319
|
+
const clickable: CSSProperties = {
|
|
320
|
+
cursor: 'pointer',
|
|
321
|
+
};
|
|
322
|
+
// Selection ring on the active block — Card has no `isSelected` state.
|
|
323
|
+
const selectedCard: CSSProperties = {
|
|
324
|
+
outline: '2px solid',
|
|
325
|
+
outlineColor: 'var(--color-border-blue)',
|
|
326
|
+
outlineOffset: -2,
|
|
327
|
+
};
|
|
328
|
+
// Circular muted chip behind the CTA icon — Center handles the centering
|
|
329
|
+
// and sizing; only the surface (radius + fill) needs custom CSS.
|
|
330
|
+
const iconCircle: CSSProperties = {
|
|
331
|
+
borderRadius: '50%',
|
|
332
|
+
backgroundColor: 'var(--color-background-muted)',
|
|
333
|
+
};
|
|
346
334
|
|
|
347
335
|
// ---------------------------------------------------------------------------
|
|
348
336
|
// Properties Form
|
|
@@ -477,15 +465,15 @@ function BlockPreview({
|
|
|
477
465
|
onSelect: () => void;
|
|
478
466
|
}) {
|
|
479
467
|
const {type, props} = block;
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
isSelected
|
|
483
|
-
|
|
468
|
+
const cardStyle: CSSProperties = {
|
|
469
|
+
...clickable,
|
|
470
|
+
...(isSelected ? selectedCard : null),
|
|
471
|
+
};
|
|
484
472
|
|
|
485
473
|
switch (type) {
|
|
486
474
|
case 'hero':
|
|
487
475
|
return (
|
|
488
|
-
<Card padding={6}
|
|
476
|
+
<Card padding={6} style={cardStyle} onClick={onSelect}>
|
|
489
477
|
<VStack gap={4}>
|
|
490
478
|
<Heading level={2}>
|
|
491
479
|
{(props.heading as string) || 'Hero Heading'}
|
|
@@ -503,7 +491,7 @@ function BlockPreview({
|
|
|
503
491
|
case 'text':
|
|
504
492
|
if (props.heading) {
|
|
505
493
|
return (
|
|
506
|
-
<Card padding={6}
|
|
494
|
+
<Card padding={6} style={cardStyle} onClick={onSelect}>
|
|
507
495
|
<EmptyState
|
|
508
496
|
title={props.heading as string}
|
|
509
497
|
description={props.description as string}
|
|
@@ -521,7 +509,7 @@ function BlockPreview({
|
|
|
521
509
|
);
|
|
522
510
|
}
|
|
523
511
|
return (
|
|
524
|
-
<Card
|
|
512
|
+
<Card style={cardStyle} onClick={onSelect}>
|
|
525
513
|
<Text type="body">
|
|
526
514
|
{(props.content as string) || 'Text content goes here'}
|
|
527
515
|
</Text>
|
|
@@ -530,7 +518,7 @@ function BlockPreview({
|
|
|
530
518
|
|
|
531
519
|
case 'image':
|
|
532
520
|
return (
|
|
533
|
-
<Card
|
|
521
|
+
<Card style={cardStyle} onClick={onSelect}>
|
|
534
522
|
<EmptyState
|
|
535
523
|
title="Image Block"
|
|
536
524
|
description="Drop an image or enter a URL"
|
|
@@ -542,7 +530,7 @@ function BlockPreview({
|
|
|
542
530
|
|
|
543
531
|
case 'button':
|
|
544
532
|
return (
|
|
545
|
-
<Card padding={6}
|
|
533
|
+
<Card padding={6} style={cardStyle} onClick={onSelect}>
|
|
546
534
|
<Center>
|
|
547
535
|
<Button
|
|
548
536
|
label={(props.label as string) || 'Button'}
|
|
@@ -559,7 +547,7 @@ function BlockPreview({
|
|
|
559
547
|
case 'features': {
|
|
560
548
|
const items = (props.items as Transaction[]) || [];
|
|
561
549
|
return (
|
|
562
|
-
<Card padding={6}
|
|
550
|
+
<Card padding={6} style={cardStyle} onClick={onSelect}>
|
|
563
551
|
<VStack gap={4}>
|
|
564
552
|
<HStack gap={3} vAlign="start" hAlign="between">
|
|
565
553
|
<VStack gap={1}>
|
|
@@ -589,7 +577,7 @@ function BlockPreview({
|
|
|
589
577
|
const cardItems =
|
|
590
578
|
(props.cards as Array<{title: string; description: string}>) || [];
|
|
591
579
|
return (
|
|
592
|
-
<Card
|
|
580
|
+
<Card style={cardStyle} onClick={onSelect}>
|
|
593
581
|
<VStack gap={4}>
|
|
594
582
|
<Heading level={3}>Cards</Heading>
|
|
595
583
|
<Divider />
|
|
@@ -609,9 +597,9 @@ function BlockPreview({
|
|
|
609
597
|
|
|
610
598
|
case 'cta':
|
|
611
599
|
return (
|
|
612
|
-
<Card padding={6}
|
|
600
|
+
<Card padding={6} style={cardStyle} onClick={onSelect}>
|
|
613
601
|
<HStack gap={4} vAlign="start">
|
|
614
|
-
<Center width={40} height={40}
|
|
602
|
+
<Center width={40} height={40} style={iconCircle}>
|
|
615
603
|
<Icon icon={LockClosedIcon} color="secondary" />
|
|
616
604
|
</Center>
|
|
617
605
|
<VStack gap={1}>
|
|
@@ -828,7 +816,7 @@ export default function EditorPage() {
|
|
|
828
816
|
<LayoutPanel
|
|
829
817
|
hasDivider={!isMobile}
|
|
830
818
|
padding={0}
|
|
831
|
-
|
|
819
|
+
style={{width: isMobile ? '100%' : 320, flexShrink: 0}}>
|
|
832
820
|
<VStack gap={4}>
|
|
833
821
|
{/* Panel Header */}
|
|
834
822
|
<Section variant="transparent" padding={4}>
|
|
@@ -919,7 +907,7 @@ export default function EditorPage() {
|
|
|
919
907
|
return (
|
|
920
908
|
<>
|
|
921
909
|
<Layout
|
|
922
|
-
|
|
910
|
+
style={pageStyle}
|
|
923
911
|
height="fill"
|
|
924
912
|
header={isMobile ? sidebar : undefined}
|
|
925
913
|
start={isMobile ? undefined : sidebar}
|
|
@@ -927,7 +915,7 @@ export default function EditorPage() {
|
|
|
927
915
|
<LayoutContent padding={8}>
|
|
928
916
|
<VStack
|
|
929
917
|
gap={4}
|
|
930
|
-
|
|
918
|
+
style={canvasStyle(VIEWPORT_MAX[viewport])}>
|
|
931
919
|
{blocks.length > 0 ? (
|
|
932
920
|
blocks.map(block => (
|
|
933
921
|
<BlockPreview
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
-
import {useState, useMemo} from 'react';
|
|
6
|
-
import * as stylex from '@stylexjs/stylex';
|
|
5
|
+
import {useState, useMemo, type CSSProperties} from 'react';
|
|
7
6
|
import {Layout, LayoutContent} from '@astryxdesign/core/Layout';
|
|
8
7
|
import {Toolbar} from '@astryxdesign/core/Toolbar';
|
|
9
8
|
import {List, ListItem} from '@astryxdesign/core/List';
|
|
@@ -145,10 +144,10 @@ const FILESYSTEM: FileSystemItem[] = [
|
|
|
145
144
|
children: [{id: 'react-index', name: 'index.js', type: 'file'}],
|
|
146
145
|
},
|
|
147
146
|
{
|
|
148
|
-
id: '
|
|
149
|
-
name: '
|
|
147
|
+
id: 'react-dom',
|
|
148
|
+
name: 'react-dom',
|
|
150
149
|
type: 'folder',
|
|
151
|
-
children: [{id: '
|
|
150
|
+
children: [{id: 'react-dom-index', name: 'index.js', type: 'file'}],
|
|
152
151
|
},
|
|
153
152
|
],
|
|
154
153
|
},
|
|
@@ -260,13 +259,11 @@ const FILESYSTEM: FileSystemItem[] = [
|
|
|
260
259
|
},
|
|
261
260
|
];
|
|
262
261
|
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
detailColumn: {flexGrow: 1, flexShrink: 0, flexBasis: 320},
|
|
269
|
-
});
|
|
262
|
+
const page: CSSProperties = {height: '100dvh'};
|
|
263
|
+
const columnRow: CSSProperties = {overflowX: 'auto', overflowY: 'hidden'};
|
|
264
|
+
const scrollable: CSSProperties = {overflowY: 'auto'};
|
|
265
|
+
const fixedColumn: CSSProperties = {flexShrink: 0};
|
|
266
|
+
const detailColumn: CSSProperties = {flexGrow: 1, flexShrink: 0, flexBasis: 320};
|
|
270
267
|
|
|
271
268
|
function findItem(items: FileSystemItem[], id: string): FileSystemItem | null {
|
|
272
269
|
for (const item of items) {
|
|
@@ -348,7 +345,7 @@ export default function FileExplorerPage() {
|
|
|
348
345
|
|
|
349
346
|
return (
|
|
350
347
|
<Layout
|
|
351
|
-
|
|
348
|
+
style={page}
|
|
352
349
|
height="fill"
|
|
353
350
|
header={
|
|
354
351
|
<Toolbar
|
|
@@ -448,7 +445,7 @@ export default function FileExplorerPage() {
|
|
|
448
445
|
}
|
|
449
446
|
content={
|
|
450
447
|
<LayoutContent padding={0} isScrollable={false}>
|
|
451
|
-
<HStack height="100%"
|
|
448
|
+
<HStack height="100%" style={columnRow}>
|
|
452
449
|
{columns.map((col, colIndex) => {
|
|
453
450
|
const showDivider =
|
|
454
451
|
colIndex < columns.length - 1 || selectedFile != null;
|
|
@@ -459,7 +456,7 @@ export default function FileExplorerPage() {
|
|
|
459
456
|
padding={2}
|
|
460
457
|
variant="transparent"
|
|
461
458
|
dividers={showDivider ? ['end'] : undefined}
|
|
462
|
-
|
|
459
|
+
style={{...scrollable, ...fixedColumn}}>
|
|
463
460
|
<List density="compact" hasDividers={false}>
|
|
464
461
|
{col.items.map(item => {
|
|
465
462
|
const isSelected = col.selectedId === item.id;
|
|
@@ -506,7 +503,7 @@ export default function FileExplorerPage() {
|
|
|
506
503
|
<Section
|
|
507
504
|
padding={6}
|
|
508
505
|
variant="transparent"
|
|
509
|
-
|
|
506
|
+
style={{...scrollable, ...detailColumn}}>
|
|
510
507
|
<VStack gap={4} hAlign="center">
|
|
511
508
|
<Avatar name={selectedFile.name} size={96} />
|
|
512
509
|
<VStack gap={1} hAlign="center">
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
-
import {useState} from 'react';
|
|
6
|
-
import * as stylex from '@stylexjs/stylex';
|
|
5
|
+
import {useState, type CSSProperties} from 'react';
|
|
7
6
|
import {VStack, HStack} from '@astryxdesign/core/Layout';
|
|
8
7
|
import {Center} from '@astryxdesign/core/Center';
|
|
9
8
|
import {Section} from '@astryxdesign/core/Section';
|
|
@@ -18,7 +17,6 @@ import {Link} from '@astryxdesign/core/Link';
|
|
|
18
17
|
import {Divider} from '@astryxdesign/core/Divider';
|
|
19
18
|
import {Card} from '@astryxdesign/core/Card';
|
|
20
19
|
import {Selector} from '@astryxdesign/core/Selector';
|
|
21
|
-
import {radiusVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
22
20
|
|
|
23
21
|
const ILLUSTRATION_URL =
|
|
24
22
|
'https://lookaside.facebook.com/assets/astryx/light-working-vertical-2.png';
|
|
@@ -51,18 +49,16 @@ const CONTACT_COLUMNS = [
|
|
|
51
49
|
// AspectRatio has no objectFit/radius prop and there's no Image primitive
|
|
52
50
|
// (#2582), so the cover photo is styled directly. overflow:hidden masks the
|
|
53
51
|
// cover crop to the rounded corners.
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
},
|
|
65
|
-
});
|
|
52
|
+
const pageStyle: CSSProperties = {
|
|
53
|
+
minHeight: '100%',
|
|
54
|
+
};
|
|
55
|
+
const illustrationImg: CSSProperties = {
|
|
56
|
+
width: '100%',
|
|
57
|
+
height: '100%',
|
|
58
|
+
objectFit: 'cover',
|
|
59
|
+
borderRadius: 'var(--radius-container)',
|
|
60
|
+
overflow: 'hidden',
|
|
61
|
+
};
|
|
66
62
|
|
|
67
63
|
/**
|
|
68
64
|
* Form (Two-column) — marketing contact form template.
|
|
@@ -95,7 +91,7 @@ export default function FormTwoColumnPage() {
|
|
|
95
91
|
const handleSubmit = () => setSubmitted(true);
|
|
96
92
|
|
|
97
93
|
return (
|
|
98
|
-
<Center
|
|
94
|
+
<Center style={pageStyle}>
|
|
99
95
|
<Section maxWidth={1100} width="100%" padding={10} variant="transparent">
|
|
100
96
|
<VStack gap={10}>
|
|
101
97
|
{/* Two-column; stacks to one column below ~520px. */}
|
|
@@ -114,7 +110,7 @@ export default function FormTwoColumnPage() {
|
|
|
114
110
|
<img
|
|
115
111
|
src={ILLUSTRATION_URL}
|
|
116
112
|
alt="Two people working at a desk"
|
|
117
|
-
{
|
|
113
|
+
style={illustrationImg}
|
|
118
114
|
/>
|
|
119
115
|
</AspectRatio>
|
|
120
116
|
</VStack>
|
|
@@ -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,
|
|
@@ -35,18 +35,16 @@ const IMAGES = [
|
|
|
35
35
|
// because Astryx has no image primitive — AspectRatio exposes no objectFit or
|
|
36
36
|
// radius props and there's no Image. Tracked in issue #2582; replace these
|
|
37
37
|
// with component props once it lands.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
},
|
|
49
|
-
});
|
|
38
|
+
// Fills the AspectRatio box. No objectFit prop on AspectRatio (#2582).
|
|
39
|
+
const galleryImage: CSSProperties = {
|
|
40
|
+
width: '100%',
|
|
41
|
+
height: '100%',
|
|
42
|
+
objectFit: 'cover',
|
|
43
|
+
};
|
|
44
|
+
// Rounds the image corners. No radius prop on AspectRatio (#2582).
|
|
45
|
+
const galleryImageClip: CSSProperties = {
|
|
46
|
+
borderRadius: 'var(--radius-container)',
|
|
47
|
+
};
|
|
50
48
|
|
|
51
49
|
export default function GalleryHero() {
|
|
52
50
|
return (
|
|
@@ -88,9 +86,9 @@ export default function GalleryHero() {
|
|
|
88
86
|
<AspectRatio
|
|
89
87
|
key={image.src}
|
|
90
88
|
ratio={4 / 5}
|
|
91
|
-
|
|
89
|
+
style={galleryImageClip}>
|
|
92
90
|
<img
|
|
93
|
-
{
|
|
91
|
+
style={galleryImage}
|
|
94
92
|
src={image.src}
|
|
95
93
|
alt={image.alt}
|
|
96
94
|
/>
|