@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,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 ── */}
|
|
@@ -2,54 +2,59 @@
|
|
|
2
2
|
|
|
3
3
|
'use client';
|
|
4
4
|
|
|
5
|
+
import type {CSSProperties} from 'react';
|
|
5
6
|
import {VStack, Layout, LayoutContent} from '@astryxdesign/core/Layout';
|
|
6
7
|
import {Text, Heading} from '@astryxdesign/core/Text';
|
|
7
8
|
import {AspectRatio} from '@astryxdesign/core/AspectRatio';
|
|
8
|
-
import * as stylex from '@stylexjs/stylex';
|
|
9
9
|
|
|
10
10
|
// ─── Styles ────────────────────────────────────────────────────────────────
|
|
11
11
|
// The masonry needs a responsive column count AND a hero that spans 2 columns
|
|
12
12
|
// on desktop but goes full-width on mobile. Grid forces grid-template-columns
|
|
13
13
|
// inline, so a responsive span can't be expressed through its props — this is a
|
|
14
14
|
// @container grid (the sanctioned Astryx pattern for container-responsive layout).
|
|
15
|
-
//
|
|
15
|
+
// The container query lives in a plain <style> tag below so it needs NO CSS
|
|
16
|
+
// compiler. Image fill + radius are custom because Astryx has no image
|
|
17
|
+
// primitive (#2582).
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
19
|
+
// Named inline-size container on the page column so the grid responds to the
|
|
20
|
+
// available content width (works inside the sandbox's resizable preview).
|
|
21
|
+
const containerStyle: CSSProperties = {
|
|
22
|
+
containerType: 'inline-size',
|
|
23
|
+
containerName: 'gallery',
|
|
24
|
+
};
|
|
25
|
+
// Fills the AspectRatio box. No objectFit prop on AspectRatio (#2582).
|
|
26
|
+
const imgStyle: CSSProperties = {
|
|
27
|
+
width: '100%',
|
|
28
|
+
height: '100%',
|
|
29
|
+
objectFit: 'cover',
|
|
30
|
+
};
|
|
31
|
+
// Rounds the image corners. No radius prop on AspectRatio (#2582).
|
|
32
|
+
const clipStyle: CSSProperties = {
|
|
33
|
+
borderRadius: 'var(--radius-element)',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// 3 columns on desktop, dropping straight to 1 column below 720px (no 2-col
|
|
37
|
+
// middle state). minmax(0, 1fr) (not 1fr) so tracks split evenly and ignore the
|
|
38
|
+
// images' intrinsic min-width. The hero spans 2 columns on desktop, then fills
|
|
39
|
+
// the row once it's single-column.
|
|
40
|
+
const GALLERY_CSS = `
|
|
41
|
+
.mixed-gallery-grid {
|
|
42
|
+
display: grid;
|
|
43
|
+
gap: var(--spacing-3);
|
|
44
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
45
|
+
}
|
|
46
|
+
.mixed-gallery-hero {
|
|
47
|
+
grid-column: span 2;
|
|
48
|
+
}
|
|
49
|
+
@container gallery (max-width: 720px) {
|
|
50
|
+
.mixed-gallery-grid {
|
|
51
|
+
grid-template-columns: minmax(0, 1fr);
|
|
52
|
+
}
|
|
53
|
+
.mixed-gallery-hero {
|
|
54
|
+
grid-column: 1 / -1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
53
58
|
|
|
54
59
|
// ─── Gallery Data ───────────────────────────────────────────────────────────
|
|
55
60
|
|
|
@@ -89,15 +94,15 @@ const IMAGES: GalleryImage[] = [
|
|
|
89
94
|
function GalleryCard({
|
|
90
95
|
image,
|
|
91
96
|
ratio,
|
|
92
|
-
|
|
97
|
+
className,
|
|
93
98
|
}: {
|
|
94
99
|
image: GalleryImage;
|
|
95
100
|
ratio: number;
|
|
96
|
-
|
|
101
|
+
className?: string;
|
|
97
102
|
}) {
|
|
98
103
|
return (
|
|
99
|
-
<AspectRatio ratio={ratio}
|
|
100
|
-
<img src={image.src} alt={image.title} {
|
|
104
|
+
<AspectRatio ratio={ratio} className={className} style={clipStyle}>
|
|
105
|
+
<img src={image.src} alt={image.title} style={imgStyle} />
|
|
101
106
|
</AspectRatio>
|
|
102
107
|
);
|
|
103
108
|
}
|
|
@@ -111,7 +116,8 @@ export default function MixedGalleryTemplate() {
|
|
|
111
116
|
contentWidth={1400}
|
|
112
117
|
content={
|
|
113
118
|
<LayoutContent padding={6}>
|
|
114
|
-
<
|
|
119
|
+
<style>{GALLERY_CSS}</style>
|
|
120
|
+
<VStack gap={6} style={containerStyle}>
|
|
115
121
|
{/* Header */}
|
|
116
122
|
<VStack gap={2} hAlign="center">
|
|
117
123
|
<Heading level={1} justify="center">
|
|
@@ -129,12 +135,12 @@ export default function MixedGalleryTemplate() {
|
|
|
129
135
|
(being 2 columns wide) it matches the row height exactly. All
|
|
130
136
|
rows are therefore the same height. Responsive via @container:
|
|
131
137
|
3 columns → 1 column at ≤720px. */}
|
|
132
|
-
<div
|
|
138
|
+
<div className="mixed-gallery-grid">
|
|
133
139
|
{/* Hero — spans 2 columns; 3:1 keeps it level with the sidebar */}
|
|
134
140
|
<GalleryCard
|
|
135
141
|
image={IMAGES[0]}
|
|
136
142
|
ratio={3 / 1}
|
|
137
|
-
|
|
143
|
+
className="mixed-gallery-hero"
|
|
138
144
|
/>
|
|
139
145
|
|
|
140
146
|
{/* Sidebar — same height as the hero */}
|