@aws-amplify/ui-svelte 0.0.0-next-c8114c5-20220105200507
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/.eslintrc.cjs +20 -0
- package/.turbo/turbo-build.log +135 -0
- package/CHANGELOG.md +15 -0
- package/README.md +38 -0
- package/dist/README.md +38 -0
- package/dist/components/Authenticator.svelte +43 -0
- package/dist/components/Authenticator.svelte.d.ts +22 -0
- package/dist/components/SignIn.svelte +69 -0
- package/dist/components/SignIn.svelte.d.ts +14 -0
- package/dist/components/UserNameAlias.svelte +29 -0
- package/dist/components/UserNameAlias.svelte.d.ts +19 -0
- package/dist/components/authStore.d.ts +20 -0
- package/dist/components/authStore.js +100 -0
- package/dist/components/primitives/AmplifyButton.svelte +23 -0
- package/dist/components/primitives/AmplifyButton.svelte.d.ts +25 -0
- package/dist/components/primitives/AmplifyError.svelte +46 -0
- package/dist/components/primitives/AmplifyError.svelte.d.ts +16 -0
- package/dist/components/primitives/AmplifyFormField.svelte +121 -0
- package/dist/components/primitives/AmplifyFormField.svelte.d.ts +25 -0
- package/dist/components/primitives/AmplifyFormSelect.svelte +38 -0
- package/dist/components/primitives/AmplifyFormSelect.svelte.d.ts +20 -0
- package/dist/components/primitives/AmplifyPasswordField.svelte +75 -0
- package/dist/components/primitives/AmplifyPasswordField.svelte.d.ts +26 -0
- package/dist/components/primitives/AmplifyPhoneNumberField.svelte +50 -0
- package/dist/components/primitives/AmplifyPhoneNumberField.svelte.d.ts +27 -0
- package/dist/components/primitives/AmplifyTabItem.svelte +0 -0
- package/dist/components/primitives/AmplifyTabItem.svelte.d.ts +19 -0
- package/dist/components/primitives/AmplifyTabs.svelte +50 -0
- package/dist/components/primitives/AmplifyTabs.svelte.d.ts +14 -0
- package/dist/components/primitives/AmplifyTextField.svelte +31 -0
- package/dist/components/primitives/AmplifyTextField.svelte.d.ts +28 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/package.json +60 -0
- package/dist/styles.css +1 -0
- package/package.json +57 -0
- package/src/app.html +21 -0
- package/src/global.d.ts +1 -0
- package/src/lib/components/Authenticator.svelte +52 -0
- package/src/lib/components/SignIn.svelte +79 -0
- package/src/lib/components/UserNameAlias.svelte +32 -0
- package/src/lib/components/authStore.ts +138 -0
- package/src/lib/components/primitives/AmplifyButton.svelte +25 -0
- package/src/lib/components/primitives/AmplifyError.svelte +48 -0
- package/src/lib/components/primitives/AmplifyFormField.svelte +146 -0
- package/src/lib/components/primitives/AmplifyFormSelect.svelte +39 -0
- package/src/lib/components/primitives/AmplifyPasswordField.svelte +78 -0
- package/src/lib/components/primitives/AmplifyPhoneNumberField.svelte +52 -0
- package/src/lib/components/primitives/AmplifyTabItem.svelte +0 -0
- package/src/lib/components/primitives/AmplifyTabs.svelte +52 -0
- package/src/lib/components/primitives/AmplifyTextField.svelte +33 -0
- package/src/lib/index.ts +4 -0
- package/src/lib/styles.css +1 -0
- package/src/routes/index.svelte +8 -0
- package/static/favicon.png +0 -0
- package/svelte.config.js +41 -0
- package/tsconfig.json +31 -0
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aws-amplify/ui-svelte",
|
|
3
|
+
"version": "0.0.0-next-c8114c5-20220105200507",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"svelte": "index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"./styles.css": "./dist/styles.css"
|
|
12
|
+
},
|
|
13
|
+
"browser": {
|
|
14
|
+
"./styles.css": "./dist/styles.css"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"dev": "svelte-kit dev",
|
|
18
|
+
"build": "svelte-kit build",
|
|
19
|
+
"postbuild": "svelte-kit package",
|
|
20
|
+
"package": "svelte-kit package",
|
|
21
|
+
"preview": "svelte-kit preview",
|
|
22
|
+
"check": "svelte-check --tsconfig ./tsconfig.json",
|
|
23
|
+
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
|
|
24
|
+
"lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .",
|
|
25
|
+
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@sveltejs/adapter-auto": "next",
|
|
29
|
+
"@sveltejs/adapter-node": "^1.0.0-next.56",
|
|
30
|
+
"@sveltejs/adapter-static": "^1.0.0-next.23",
|
|
31
|
+
"@sveltejs/kit": "next",
|
|
32
|
+
"@typescript-eslint/eslint-plugin": "^4.31.1",
|
|
33
|
+
"@typescript-eslint/parser": "^4.31.1",
|
|
34
|
+
"eslint": "^7.32.0",
|
|
35
|
+
"eslint-config-prettier": "^8.3.0",
|
|
36
|
+
"eslint-plugin-svelte3": "^3.2.1",
|
|
37
|
+
"prettier": "^2.4.1",
|
|
38
|
+
"prettier-plugin-svelte": "^2.4.0",
|
|
39
|
+
"svelte": "^3.44.0",
|
|
40
|
+
"svelte-check": "^2.2.6",
|
|
41
|
+
"svelte-preprocess": "^4.9.4",
|
|
42
|
+
"svelte2tsx": "^0.4.12",
|
|
43
|
+
"tslib": "^2.3.1",
|
|
44
|
+
"typescript": "^4.4.3"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"aws-amplify": "^4.2.2"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@aws-amplify/ui": "^0.0.0-next-c8114c5-20220105200507",
|
|
51
|
+
"@rollup/plugin-replace": "^3.0.0",
|
|
52
|
+
"nanoid": "^3.1.30",
|
|
53
|
+
"qrcode": "^1.5.0",
|
|
54
|
+
"svelte2tsx": "^0.4.12",
|
|
55
|
+
"xstate": "^4.26.1"
|
|
56
|
+
}
|
|
57
|
+
}
|
package/src/app.html
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="description" content="" />
|
|
6
|
+
<link rel="icon" href="/favicon.png" />
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
8
|
+
%svelte.head%
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="svelte">%svelte.body%</div>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
14
|
+
<script>
|
|
15
|
+
const isBrowser = () => typeof window !== 'undefined';
|
|
16
|
+
const isGlobal = () => typeof global !== 'undefined';
|
|
17
|
+
var exports = {};
|
|
18
|
+
if (!isGlobal() && isBrowser()) {
|
|
19
|
+
var global = window;
|
|
20
|
+
}
|
|
21
|
+
</script>
|
package/src/global.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="@sveltejs/kit" />
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onDestroy } from 'svelte';
|
|
3
|
+
import { setupMachine, route, toSignIn } from '$lib/components/authStore';
|
|
4
|
+
import SignIn from './SignIn.svelte';
|
|
5
|
+
import AmplifyTabs from './primitives/AmplifyTabs.svelte';
|
|
6
|
+
|
|
7
|
+
export let initialState = undefined;
|
|
8
|
+
export let loginMechanisms = undefined;
|
|
9
|
+
export let services = undefined;
|
|
10
|
+
export let signUpAttributes = undefined;
|
|
11
|
+
export let socialProviders = undefined;
|
|
12
|
+
|
|
13
|
+
const _subscription = setupMachine(
|
|
14
|
+
initialState,
|
|
15
|
+
loginMechanisms,
|
|
16
|
+
services,
|
|
17
|
+
signUpAttributes,
|
|
18
|
+
socialProviders
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
onDestroy(() => {
|
|
22
|
+
if (_subscription) _subscription.unsubscribe();
|
|
23
|
+
});
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
{#if $route !== 'authenticated'}
|
|
27
|
+
<div data-amplify-authenticator>
|
|
28
|
+
<div data-amplify-container>
|
|
29
|
+
<!--Slot header goes here-->
|
|
30
|
+
<div data-amplify-router>
|
|
31
|
+
{#if $route === 'signIn' || $route === 'signUp'}
|
|
32
|
+
<AmplifyTabs />
|
|
33
|
+
{/if}
|
|
34
|
+
|
|
35
|
+
{#if $route === 'signIn'}
|
|
36
|
+
<SignIn />
|
|
37
|
+
{/if}
|
|
38
|
+
{#if $route === 'signUp'}
|
|
39
|
+
<p>Sign Up</p>
|
|
40
|
+
<button on:click={toSignIn}>To Sign In</button>
|
|
41
|
+
{/if}
|
|
42
|
+
{#if $route === 'resetPassword'}
|
|
43
|
+
<p>reset password</p>
|
|
44
|
+
<button on:click={toSignIn}>To Sign In</button>
|
|
45
|
+
{/if}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
{/if}
|
|
50
|
+
{#if $route === 'authenticated'}
|
|
51
|
+
<slot />
|
|
52
|
+
{/if}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import AmplifyFormField from './primitives/AmplifyFormField.svelte';
|
|
3
|
+
import AmplifyError from './primitives/AmplifyError.svelte';
|
|
4
|
+
import UserNameAlias from './UserNameAlias.svelte';
|
|
5
|
+
import AmplifyButton from './primitives/AmplifyButton.svelte';
|
|
6
|
+
import { translate } from '@aws-amplify/ui';
|
|
7
|
+
import {
|
|
8
|
+
updateForm,
|
|
9
|
+
submitForm,
|
|
10
|
+
isPending,
|
|
11
|
+
error,
|
|
12
|
+
toResetPassword,
|
|
13
|
+
} from '$lib/components/authStore';
|
|
14
|
+
|
|
15
|
+
const forgotPasswordText = translate('Forgot your password? ');
|
|
16
|
+
const signInButtonText = translate('Sign in');
|
|
17
|
+
const signingButtonText = translate('Signing in');
|
|
18
|
+
|
|
19
|
+
function onInput(event: Event) {
|
|
20
|
+
event.preventDefault();
|
|
21
|
+
const { name, value } = <HTMLInputElement>event.target;
|
|
22
|
+
updateForm({ name, value });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function onSubmit(event: Event): void {
|
|
26
|
+
event.preventDefault();
|
|
27
|
+
submitForm();
|
|
28
|
+
}
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<div data-amplify-container>
|
|
32
|
+
<form
|
|
33
|
+
data-amplify-form
|
|
34
|
+
on:submit|preventDefault={onSubmit}
|
|
35
|
+
on:input={onInput}
|
|
36
|
+
>
|
|
37
|
+
<fieldset
|
|
38
|
+
class="amplify-flex"
|
|
39
|
+
style="flex-direction: column"
|
|
40
|
+
data-amplify-fieldset
|
|
41
|
+
disabled={$isPending}
|
|
42
|
+
>
|
|
43
|
+
<UserNameAlias />
|
|
44
|
+
<AmplifyFormField
|
|
45
|
+
data-amplify-password
|
|
46
|
+
name="password"
|
|
47
|
+
type="password"
|
|
48
|
+
autocomplete="current-password"
|
|
49
|
+
/>
|
|
50
|
+
<AmplifyButton
|
|
51
|
+
disabled={$isPending}
|
|
52
|
+
variation="primary"
|
|
53
|
+
fullWidth="true"
|
|
54
|
+
type="submit"
|
|
55
|
+
>
|
|
56
|
+
{$isPending ? signingButtonText : signInButtonText}
|
|
57
|
+
</AmplifyButton>
|
|
58
|
+
|
|
59
|
+
{#if $error}
|
|
60
|
+
<AmplifyError>
|
|
61
|
+
{$error}
|
|
62
|
+
</AmplifyError>
|
|
63
|
+
{/if}
|
|
64
|
+
</fieldset>
|
|
65
|
+
</form>
|
|
66
|
+
|
|
67
|
+
<div data-amplify-footer>
|
|
68
|
+
<AmplifyButton
|
|
69
|
+
amplify-button
|
|
70
|
+
fontWeight="normal"
|
|
71
|
+
data-size="small"
|
|
72
|
+
variation="link"
|
|
73
|
+
fullWidth="true"
|
|
74
|
+
on:click={toResetPassword}
|
|
75
|
+
>
|
|
76
|
+
{forgotPasswordText}
|
|
77
|
+
</AmplifyButton>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import AmplifyFormField from './primitives/AmplifyFormField.svelte';
|
|
3
|
+
import { onMount } from 'svelte';
|
|
4
|
+
import { authState } from '$lib/components/authStore';
|
|
5
|
+
import { getAliasInfoFromContext } from '@aws-amplify/ui';
|
|
6
|
+
export let name: string = 'username';
|
|
7
|
+
export let disabled: boolean = false;
|
|
8
|
+
export let initialValue: string = '';
|
|
9
|
+
export let required: boolean = true;
|
|
10
|
+
let label: string;
|
|
11
|
+
let type: string;
|
|
12
|
+
let error: string;
|
|
13
|
+
let placeholder: string;
|
|
14
|
+
|
|
15
|
+
onMount(() => {
|
|
16
|
+
const { label, type } = getAliasInfoFromContext($authState.context);
|
|
17
|
+
|
|
18
|
+
placeholder = label;
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<AmplifyFormField
|
|
23
|
+
data-amplify-usernamealias
|
|
24
|
+
{name}
|
|
25
|
+
{label}
|
|
26
|
+
{type}
|
|
27
|
+
{placeholder}
|
|
28
|
+
{initialValue}
|
|
29
|
+
{disabled}
|
|
30
|
+
{required}
|
|
31
|
+
autocomplete="username"
|
|
32
|
+
/>
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createAuthenticatorMachine,
|
|
3
|
+
getServiceContextFacade,
|
|
4
|
+
getSendEventAliases,
|
|
5
|
+
translate,
|
|
6
|
+
} from '@aws-amplify/ui';
|
|
7
|
+
import { interpret } from 'xstate';
|
|
8
|
+
|
|
9
|
+
import { writable, get } from 'svelte/store';
|
|
10
|
+
|
|
11
|
+
let _facade = writable<ReturnType<typeof getServiceContextFacade>>(null);
|
|
12
|
+
export const error = writable(null);
|
|
13
|
+
export const route = writable(null);
|
|
14
|
+
export const isPending = writable(null);
|
|
15
|
+
export const hasValidationErrors = writable(null);
|
|
16
|
+
export const user = writable(null);
|
|
17
|
+
export const validationErrors = writable(null);
|
|
18
|
+
export const codeDeliveryDetails = writable(null);
|
|
19
|
+
const _sendEventAliases =
|
|
20
|
+
writable<ReturnType<typeof getSendEventAliases>>(null);
|
|
21
|
+
/** @deprecated For internal use only */
|
|
22
|
+
export const authState = writable(null);
|
|
23
|
+
|
|
24
|
+
export function setupMachine(
|
|
25
|
+
initialState,
|
|
26
|
+
loginMechanisms,
|
|
27
|
+
services,
|
|
28
|
+
signUpAttributes,
|
|
29
|
+
socialProviders
|
|
30
|
+
) {
|
|
31
|
+
const machine = createAuthenticatorMachine({
|
|
32
|
+
initialState,
|
|
33
|
+
loginMechanisms,
|
|
34
|
+
services,
|
|
35
|
+
signUpAttributes,
|
|
36
|
+
socialProviders,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const authService = interpret(machine, {
|
|
40
|
+
devTools: process.env.NODE_ENV === 'development',
|
|
41
|
+
}).start();
|
|
42
|
+
|
|
43
|
+
const subscription = authService.subscribe((state) => {
|
|
44
|
+
authState.update(() => state);
|
|
45
|
+
_facade.update(() => getServiceContextFacade(state));
|
|
46
|
+
setError();
|
|
47
|
+
setRoute();
|
|
48
|
+
setHasValidationErrors();
|
|
49
|
+
setCodeDeliveryDetails();
|
|
50
|
+
setIsPending();
|
|
51
|
+
setUser();
|
|
52
|
+
setValidationErrors();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
_sendEventAliases.set(getSendEventAliases(authService.send));
|
|
56
|
+
const _authService = authService;
|
|
57
|
+
return subscription;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Context facades
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
function setError() {
|
|
65
|
+
error.set(translate(get(_facade).error));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function setRoute() {
|
|
69
|
+
route.set(get(_facade).route);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function setHasValidationErrors() {
|
|
73
|
+
hasValidationErrors.set(get(_facade).hasValidationErrors);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function setIsPending() {
|
|
77
|
+
isPending.set(get(_facade).isPending);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function setUser() {
|
|
81
|
+
user.set(get(_facade).user);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function setValidationErrors() {
|
|
85
|
+
validationErrors.set(get(_facade).validationErrors);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function setCodeDeliveryDetails() {
|
|
89
|
+
codeDeliveryDetails.set(get(_facade).codeDeliveryDetails);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// /**
|
|
93
|
+
// * Service facades
|
|
94
|
+
// */
|
|
95
|
+
|
|
96
|
+
export function updateForm(...args) {
|
|
97
|
+
return get(_sendEventAliases).updateForm(...args);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function updateBlur(...args) {
|
|
101
|
+
return get(_sendEventAliases).updateBlur(...args);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function resendCode(...args) {
|
|
105
|
+
return get(_sendEventAliases).resendCode(...args);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function signOut(...args) {
|
|
109
|
+
return get(_sendEventAliases).signOut(...args);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function submitForm(...args) {
|
|
113
|
+
return get(_sendEventAliases).submitForm(...args);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// /**
|
|
117
|
+
// * Transition facades
|
|
118
|
+
// */
|
|
119
|
+
|
|
120
|
+
export function toFederatedSignIn(...args) {
|
|
121
|
+
return get(_sendEventAliases).toFederatedSignIn(...args);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function toResetPassword(...args) {
|
|
125
|
+
return get(_sendEventAliases).toResetPassword(...args);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function toSignIn(...args) {
|
|
129
|
+
return get(_sendEventAliases).toSignIn(...args);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function toSignUp(...args) {
|
|
133
|
+
return get(_sendEventAliases).toSignUp(...args);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function skipVerification(...args) {
|
|
137
|
+
return get(_sendEventAliases).skipVerification(...args);
|
|
138
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { createEventDispatcher } from 'svelte';
|
|
3
|
+
export let type: 'submit' | 'button' = 'button';
|
|
4
|
+
export let fullWidth: boolean | string = false;
|
|
5
|
+
export let size: 'small' | 'medium' | 'large' = 'medium';
|
|
6
|
+
export let variation: 'primary' | 'default' | 'link' = 'default';
|
|
7
|
+
export let fontWeight: 'normal' | 'bold' | 'lighter' = 'normal';
|
|
8
|
+
|
|
9
|
+
const dispatch = createEventDispatcher();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<button
|
|
13
|
+
{...$$restProps}
|
|
14
|
+
on:click={() => dispatch('click')}
|
|
15
|
+
class={`amplify-button ${$$props.class ?? ''}`}
|
|
16
|
+
{type}
|
|
17
|
+
style="font-weight: {fontWeight} "
|
|
18
|
+
data-fullwidth={fullWidth}
|
|
19
|
+
data-size={size}
|
|
20
|
+
data-fontWeight={fontWeight}
|
|
21
|
+
data-variation={variation}
|
|
22
|
+
data-amplify-button=""
|
|
23
|
+
>
|
|
24
|
+
<slot />
|
|
25
|
+
</button>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import AmplifyButton from './AmplifyButton.svelte';
|
|
3
|
+
let isVisible = true;
|
|
4
|
+
|
|
5
|
+
function close() {
|
|
6
|
+
isVisible = false;
|
|
7
|
+
}
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
{#if isVisible}
|
|
11
|
+
<div
|
|
12
|
+
class="amplify-flex amplify-alert"
|
|
13
|
+
data-variation="error"
|
|
14
|
+
style="align-items: center; justify-content: space-between"
|
|
15
|
+
role="alert"
|
|
16
|
+
>
|
|
17
|
+
<div class="amplify-flex" style="align-items: center">
|
|
18
|
+
<svg
|
|
19
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
20
|
+
class="amplify-icon"
|
|
21
|
+
viewBox="0 0 24 24"
|
|
22
|
+
fill="currentColor"
|
|
23
|
+
>
|
|
24
|
+
<path
|
|
25
|
+
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"
|
|
26
|
+
/>
|
|
27
|
+
</svg>
|
|
28
|
+
<div><slot /></div>
|
|
29
|
+
</div>
|
|
30
|
+
<AmplifyButton
|
|
31
|
+
class="amplify-field-group__control"
|
|
32
|
+
variation="link"
|
|
33
|
+
fullWidth={false}
|
|
34
|
+
on:click={close}
|
|
35
|
+
>
|
|
36
|
+
<svg
|
|
37
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
38
|
+
class="amplify-icon"
|
|
39
|
+
viewBox="0 0 24 24"
|
|
40
|
+
fill="currentColor"
|
|
41
|
+
>
|
|
42
|
+
<path
|
|
43
|
+
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
|
|
44
|
+
/>
|
|
45
|
+
</svg>
|
|
46
|
+
</AmplifyButton>
|
|
47
|
+
</div>
|
|
48
|
+
{/if}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import AmplifyPhoneNumberField from './AmplifyPhoneNumberField.svelte';
|
|
3
|
+
import AmplifyPasswordField from './AmplifyPasswordField.svelte';
|
|
4
|
+
import AmplifyTextField from './AmplifyTextField.svelte';
|
|
5
|
+
import AmplifyError from './AmplifyError.svelte';
|
|
6
|
+
|
|
7
|
+
import { authState, updateForm, updateBlur } from '$lib/components/authStore';
|
|
8
|
+
import {
|
|
9
|
+
ActorContextWithForms,
|
|
10
|
+
authInputAttributes,
|
|
11
|
+
AuthInputAttributes,
|
|
12
|
+
getActorContext,
|
|
13
|
+
translate,
|
|
14
|
+
} from '@aws-amplify/ui';
|
|
15
|
+
|
|
16
|
+
import { onMount } from 'svelte';
|
|
17
|
+
|
|
18
|
+
export let name: string;
|
|
19
|
+
export let type: string;
|
|
20
|
+
export let required = true;
|
|
21
|
+
export let placeholder = '';
|
|
22
|
+
export let label = '';
|
|
23
|
+
export let initialValue = '';
|
|
24
|
+
export let disabled = false;
|
|
25
|
+
export let autocomplete = '';
|
|
26
|
+
export let labelHidden = true;
|
|
27
|
+
|
|
28
|
+
const getAttributeMap: AttributeInfoProvider = () => authInputAttributes;
|
|
29
|
+
type AttributeInfoProvider = () => AuthInputAttributes;
|
|
30
|
+
|
|
31
|
+
let defaultCountryCode: string;
|
|
32
|
+
onMount(() => {
|
|
33
|
+
if (isPhoneField) {
|
|
34
|
+
const state = $authState;
|
|
35
|
+
const { country_code }: ActorContextWithForms = getActorContext(state);
|
|
36
|
+
defaultCountryCode = country_code;
|
|
37
|
+
|
|
38
|
+
// TODO: remove this side-effect
|
|
39
|
+
updateForm({
|
|
40
|
+
name: 'country_code',
|
|
41
|
+
value: country_code,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const attributeMap = getAttributeMap();
|
|
47
|
+
|
|
48
|
+
let error: string;
|
|
49
|
+
$: {
|
|
50
|
+
const formContext: ActorContextWithForms = getActorContext($authState);
|
|
51
|
+
const { validationError } = formContext;
|
|
52
|
+
error = translate(validationError[name]);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function onBlur($event) {
|
|
56
|
+
let { name } = <HTMLInputElement>$event?.detail?.target;
|
|
57
|
+
|
|
58
|
+
updateBlur({ name });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let inferLabel: string;
|
|
62
|
+
$: {
|
|
63
|
+
const myLabel = label || attributeMap[name]?.label;
|
|
64
|
+
inferLabel = translate<string>(myLabel);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let inferPlaceholder: string;
|
|
68
|
+
$: {
|
|
69
|
+
const myPlaceholder =
|
|
70
|
+
placeholder || attributeMap[name]?.placeholder || inferLabel;
|
|
71
|
+
inferPlaceholder = translate<string>(myPlaceholder);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// infers what the `type` of underlying input element should be.
|
|
75
|
+
let inferType: string;
|
|
76
|
+
$: {
|
|
77
|
+
inferType = type ?? attributeMap[name]?.type ?? 'text';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let inferAutocomplete: string;
|
|
81
|
+
$: {
|
|
82
|
+
inferAutocomplete = autocomplete || attributeMap[name]?.autocomplete;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// TODO(enhancement): use enum to differentiate special field types
|
|
86
|
+
let isPasswordField: boolean;
|
|
87
|
+
$: {
|
|
88
|
+
isPasswordField = inferType === 'password';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let isPhoneField: boolean;
|
|
92
|
+
isPhoneField = inferType === 'tel';
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
<div class="amplify-flex amplify-field" style="flex-direction: column">
|
|
96
|
+
<!-- Country code field -->
|
|
97
|
+
{#if isPhoneField}
|
|
98
|
+
<AmplifyPhoneNumberField
|
|
99
|
+
{defaultCountryCode}
|
|
100
|
+
type={inferType}
|
|
101
|
+
{name}
|
|
102
|
+
label={inferLabel}
|
|
103
|
+
placeholder={inferPlaceholder}
|
|
104
|
+
{required}
|
|
105
|
+
{initialValue}
|
|
106
|
+
{disabled}
|
|
107
|
+
{labelHidden}
|
|
108
|
+
autocomplete={inferAutocomplete}
|
|
109
|
+
/>
|
|
110
|
+
{/if}
|
|
111
|
+
|
|
112
|
+
{#if isPasswordField}
|
|
113
|
+
<AmplifyPasswordField
|
|
114
|
+
{...$$restProps}
|
|
115
|
+
{name}
|
|
116
|
+
label={inferLabel}
|
|
117
|
+
placeholder={inferPlaceholder}
|
|
118
|
+
{required}
|
|
119
|
+
{initialValue}
|
|
120
|
+
{disabled}
|
|
121
|
+
{labelHidden}
|
|
122
|
+
autocomplete={inferAutocomplete}
|
|
123
|
+
/>
|
|
124
|
+
{/if}
|
|
125
|
+
|
|
126
|
+
{#if !isPasswordField && !isPhoneField}
|
|
127
|
+
<AmplifyTextField
|
|
128
|
+
on:blur={onBlur}
|
|
129
|
+
type={inferType}
|
|
130
|
+
{name}
|
|
131
|
+
label={inferLabel}
|
|
132
|
+
placeholder={inferPlaceholder}
|
|
133
|
+
{required}
|
|
134
|
+
{initialValue}
|
|
135
|
+
{disabled}
|
|
136
|
+
{labelHidden}
|
|
137
|
+
autocomplete={inferAutocomplete}
|
|
138
|
+
/>
|
|
139
|
+
{/if}
|
|
140
|
+
|
|
141
|
+
{#if error}
|
|
142
|
+
<AmplifyError>
|
|
143
|
+
{error}
|
|
144
|
+
</AmplifyError>
|
|
145
|
+
{/if}
|
|
146
|
+
</div>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export let items: string[];
|
|
3
|
+
export let name: string;
|
|
4
|
+
export let label: string;
|
|
5
|
+
export let id: string;
|
|
6
|
+
export let defaultValue: string;
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<label class="amplify-label sr-only" for={id}>
|
|
10
|
+
{label}
|
|
11
|
+
</label>
|
|
12
|
+
<div class="amplify-select__wrapper">
|
|
13
|
+
<select
|
|
14
|
+
class="amplify-select amplify-field-group__control"
|
|
15
|
+
autocomplete="tel-country-code"
|
|
16
|
+
{id}
|
|
17
|
+
{name}
|
|
18
|
+
>
|
|
19
|
+
{#each items as item}
|
|
20
|
+
<option value={item} selected={item === defaultValue}>
|
|
21
|
+
{item}
|
|
22
|
+
</option>
|
|
23
|
+
{/each}
|
|
24
|
+
</select>
|
|
25
|
+
<div
|
|
26
|
+
class="amplify-flex amplify-select__icon-wrapper"
|
|
27
|
+
style="align-items: center; justify-content: center"
|
|
28
|
+
>
|
|
29
|
+
<svg
|
|
30
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
31
|
+
class="amplify-icon"
|
|
32
|
+
viewBox="0 0 24 24"
|
|
33
|
+
data-size="large"
|
|
34
|
+
fill="currentColor"
|
|
35
|
+
>
|
|
36
|
+
<path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" />
|
|
37
|
+
</svg>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|