astryx-dracula 0.5.0 → 0.6.2
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/BRAND.md +3 -3
- package/README.md +7 -4
- package/USAGE.md +49 -49
- package/astryx-dracula.d.ts +2 -2
- package/astryx-dracula.js +25 -9
- package/astryx-dracula.variants.d.ts +2 -2
- package/astryx.integration.mjs +1 -1
- package/icons.mjs +21 -17
- package/icons.tsx +69 -62
- package/package.json +125 -120
- package/shared/auth-chrome-config.ts +6 -6
- package/shared/auth-chrome.tsx +143 -144
- package/shared/auth-copy.ts +14 -14
- package/shared/chaptered-doc-config.ts +48 -51
- package/shared/chaptered-doc.tsx +267 -289
- package/shared/chart-hues.ts +25 -10
- package/shared/chart-labels.tsx +31 -30
- package/shared/chart-legend.tsx +55 -56
- package/shared/chart-panel-style.ts +3 -3
- package/shared/data-bar.tsx +97 -102
- package/shared/format-money.ts +1 -1
- package/shared/gallery-image.ts +6 -6
- package/shared/login-demo.ts +1 -1
- package/shared/metric-card.tsx +101 -105
- package/shared/metric-delta.tsx +28 -27
- package/shared/order-desk.tsx +205 -216
- package/shared/revenue-chart.tsx +145 -165
- package/shared/scene-castle.tsx +206 -291
- package/shared/scene-frame.tsx +33 -32
- package/shared/scene-hues.ts +17 -17
- package/shared/scene-tile.tsx +88 -92
- package/shared/settings-data.ts +119 -125
- package/shared/settings-rows.tsx +122 -159
- package/shared/sparkline.tsx +75 -88
- package/shared/sso-icons.tsx +10 -22
- package/shared/stars.tsx +16 -25
- package/templates/ai-chat-landing.template.mjs +5 -4
- package/templates/ai-chat-landing.tsx +473 -460
- package/templates/ai-chat.template.mjs +5 -4
- package/templates/ai-chat.tsx +543 -612
- package/templates/blank.template.mjs +5 -4
- package/templates/blank.tsx +18 -14
- package/templates/centered-hero.template.mjs +5 -4
- package/templates/centered-hero.tsx +55 -68
- package/templates/classic-gallery.template.mjs +5 -4
- package/templates/classic-gallery.tsx +97 -104
- package/templates/contact-form.template.mjs +5 -4
- package/templates/contact-form.tsx +247 -282
- package/templates/dashboard-portfolio.template.mjs +5 -4
- package/templates/dashboard-portfolio.tsx +717 -548
- package/templates/dashboard.template.mjs +5 -4
- package/templates/dashboard.tsx +596 -567
- package/templates/detail-page.template.mjs +5 -4
- package/templates/detail-page.tsx +546 -603
- package/templates/documentation-design.template.mjs +5 -4
- package/templates/documentation-design.tsx +231 -243
- package/templates/documentation-technical.template.mjs +5 -4
- package/templates/documentation-technical.tsx +236 -239
- package/templates/documentation.template.mjs +5 -4
- package/templates/documentation.tsx +267 -279
- package/templates/editor.template.mjs +5 -4
- package/templates/editor.tsx +844 -877
- package/templates/file-explorer.template.mjs +5 -4
- package/templates/file-explorer.tsx +566 -590
- package/templates/form-two-column.template.mjs +5 -4
- package/templates/form-two-column.tsx +195 -210
- package/templates/gallery-hero.template.mjs +5 -4
- package/templates/gallery-hero.tsx +93 -114
- package/templates/ide.template.mjs +5 -4
- package/templates/ide.tsx +407 -453
- package/templates/incident-console.template.mjs +5 -4
- package/templates/incident-console.tsx +593 -575
- package/templates/kanban-board.template.mjs +5 -4
- package/templates/kanban-board.tsx +665 -683
- package/templates/library.template.mjs +5 -4
- package/templates/library.tsx +409 -430
- package/templates/login-card.template.mjs +5 -4
- package/templates/login-card.tsx +63 -72
- package/templates/login-split.template.mjs +5 -4
- package/templates/login-split.tsx +192 -193
- package/templates/login-sso.template.mjs +5 -4
- package/templates/login-sso.tsx +257 -258
- package/templates/login.template.mjs +5 -4
- package/templates/login.tsx +53 -49
- package/templates/messaging-shell.template.mjs +5 -4
- package/templates/messaging-shell.tsx +556 -574
- package/templates/mixed-gallery.template.mjs +5 -4
- package/templates/mixed-gallery.tsx +60 -58
- package/templates/payment-form.template.mjs +5 -4
- package/templates/payment-form.tsx +882 -991
- package/templates/product-detail.template.mjs +5 -4
- package/templates/product-detail.tsx +261 -272
- package/templates/product-gallery.template.mjs +5 -4
- package/templates/product-gallery.tsx +126 -137
- package/templates/product-tour.template.mjs +5 -4
- package/templates/product-tour.tsx +741 -773
- package/templates/settings-dialog.template.mjs +5 -4
- package/templates/settings-dialog.tsx +688 -717
- package/templates/settings-sidebar.template.mjs +5 -4
- package/templates/settings-sidebar.tsx +762 -807
- package/templates/settings.template.mjs +5 -4
- package/templates/settings.tsx +289 -304
- package/templates/shell-nav.template.mjs +5 -4
- package/templates/shell-nav.tsx +212 -219
- package/templates/shell-side-nav.template.mjs +5 -4
- package/templates/shell-side-nav.tsx +135 -157
- package/templates/shell-top-nav.template.mjs +5 -4
- package/templates/shell-top-nav.tsx +182 -203
- package/templates/side-gallery.template.mjs +5 -4
- package/templates/side-gallery.tsx +85 -90
- package/templates/table-grouped.template.mjs +5 -4
- package/templates/table-grouped.tsx +1000 -1053
- package/templates/table-page-chart.template.mjs +5 -4
- package/templates/table-page-chart.tsx +400 -398
- package/templates/table-page-heatmap-status.template.mjs +5 -4
- package/templates/table-page-heatmap-status.tsx +483 -512
- package/templates/table-page-shoe-store-heatmap.template.mjs +5 -4
- package/templates/table-page-shoe-store-heatmap.tsx +748 -746
- package/templates/table-page.template.mjs +5 -4
- package/templates/table-page.tsx +396 -405
- package/templates/table.template.mjs +5 -4
- package/templates/table.tsx +92 -93
- package/templates/tech-report.template.mjs +5 -4
- package/templates/tech-report.tsx +1316 -1304
- package/templates/theme-showcase.template.mjs +5 -4
- package/templates/theme-showcase.tsx +871 -951
- package/theme.css +35 -77
- package/theme.css.d.ts +9 -0
- package/tokens.css +373 -380
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
type: "page",
|
|
3
|
+
name: "Login Card",
|
|
4
|
+
description: "Centered auth card with email and password",
|
|
5
|
+
keywords: ["login", "sign in", "auth", "card", "credentials", "account"],
|
|
6
|
+
category: "auth",
|
|
6
7
|
};
|
package/templates/login-card.tsx
CHANGED
|
@@ -1,83 +1,74 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
// XLE (canonical structure
|
|
3
|
-
//
|
|
2
|
+
// XLE (canonical structure of the tree below; the CLI had no XLE validator
|
|
3
|
+
// after `astryx layout` was removed in 0.7.0, so this is a reading aid and a
|
|
4
|
+
// human drift check — update it with the file, never alone):
|
|
5
|
+
// Ctr > V[g=4 a=center] > (V[g=2 a=center] > Ic + Tx"Castle Dracula"[t=body]) + (C[p=4] > V[g=4] > (V[g=1 a=center] > Hd"Welcome back to the night"[level=1 t=display-2] + Tx"Sign in to your crypt"[t=body]) + (V[g=2] > TI"Email"[t=email] + (V[g=1] > TI"Password"[t=password] + Lk"Forgot password?")) + B.primary"Sign in" + D"Or continue with" + (V[g=3] > B.secondary"Login with Apple" + B.secondary"Login with Google") + (V[a=center] > Tx"New to the castle?"[t=supporting] + Lk"Sign up")) + (V[a=center] > Tx"By clicking continue, you agree to our Terms of service and Privacy policy"[t=supporting])
|
|
4
6
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
7
|
+
import { Button } from "@astryxdesign/core/Button";
|
|
8
|
+
import { Center } from "@astryxdesign/core/Center";
|
|
9
|
+
import { Divider } from "@astryxdesign/core/Divider";
|
|
10
|
+
import { VStack } from "@astryxdesign/core/Layout";
|
|
11
|
+
import { AuthCard, AuthLoginFields, LoginBrand } from "astryx-dracula/shared/auth-chrome";
|
|
8
12
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
import {authPageStyle as pageStyle, authContentStyle as contentStyle} from 'astryx-dracula/shared/auth-chrome-config';
|
|
18
|
-
import {LoginBrand, AuthCard, AuthLoginFields} from 'astryx-dracula/shared/auth-chrome';
|
|
13
|
+
authContentStyle as contentStyle,
|
|
14
|
+
authPageStyle as pageStyle,
|
|
15
|
+
} from "astryx-dracula/shared/auth-chrome-config";
|
|
16
|
+
import { AUTH_ERROR_MESSAGE, AUTH_SSO_DIVIDER } from "astryx-dracula/shared/auth-copy";
|
|
17
|
+
import { demoLogin } from "astryx-dracula/shared/login-demo";
|
|
18
|
+
import { AppleIcon, GoogleIcon } from "astryx-dracula/shared/sso-icons";
|
|
19
|
+
import { useState, useTransition } from "react";
|
|
19
20
|
|
|
20
21
|
export default function LoginCard() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const [email, setEmail] = useState("");
|
|
23
|
+
const [password, setPassword] = useState("");
|
|
24
|
+
const [error, setError] = useState<string | null>(null);
|
|
25
|
+
const [isLoading, startTransition] = useTransition();
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
const handleLogin = () => {
|
|
28
|
+
if (!email || !password) {
|
|
29
|
+
setError(AUTH_ERROR_MESSAGE);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
setError(null);
|
|
33
|
+
startTransition(async () => {
|
|
34
|
+
await demoLogin();
|
|
35
|
+
setError(AUTH_ERROR_MESSAGE);
|
|
36
|
+
});
|
|
37
|
+
};
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
return (
|
|
40
|
+
<Center axis="both" style={pageStyle}>
|
|
41
|
+
<VStack gap={4} hAlign="center" style={contentStyle}>
|
|
42
|
+
<LoginBrand />
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
44
|
+
<AuthCard selfHash="#/templates/login-card">
|
|
45
|
+
<AuthLoginFields
|
|
46
|
+
email={email}
|
|
47
|
+
password={password}
|
|
48
|
+
error={error}
|
|
49
|
+
selfHash="#/templates/login-card"
|
|
50
|
+
isLoading={isLoading}
|
|
51
|
+
onEmailChange={(v: string) => {
|
|
52
|
+
setEmail(v);
|
|
53
|
+
setError(null);
|
|
54
|
+
}}
|
|
55
|
+
onPasswordChange={(v: string) => {
|
|
56
|
+
setPassword(v);
|
|
57
|
+
setError(null);
|
|
58
|
+
}}
|
|
59
|
+
onSubmit={handleLogin}
|
|
60
|
+
/>
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
{/* Divider */}
|
|
63
|
+
<Divider label={AUTH_SSO_DIVIDER} />
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
label="Login with Google"
|
|
74
|
-
variant="secondary"
|
|
75
|
-
icon={<GoogleIcon />}
|
|
76
|
-
size="lg"
|
|
77
|
-
/>
|
|
78
|
-
</VStack>
|
|
79
|
-
</AuthCard>
|
|
80
|
-
</VStack>
|
|
81
|
-
</Center>
|
|
82
|
-
);
|
|
65
|
+
{/* Social buttons */}
|
|
66
|
+
<VStack gap={3} hAlign="stretch">
|
|
67
|
+
<Button label="Login with Apple" variant="secondary" icon={<AppleIcon />} size="lg" />
|
|
68
|
+
<Button label="Login with Google" variant="secondary" icon={<GoogleIcon />} size="lg" />
|
|
69
|
+
</VStack>
|
|
70
|
+
</AuthCard>
|
|
71
|
+
</VStack>
|
|
72
|
+
</Center>
|
|
73
|
+
);
|
|
83
74
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
type: "page",
|
|
3
|
+
name: "Login Split",
|
|
4
|
+
description: "Two-column auth with cover art panel",
|
|
5
|
+
keywords: ["login", "sign in", "auth", "split", "credentials", "account"],
|
|
6
|
+
category: "auth",
|
|
6
7
|
};
|
|
@@ -1,51 +1,53 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
// XLE (canonical structure
|
|
3
|
-
//
|
|
2
|
+
// XLE (canonical structure of the tree below; the CLI had no XLE validator
|
|
3
|
+
// after `astryx layout` was removed in 0.7.0, so this is a reading aid and a
|
|
4
|
+
// human drift check — update it with the file, never alone):
|
|
5
|
+
// Ctr > V[g=4] > (Ctr.horizontal > C[p=0] > G[c={min:240} g=8 a=stretch] > (S.transparent[p=0] > V[g=4] > (H[g=2 a=center] > Ic + Tx"Castle Dracula"[t=body]) + (V[g=4] > (V[g=1] > Hd"Welcome back to the night"[level=1 t=display-2] + Tx"Sign in to your crypt"[t=body]) + (V[g=2] > TI"Email"[t=email] + (V[g=1] > TI"Password"[t=password] + Lk"Forgot password?")) + B.primary"Sign in" + D"Or continue with" + (G[c={min:200} g=3] > B.secondary"Login with Apple" + B.secondary"Login with Google")) + (V[a=center] > Tx"New to the castle?"[t=supporting] + Lk"Sign up")) + (C.transparent[p=0] > Scene{SceneCastle})) + (V[a=center] > Tx"By clicking continue, you agree to our Terms of service and Privacy policy"[t=supporting])
|
|
4
6
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { Button } from "@astryxdesign/core/Button";
|
|
8
|
+
import { Card } from "@astryxdesign/core/Card";
|
|
9
|
+
import { Center } from "@astryxdesign/core/Center";
|
|
10
|
+
import { Divider } from "@astryxdesign/core/Divider";
|
|
11
|
+
import { Grid } from "@astryxdesign/core/Grid";
|
|
12
|
+
import { Icon } from "@astryxdesign/core/Icon";
|
|
13
|
+
import { HStack, StackItem, VStack } from "@astryxdesign/core/Layout";
|
|
14
|
+
import { Link } from "@astryxdesign/core/Link";
|
|
15
|
+
import { Section } from "@astryxdesign/core/Section";
|
|
16
|
+
import { Heading, Text } from "@astryxdesign/core/Text";
|
|
17
|
+
import { TextInput } from "@astryxdesign/core/TextInput";
|
|
18
|
+
import { authPageStyle, inputAutoComplete } from "astryx-dracula/shared/auth-chrome-config";
|
|
9
19
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
} from
|
|
25
|
-
import {SceneCastle} from 'astryx-dracula/shared/scene-castle';
|
|
26
|
-
import {VStack, HStack, StackItem} from '@astryxdesign/core/Layout';
|
|
27
|
-
import {Grid} from '@astryxdesign/core/Grid';
|
|
28
|
-
import {Center} from '@astryxdesign/core/Center';
|
|
29
|
-
import {Card} from '@astryxdesign/core/Card';
|
|
30
|
-
import {Section} from '@astryxdesign/core/Section';
|
|
31
|
-
import {Text, Heading} from '@astryxdesign/core/Text';
|
|
32
|
-
import {Icon} from '@astryxdesign/core/Icon';
|
|
33
|
-
import {TextInput} from '@astryxdesign/core/TextInput';
|
|
34
|
-
import {Button} from '@astryxdesign/core/Button';
|
|
35
|
-
import {Link} from '@astryxdesign/core/Link';
|
|
36
|
-
import {Divider} from '@astryxdesign/core/Divider';
|
|
20
|
+
AUTH_BRAND_NAME,
|
|
21
|
+
AUTH_EMAIL_PLACEHOLDER,
|
|
22
|
+
AUTH_ERROR_MESSAGE,
|
|
23
|
+
AUTH_FORGOT_PASSWORD,
|
|
24
|
+
AUTH_HEADING,
|
|
25
|
+
AUTH_PASSWORD_PLACEHOLDER,
|
|
26
|
+
AUTH_PRIMARY_CTA,
|
|
27
|
+
AUTH_SIGNUP_LINK,
|
|
28
|
+
AUTH_SIGNUP_PROMPT,
|
|
29
|
+
AUTH_SSO_DIVIDER,
|
|
30
|
+
AUTH_SUBTITLE,
|
|
31
|
+
AUTH_TERMS_PREFIX,
|
|
32
|
+
AUTH_TERMS_PRIVACY,
|
|
33
|
+
AUTH_TERMS_SERVICE,
|
|
34
|
+
} from "astryx-dracula/shared/auth-copy";
|
|
37
35
|
|
|
36
|
+
import { demoLogin } from "astryx-dracula/shared/login-demo";
|
|
37
|
+
import { SceneCastle } from "astryx-dracula/shared/scene-castle";
|
|
38
|
+
import { AppleIcon, GoogleIcon } from "astryx-dracula/shared/sso-icons";
|
|
38
39
|
// ============= ICONS (verified lucide-react exports) =============
|
|
39
40
|
// Moon is the castle brand mark (see login, login-card).
|
|
40
|
-
import {Moon} from
|
|
41
|
+
import { Moon } from "lucide-react";
|
|
42
|
+
import { useState, useTransition } from "react";
|
|
41
43
|
|
|
42
44
|
// Cover art lives in shared/scene-castle (`rooftops` variant:
|
|
43
45
|
// crescent-overlay moon over a rooftop skyline). The transparent Card clips
|
|
44
46
|
// it to rounded corners (overflow:clip + radius), so the art needs no radius.
|
|
45
47
|
const cardWrap = {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
width: "100%",
|
|
49
|
+
maxWidth: 1000,
|
|
50
|
+
marginInline: "auto",
|
|
49
51
|
} as const;
|
|
50
52
|
|
|
51
53
|
// The container query lives in a plain <style> tag so it needs NO CSS compiler.
|
|
@@ -79,177 +81,174 @@ const LOGIN_SPLIT_CSS = `
|
|
|
79
81
|
`;
|
|
80
82
|
|
|
81
83
|
export default function LoginSplit() {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
const [email, setEmail] = useState("");
|
|
85
|
+
const [password, setPassword] = useState("");
|
|
86
|
+
const [error, setError] = useState<string | null>(null);
|
|
87
|
+
const [isLoading, startTransition] = useTransition();
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
const handleLogin = () => {
|
|
90
|
+
if (!email || !password) {
|
|
91
|
+
setError(AUTH_ERROR_MESSAGE);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
setError(null);
|
|
95
|
+
startTransition(async () => {
|
|
96
|
+
await demoLogin();
|
|
97
|
+
});
|
|
98
|
+
};
|
|
97
99
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
100
|
+
return (
|
|
101
|
+
<Center axis="both" style={authPageStyle}>
|
|
102
|
+
<style>{LOGIN_SPLIT_CSS}</style>
|
|
103
|
+
<VStack gap={4} width="100%">
|
|
104
|
+
<Center axis="horizontal" style={cardWrap}>
|
|
105
|
+
<Card padding={0} width="100%">
|
|
106
|
+
<Grid
|
|
107
|
+
columns={{ minWidth: 240, repeat: "fit" }}
|
|
108
|
+
gap={8}
|
|
109
|
+
align="stretch"
|
|
110
|
+
className="login-split-grid"
|
|
111
|
+
>
|
|
112
|
+
{/* Form */}
|
|
113
|
+
<Section variant="transparent" padding={0} height="100%">
|
|
114
|
+
<VStack gap={4} height="100%">
|
|
115
|
+
<HStack gap={2} vAlign="center">
|
|
116
|
+
<Icon icon={Moon} color="secondary" size="lg" />
|
|
117
|
+
<Text type="body" weight="semibold">
|
|
118
|
+
{AUTH_BRAND_NAME}
|
|
119
|
+
</Text>
|
|
120
|
+
</HStack>
|
|
118
121
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
122
|
+
<StackItem size="fill">
|
|
123
|
+
<Center axis="vertical" height="100%">
|
|
124
|
+
<VStack gap={4} hAlign="stretch" width="100%">
|
|
125
|
+
<VStack gap={1}>
|
|
126
|
+
<Heading level={1} type="display-2">
|
|
127
|
+
{AUTH_HEADING}
|
|
128
|
+
</Heading>
|
|
129
|
+
<Text type="body" color="secondary">
|
|
130
|
+
{AUTH_SUBTITLE}
|
|
131
|
+
</Text>
|
|
132
|
+
</VStack>
|
|
130
133
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
</VStack>
|
|
173
|
-
</VStack>
|
|
134
|
+
<VStack gap={2}>
|
|
135
|
+
<TextInput
|
|
136
|
+
label="Email"
|
|
137
|
+
isLabelHidden
|
|
138
|
+
type="email"
|
|
139
|
+
{...inputAutoComplete("email")}
|
|
140
|
+
placeholder={AUTH_EMAIL_PLACEHOLDER}
|
|
141
|
+
value={email}
|
|
142
|
+
onChange={(v: string) => {
|
|
143
|
+
setEmail(v);
|
|
144
|
+
setError(null);
|
|
145
|
+
}}
|
|
146
|
+
size="lg"
|
|
147
|
+
onEnter={handleLogin}
|
|
148
|
+
status={error ? { type: "error", message: error } : undefined}
|
|
149
|
+
/>
|
|
150
|
+
<VStack gap={1}>
|
|
151
|
+
<TextInput
|
|
152
|
+
label="Password"
|
|
153
|
+
isLabelHidden
|
|
154
|
+
placeholder={AUTH_PASSWORD_PLACEHOLDER}
|
|
155
|
+
type="password"
|
|
156
|
+
{...inputAutoComplete("current-password")}
|
|
157
|
+
value={password}
|
|
158
|
+
onChange={(v: string) => {
|
|
159
|
+
setPassword(v);
|
|
160
|
+
setError(null);
|
|
161
|
+
}}
|
|
162
|
+
size="lg"
|
|
163
|
+
onEnter={handleLogin}
|
|
164
|
+
status={error ? { type: "error", message: error } : undefined}
|
|
165
|
+
/>
|
|
166
|
+
{error && (
|
|
167
|
+
<VStack hAlign="end">
|
|
168
|
+
<Link href="#/templates/login-split" isStandalone>
|
|
169
|
+
{AUTH_FORGOT_PASSWORD}
|
|
170
|
+
</Link>
|
|
171
|
+
</VStack>
|
|
172
|
+
)}
|
|
173
|
+
</VStack>
|
|
174
|
+
</VStack>
|
|
174
175
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
176
|
+
<Button
|
|
177
|
+
label={AUTH_PRIMARY_CTA}
|
|
178
|
+
variant="primary"
|
|
179
|
+
size="lg"
|
|
180
|
+
isLoading={isLoading}
|
|
181
|
+
onClick={handleLogin}
|
|
182
|
+
/>
|
|
182
183
|
|
|
183
|
-
|
|
184
|
+
<Divider label={AUTH_SSO_DIVIDER} />
|
|
184
185
|
|
|
185
|
-
|
|
186
|
+
{/* minWidth (not a fixed 2-up) so the pair stacks inside
|
|
186
187
|
the narrow single-column container instead of
|
|
187
188
|
giving each button ~114px for an icon + label. */}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
</VStack>
|
|
206
|
-
</Center>
|
|
207
|
-
</StackItem>
|
|
189
|
+
<Grid columns={{ minWidth: 200, repeat: "fit" }} gap={3} justify="stretch">
|
|
190
|
+
<Button
|
|
191
|
+
label="Login with Apple"
|
|
192
|
+
variant="secondary"
|
|
193
|
+
icon={<AppleIcon />}
|
|
194
|
+
size="lg"
|
|
195
|
+
/>
|
|
196
|
+
<Button
|
|
197
|
+
label="Login with Google"
|
|
198
|
+
variant="secondary"
|
|
199
|
+
icon={<GoogleIcon />}
|
|
200
|
+
size="lg"
|
|
201
|
+
/>
|
|
202
|
+
</Grid>
|
|
203
|
+
</VStack>
|
|
204
|
+
</Center>
|
|
205
|
+
</StackItem>
|
|
208
206
|
|
|
209
|
-
|
|
207
|
+
{/* Prose link: colour alone is not a cue inside a sentence
|
|
210
208
|
(WCAG 1.4.1 / F73), so it asks for the underline the kit
|
|
211
209
|
only gives on hover. The VStack centres the line, as the
|
|
212
210
|
other three login templates do — it was sitting flush
|
|
213
211
|
left under a left-aligned form. */}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
212
|
+
<VStack hAlign="center">
|
|
213
|
+
<Text type="supporting" color="secondary">
|
|
214
|
+
{AUTH_SIGNUP_PROMPT}{" "}
|
|
215
|
+
<Link href="#/templates/login-split" type="supporting" hasUnderline>
|
|
216
|
+
{AUTH_SIGNUP_LINK}
|
|
217
|
+
</Link>
|
|
218
|
+
</Text>
|
|
219
|
+
</VStack>
|
|
220
|
+
</VStack>
|
|
221
|
+
</Section>
|
|
224
222
|
|
|
225
|
-
|
|
223
|
+
{/* Cover art — the transparent Card clips it to rounded
|
|
226
224
|
corners (overflow:clip + radius), so the art needs no radius. */}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
225
|
+
<Card
|
|
226
|
+
variant="transparent"
|
|
227
|
+
padding={0}
|
|
228
|
+
width="100%"
|
|
229
|
+
height="100%"
|
|
230
|
+
className="login-split-image"
|
|
231
|
+
>
|
|
232
|
+
<SceneCastle variant="rooftops" />
|
|
233
|
+
</Card>
|
|
234
|
+
</Grid>
|
|
235
|
+
</Card>
|
|
236
|
+
</Center>
|
|
238
237
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
238
|
+
<VStack hAlign="center" width="100%">
|
|
239
|
+
<Text type="supporting" color="secondary" justify="center">
|
|
240
|
+
{AUTH_TERMS_PREFIX}{" "}
|
|
241
|
+
<Link href="#/templates/login-split" type="supporting" hasUnderline>
|
|
242
|
+
{AUTH_TERMS_SERVICE}
|
|
243
|
+
</Link>{" "}
|
|
244
|
+
and{" "}
|
|
245
|
+
<Link href="#/templates/login-split" type="supporting" hasUnderline>
|
|
246
|
+
{AUTH_TERMS_PRIVACY}
|
|
247
|
+
</Link>
|
|
248
|
+
.
|
|
249
|
+
</Text>
|
|
250
|
+
</VStack>
|
|
251
|
+
</VStack>
|
|
252
|
+
</Center>
|
|
253
|
+
);
|
|
255
254
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
type: "page",
|
|
3
|
+
name: "Login SSO",
|
|
4
|
+
description: "Email-first SSO with password fallback",
|
|
5
|
+
keywords: ["login", "sso", "saml", "oauth", "auth", "providers", "account"],
|
|
6
|
+
category: "auth",
|
|
6
7
|
};
|