@astryxdesign/cli 0.1.0-canary.f94dd07 → 0.1.1-canary.a514b99
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/icons.doc.mjs +1 -1
- package/docs/migration.doc.mjs +2 -2
- package/docs/shape.doc.mjs +1 -1
- package/docs/styling.doc.mjs +2 -2
- 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/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 +92 -56
- package/src/commands/agent-docs.path-safety.test.mjs +1 -1
- package/src/commands/agent-docs.test.mjs +66 -10
- 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 +9 -1
- 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.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 +11 -14
- package/templates/pages/documentation-design/page.tsx +10 -13
- package/templates/pages/documentation-technical/page.tsx +15 -16
- 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 +32 -39
- 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,14 +2,12 @@
|
|
|
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
|
|
|
8
7
|
import {Layout, LayoutContent, LayoutPanel} from '@astryxdesign/core/Layout';
|
|
9
8
|
import {ResizeHandle, useResizable} from '@astryxdesign/core/Resizable';
|
|
10
9
|
import {Text, Heading} from '@astryxdesign/core/Text';
|
|
11
10
|
import {CodeBlock} from '@astryxdesign/core/CodeBlock';
|
|
12
|
-
import {colorVars, spacingVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
13
11
|
import {Stack, StackItem} from '@astryxdesign/core/Layout';
|
|
14
12
|
import {useMediaQuery} from '@astryxdesign/core/hooks';
|
|
15
13
|
import {TabList, Tab} from '@astryxdesign/core/TabList';
|
|
@@ -30,7 +28,7 @@ import {
|
|
|
30
28
|
MagnifyingGlassIcon,
|
|
31
29
|
} from '@heroicons/react/24/outline';
|
|
32
30
|
|
|
33
|
-
const styles =
|
|
31
|
+
const styles: Record<string, CSSProperties> = {
|
|
34
32
|
contentFill: {
|
|
35
33
|
height: '100%',
|
|
36
34
|
},
|
|
@@ -40,16 +38,16 @@ const styles = stylex.create({
|
|
|
40
38
|
display: 'grid',
|
|
41
39
|
},
|
|
42
40
|
tabListPadding: {
|
|
43
|
-
paddingTop:
|
|
41
|
+
paddingTop: 'var(--spacing-2)',
|
|
44
42
|
},
|
|
45
43
|
metadataCompact: {
|
|
46
|
-
gap:
|
|
44
|
+
gap: 'var(--spacing-1) var(--spacing-3)',
|
|
47
45
|
},
|
|
48
46
|
historyTimelineDot: {
|
|
49
47
|
width: 8,
|
|
50
48
|
height: 8,
|
|
51
49
|
borderRadius: '50%',
|
|
52
|
-
backgroundColor:
|
|
50
|
+
backgroundColor: 'var(--color-border-emphasized)',
|
|
53
51
|
marginTop: 6,
|
|
54
52
|
flexShrink: 0,
|
|
55
53
|
},
|
|
@@ -75,26 +73,23 @@ const styles = stylex.create({
|
|
|
75
73
|
height: '100%',
|
|
76
74
|
overflow: 'hidden',
|
|
77
75
|
},
|
|
78
|
-
}
|
|
76
|
+
};
|
|
79
77
|
|
|
80
78
|
const EDITOR_CODE = `import {useState, useCallback} from 'react';
|
|
81
|
-
import * as stylex from '@stylexjs/stylex';
|
|
82
79
|
import {Button} from '@astryxdesign/core/Button';
|
|
83
80
|
import {Text} from '@astryxdesign/core/Text';
|
|
84
81
|
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
},
|
|
97
|
-
});
|
|
82
|
+
const containerStyle = {
|
|
83
|
+
display: 'flex',
|
|
84
|
+
flexDirection: 'column',
|
|
85
|
+
gap: 8,
|
|
86
|
+
padding: 16,
|
|
87
|
+
};
|
|
88
|
+
const counterStyle = {
|
|
89
|
+
fontSize: 48,
|
|
90
|
+
fontWeight: 700,
|
|
91
|
+
fontVariantNumeric: 'tabular-nums',
|
|
92
|
+
};
|
|
98
93
|
|
|
99
94
|
export default function Counter() {
|
|
100
95
|
const [count, setCount] = useState(0);
|
|
@@ -108,9 +103,9 @@ export default function Counter() {
|
|
|
108
103
|
}, []);
|
|
109
104
|
|
|
110
105
|
return (
|
|
111
|
-
<div {
|
|
106
|
+
<div style={containerStyle}>
|
|
112
107
|
<Text type="label">Counter</Text>
|
|
113
|
-
<span {
|
|
108
|
+
<span style={counterStyle}>
|
|
114
109
|
{count}
|
|
115
110
|
</span>
|
|
116
111
|
<Button label="Increment" onClick={increment} />
|
|
@@ -172,7 +167,7 @@ function buildFileTree(
|
|
|
172
167
|
label: label('styles'),
|
|
173
168
|
startContent: <Icon icon={FolderIcon} size="xsm" />,
|
|
174
169
|
isExpanded: true,
|
|
175
|
-
children: [file('tokens.
|
|
170
|
+
children: [file('tokens.ts'), file('theme.ts')],
|
|
176
171
|
},
|
|
177
172
|
],
|
|
178
173
|
},
|
|
@@ -196,7 +191,7 @@ const PROPERTIES = [
|
|
|
196
191
|
const HISTORY_ITEMS = [
|
|
197
192
|
{label: 'Opened Counter.tsx', time: '2 min ago'},
|
|
198
193
|
{label: 'Opened Layout.tsx', time: '6 min ago'},
|
|
199
|
-
{label: 'Viewed tokens.
|
|
194
|
+
{label: 'Viewed tokens.ts', time: '11 min ago'},
|
|
200
195
|
];
|
|
201
196
|
|
|
202
197
|
export default function ResizableWorkspacePage() {
|
|
@@ -248,7 +243,7 @@ export default function ResizableWorkspacePage() {
|
|
|
248
243
|
padding={0}>
|
|
249
244
|
<Stack
|
|
250
245
|
direction="vertical"
|
|
251
|
-
|
|
246
|
+
style={styles.fileExplorer}
|
|
252
247
|
gap={2}>
|
|
253
248
|
<TextInput
|
|
254
249
|
label="Search files"
|
|
@@ -278,8 +273,8 @@ export default function ResizableWorkspacePage() {
|
|
|
278
273
|
height="fill"
|
|
279
274
|
content={
|
|
280
275
|
<LayoutContent padding={0}>
|
|
281
|
-
<Stack direction="vertical"
|
|
282
|
-
<StackItem size="fill"
|
|
276
|
+
<Stack direction="vertical" style={styles.contentFill}>
|
|
277
|
+
<StackItem size="fill" style={styles.editorArea}>
|
|
283
278
|
<CodeBlock
|
|
284
279
|
code={EDITOR_CODE}
|
|
285
280
|
language="typescript"
|
|
@@ -314,13 +309,13 @@ export default function ResizableWorkspacePage() {
|
|
|
314
309
|
}}>
|
|
315
310
|
<Stack
|
|
316
311
|
direction="vertical"
|
|
317
|
-
|
|
312
|
+
style={styles.contentFill}>
|
|
318
313
|
<TabList
|
|
319
314
|
value={activeTermTab}
|
|
320
315
|
onChange={val => setActiveTermTab(val)}
|
|
321
316
|
size="sm"
|
|
322
317
|
hasDivider={false}
|
|
323
|
-
|
|
318
|
+
style={styles.tabListPadding}>
|
|
324
319
|
<Tab label="Terminal" value="terminal" />
|
|
325
320
|
<Tab label="Problems" value="problems" />
|
|
326
321
|
<Tab label="Output" value="output" />
|
|
@@ -328,7 +323,7 @@ export default function ResizableWorkspacePage() {
|
|
|
328
323
|
</TabList>
|
|
329
324
|
<StackItem
|
|
330
325
|
size="fill"
|
|
331
|
-
|
|
326
|
+
style={styles.terminalWrapper}>
|
|
332
327
|
<CodeBlock
|
|
333
328
|
code={TERMINAL_OUTPUT}
|
|
334
329
|
language="bash"
|
|
@@ -369,7 +364,7 @@ export default function ResizableWorkspacePage() {
|
|
|
369
364
|
<Stack
|
|
370
365
|
direction="vertical"
|
|
371
366
|
gap={3}
|
|
372
|
-
|
|
367
|
+
style={styles.propertiesPanel}>
|
|
373
368
|
<SegmentedControl
|
|
374
369
|
label="Properties panel sections"
|
|
375
370
|
value={activePropertiesTab}
|
|
@@ -389,7 +384,7 @@ export default function ResizableWorkspacePage() {
|
|
|
389
384
|
<Stack
|
|
390
385
|
direction="vertical"
|
|
391
386
|
gap={3}
|
|
392
|
-
|
|
387
|
+
style={styles.propertiesContent}>
|
|
393
388
|
<Stack direction="vertical" gap={1}>
|
|
394
389
|
<Heading level={3} maxLines={1}>
|
|
395
390
|
{activeFile}
|
|
@@ -401,7 +396,7 @@ export default function ResizableWorkspacePage() {
|
|
|
401
396
|
src/components/{activeFile}
|
|
402
397
|
</Text>
|
|
403
398
|
</Stack>
|
|
404
|
-
<MetadataList
|
|
399
|
+
<MetadataList style={styles.metadataCompact}>
|
|
405
400
|
{PROPERTIES.map(prop => (
|
|
406
401
|
<MetadataListItem
|
|
407
402
|
key={prop.label}
|
|
@@ -413,7 +408,7 @@ export default function ResizableWorkspacePage() {
|
|
|
413
408
|
<Stack
|
|
414
409
|
direction="vertical"
|
|
415
410
|
gap={2}
|
|
416
|
-
|
|
411
|
+
style={styles.propertyActions}>
|
|
417
412
|
<Button
|
|
418
413
|
label="Format Document"
|
|
419
414
|
size="sm"
|
|
@@ -448,9 +443,7 @@ export default function ResizableWorkspacePage() {
|
|
|
448
443
|
}
|
|
449
444
|
startContent={
|
|
450
445
|
<span
|
|
451
|
-
{
|
|
452
|
-
styles.historyTimelineDot,
|
|
453
|
-
)}
|
|
446
|
+
style={styles.historyTimelineDot}
|
|
454
447
|
/>
|
|
455
448
|
}
|
|
456
449
|
/>
|
|
@@ -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, LayoutHeader, LayoutContent} from '@astryxdesign/core/Layout';
|
|
8
7
|
import {Text, Heading} from '@astryxdesign/core/Text';
|
|
9
8
|
import {Card} from '@astryxdesign/core/Card';
|
|
@@ -320,21 +319,19 @@ const ITEMS: LibraryItem[] = [
|
|
|
320
319
|
},
|
|
321
320
|
];
|
|
322
321
|
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
},
|
|
337
|
-
});
|
|
322
|
+
const thumbnailWrapper: CSSProperties = {
|
|
323
|
+
position: 'relative',
|
|
324
|
+
aspectRatio: '16/9',
|
|
325
|
+
overflow: 'clip',
|
|
326
|
+
flexShrink: 0,
|
|
327
|
+
};
|
|
328
|
+
const thumbnailImage: CSSProperties = {
|
|
329
|
+
position: 'absolute',
|
|
330
|
+
inset: 0,
|
|
331
|
+
width: '100%',
|
|
332
|
+
height: '100%',
|
|
333
|
+
objectFit: 'cover',
|
|
334
|
+
};
|
|
338
335
|
|
|
339
336
|
// =============================================================================
|
|
340
337
|
// Side Nav
|
|
@@ -343,12 +340,8 @@ const styles = stylex.create({
|
|
|
343
340
|
function LibraryCard({item}: {item: LibraryItem}) {
|
|
344
341
|
return (
|
|
345
342
|
<Card padding={0}>
|
|
346
|
-
<div {
|
|
347
|
-
<img
|
|
348
|
-
src={item.imageUrl}
|
|
349
|
-
alt={item.name}
|
|
350
|
-
{...stylex.props(styles.thumbnailImage)}
|
|
351
|
-
/>
|
|
343
|
+
<div style={thumbnailWrapper}>
|
|
344
|
+
<img src={item.imageUrl} alt={item.name} style={thumbnailImage} />
|
|
352
345
|
</div>
|
|
353
346
|
<Section variant="transparent" padding={4}>
|
|
354
347
|
<VStack gap={1}>
|
|
@@ -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} from '@astryxdesign/core/Layout';
|
|
8
7
|
import {Center} from '@astryxdesign/core/Center';
|
|
9
8
|
import {Text, Heading} from '@astryxdesign/core/Text';
|
|
@@ -13,22 +12,19 @@ import {Card} from '@astryxdesign/core/Card';
|
|
|
13
12
|
import {Icon} from '@astryxdesign/core/Icon';
|
|
14
13
|
import {Banner} from '@astryxdesign/core/Banner';
|
|
15
14
|
import {CubeIcon} from '@heroicons/react/24/outline';
|
|
16
|
-
import {colorVars, spacingVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
17
15
|
|
|
18
16
|
// Standalone auth page paints its own body background (no host shell).
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
});
|
|
17
|
+
const pageStyle: CSSProperties = {
|
|
18
|
+
minHeight: '100%',
|
|
19
|
+
backgroundColor: 'var(--color-background-body)',
|
|
20
|
+
padding: 'var(--spacing-6)',
|
|
21
|
+
};
|
|
22
|
+
// Cap the column at 400px but let it shrink to fit narrow screens (Stack
|
|
23
|
+
// has no maxWidth prop, so it's set here).
|
|
24
|
+
const contentStyle: CSSProperties = {
|
|
25
|
+
width: '100%',
|
|
26
|
+
maxWidth: 400,
|
|
27
|
+
};
|
|
32
28
|
|
|
33
29
|
export default function LoginPage() {
|
|
34
30
|
const [email, setEmail] = useState('');
|
|
@@ -47,8 +43,8 @@ export default function LoginPage() {
|
|
|
47
43
|
};
|
|
48
44
|
|
|
49
45
|
return (
|
|
50
|
-
<Center axis="both"
|
|
51
|
-
<VStack gap={4} hAlign="center"
|
|
46
|
+
<Center axis="both" style={pageStyle}>
|
|
47
|
+
<VStack gap={4} hAlign="center" style={contentStyle}>
|
|
52
48
|
{/* Logo */}
|
|
53
49
|
<VStack gap={2} hAlign="center">
|
|
54
50
|
<Icon icon={CubeIcon} size="lg" />
|
|
@@ -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 {CubeIcon} from '@heroicons/react/24/outline';
|
|
8
7
|
import {VStack} from '@astryxdesign/core/Layout';
|
|
9
8
|
import {Center} from '@astryxdesign/core/Center';
|
|
@@ -14,7 +13,6 @@ import {Card} from '@astryxdesign/core/Card';
|
|
|
14
13
|
import {Link} from '@astryxdesign/core/Link';
|
|
15
14
|
import {Divider} from '@astryxdesign/core/Divider';
|
|
16
15
|
import {Icon} from '@astryxdesign/core/Icon';
|
|
17
|
-
import {colorVars, spacingVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
18
16
|
|
|
19
17
|
// Brand sign-in marks — no heroicons or template-assets equivalent.
|
|
20
18
|
const AppleIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
|
@@ -57,19 +55,17 @@ const GoogleIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
|
|
57
55
|
);
|
|
58
56
|
|
|
59
57
|
// Standalone auth page paints its own body background (no host shell).
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
},
|
|
72
|
-
});
|
|
58
|
+
const pageStyle: CSSProperties = {
|
|
59
|
+
minHeight: '100%',
|
|
60
|
+
backgroundColor: 'var(--color-background-body)',
|
|
61
|
+
padding: 'var(--spacing-6)',
|
|
62
|
+
};
|
|
63
|
+
// Cap the column at 400px but let it shrink to fit narrow screens (Stack
|
|
64
|
+
// has no maxWidth prop, so it's set here).
|
|
65
|
+
const contentStyle: CSSProperties = {
|
|
66
|
+
width: '100%',
|
|
67
|
+
maxWidth: 400,
|
|
68
|
+
};
|
|
73
69
|
|
|
74
70
|
export default function LoginSimple() {
|
|
75
71
|
const [email, setEmail] = useState('');
|
|
@@ -91,8 +87,8 @@ export default function LoginSimple() {
|
|
|
91
87
|
};
|
|
92
88
|
|
|
93
89
|
return (
|
|
94
|
-
<Center axis="both"
|
|
95
|
-
<VStack gap={4} hAlign="center"
|
|
90
|
+
<Center axis="both" style={pageStyle}>
|
|
91
|
+
<VStack gap={4} hAlign="center" style={contentStyle}>
|
|
96
92
|
{/* Logo */}
|
|
97
93
|
<VStack gap={2} hAlign="center">
|
|
98
94
|
<Icon icon={CubeIcon} size="lg" />
|
|
@@ -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, StackItem} from '@astryxdesign/core/Layout';
|
|
8
7
|
import {Grid} from '@astryxdesign/core/Grid';
|
|
9
8
|
import {Center} from '@astryxdesign/core/Center';
|
|
@@ -17,7 +16,6 @@ import {TextInput} from '@astryxdesign/core/TextInput';
|
|
|
17
16
|
import {Button} from '@astryxdesign/core/Button';
|
|
18
17
|
import {Link} from '@astryxdesign/core/Link';
|
|
19
18
|
import {Divider} from '@astryxdesign/core/Divider';
|
|
20
|
-
import {colorVars, spacingVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
21
19
|
|
|
22
20
|
const COVER_IMAGE_URL =
|
|
23
21
|
'https://lookaside.facebook.com/assets/astryx/light-working-vertical-1.png';
|
|
@@ -34,47 +32,50 @@ const COLUMN_MIN_WIDTH = 240;
|
|
|
34
32
|
// below 2×MIN + 32(gap) = 512px. The container query reorders the image and
|
|
35
33
|
// tightens the inset at that same point, keyed to the card width (not the
|
|
36
34
|
// window) so it never desyncs.
|
|
37
|
-
|
|
35
|
+
// minHeight:100% fills the host so the centered card never leaves an unpainted
|
|
36
|
+
// band; padding keeps it off the surface edges.
|
|
37
|
+
const pageStyle: CSSProperties = {
|
|
38
|
+
minHeight: '100%',
|
|
39
|
+
backgroundColor: 'var(--color-background-body)',
|
|
40
|
+
padding: 'var(--spacing-6)',
|
|
41
|
+
};
|
|
42
|
+
const cardWrap: CSSProperties = {
|
|
43
|
+
width: '100%',
|
|
44
|
+
maxWidth: 1000,
|
|
45
|
+
marginInline: 'auto',
|
|
46
|
+
};
|
|
47
|
+
const coverImage: CSSProperties = {
|
|
48
|
+
width: '100%',
|
|
49
|
+
height: '100%',
|
|
50
|
+
objectFit: 'cover',
|
|
51
|
+
};
|
|
38
52
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
padding:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
width: '100%',
|
|
66
|
-
// order:-1 moves the image above the form when stacked.
|
|
67
|
-
order: {
|
|
68
|
-
default: 0,
|
|
69
|
-
[STACK_QUERY]: -1,
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
coverImage: {
|
|
73
|
-
width: '100%',
|
|
74
|
-
height: '100%',
|
|
75
|
-
objectFit: 'cover' as const,
|
|
76
|
-
},
|
|
77
|
-
});
|
|
53
|
+
// The container query lives in a plain <style> tag so it needs NO CSS compiler.
|
|
54
|
+
// - Pad the grid, not the Card: the form's Section escapes Card's
|
|
55
|
+
// --container-padding-* vars, which would cancel the inset on the form side.
|
|
56
|
+
// container-type makes the grid the query container for the stack point.
|
|
57
|
+
// - repeat:'fit' (auto-fit) collapses the two columns to one below 511px; the
|
|
58
|
+
// query reorders the image (order:-1) and tightens the inset at that point,
|
|
59
|
+
// keyed to the card width (not the window) so it never desyncs.
|
|
60
|
+
const LOGIN_SPLIT_CSS = `
|
|
61
|
+
.login-split-grid {
|
|
62
|
+
container-type: inline-size;
|
|
63
|
+
container-name: login-split;
|
|
64
|
+
padding: var(--spacing-8);
|
|
65
|
+
}
|
|
66
|
+
.login-split-image {
|
|
67
|
+
width: 100%;
|
|
68
|
+
order: 0;
|
|
69
|
+
}
|
|
70
|
+
@container login-split (max-width: 511px) {
|
|
71
|
+
.login-split-grid {
|
|
72
|
+
padding: var(--spacing-4);
|
|
73
|
+
}
|
|
74
|
+
.login-split-image {
|
|
75
|
+
order: -1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
`;
|
|
78
79
|
|
|
79
80
|
export default function LoginTwoColumn() {
|
|
80
81
|
const [email, setEmail] = useState('');
|
|
@@ -97,15 +98,16 @@ export default function LoginTwoColumn() {
|
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
return (
|
|
100
|
-
<Center axis="both"
|
|
101
|
+
<Center axis="both" style={pageStyle}>
|
|
102
|
+
<style>{LOGIN_SPLIT_CSS}</style>
|
|
101
103
|
<VStack gap={4} width="100%">
|
|
102
|
-
<div {
|
|
104
|
+
<div style={cardWrap}>
|
|
103
105
|
<Card padding={0} width="100%">
|
|
104
106
|
<Grid
|
|
105
107
|
columns={{minWidth: COLUMN_MIN_WIDTH, repeat: 'fit'}}
|
|
106
108
|
gap={8}
|
|
107
109
|
align="stretch"
|
|
108
|
-
|
|
110
|
+
className="login-split-grid">
|
|
109
111
|
{/* Form */}
|
|
110
112
|
<Section variant="transparent" padding={0} height="100%">
|
|
111
113
|
<VStack gap={4} height="100%">
|
|
@@ -237,14 +239,14 @@ export default function LoginTwoColumn() {
|
|
|
237
239
|
|
|
238
240
|
{/* Cover image — the transparent Card clips it to rounded
|
|
239
241
|
corners (overflow:clip + radius), so the image needs no radius. */}
|
|
240
|
-
<div
|
|
242
|
+
<div className="login-split-image">
|
|
241
243
|
<Card
|
|
242
244
|
variant="transparent"
|
|
243
245
|
padding={0}
|
|
244
246
|
width="100%"
|
|
245
247
|
height="100%">
|
|
246
248
|
<img
|
|
247
|
-
{
|
|
249
|
+
style={coverImage}
|
|
248
250
|
src={COVER_IMAGE_URL}
|
|
249
251
|
alt="Two people working at a desk"
|
|
250
252
|
/>
|
|
@@ -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 {ShieldCheckIcon} from '@heroicons/react/24/outline';
|
|
8
7
|
import {VStack, HStack} from '@astryxdesign/core/Layout';
|
|
9
8
|
import {Center} from '@astryxdesign/core/Center';
|
|
@@ -16,7 +15,6 @@ import {Link} from '@astryxdesign/core/Link';
|
|
|
16
15
|
import {Divider} from '@astryxdesign/core/Divider';
|
|
17
16
|
import {Icon} from '@astryxdesign/core/Icon';
|
|
18
17
|
import {Avatar} from '@astryxdesign/core/Avatar';
|
|
19
|
-
import {spacingVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
20
18
|
|
|
21
19
|
// ---------------------------------------------------------------------------
|
|
22
20
|
// Styles
|
|
@@ -24,15 +22,13 @@ import {spacingVars} from '@astryxdesign/core/theme/tokens.stylex';
|
|
|
24
22
|
|
|
25
23
|
const BG_URL = 'https://lookaside.facebook.com/assets/astryx/building.png';
|
|
26
24
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
},
|
|
35
|
-
});
|
|
25
|
+
const pageStyle: CSSProperties = {
|
|
26
|
+
minHeight: '100%',
|
|
27
|
+
backgroundImage: `url(${BG_URL})`,
|
|
28
|
+
backgroundSize: 'cover',
|
|
29
|
+
backgroundPosition: 'center',
|
|
30
|
+
padding: 'var(--spacing-6)',
|
|
31
|
+
};
|
|
36
32
|
|
|
37
33
|
type SSOProvider = {
|
|
38
34
|
name: string;
|
|
@@ -102,7 +98,7 @@ export default function LoginSSO() {
|
|
|
102
98
|
};
|
|
103
99
|
|
|
104
100
|
return (
|
|
105
|
-
<Center axis="both"
|
|
101
|
+
<Center axis="both" style={pageStyle}>
|
|
106
102
|
<Card padding={8} width="100%" maxWidth={400}>
|
|
107
103
|
<VStack gap={4} hAlign="stretch">
|
|
108
104
|
{/* ── Step 1: Email entry ── */}
|