@draftlab/auth 0.1.6 → 0.2.0
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/dist/ui/base.js +228 -228
- package/dist/ui/code.js +12 -84
- package/dist/ui/form.d.ts +0 -1
- package/dist/ui/form.js +35 -45
- package/dist/ui/passkey.js +38 -61
- package/package.json +1 -1
package/dist/ui/base.js
CHANGED
|
@@ -6,293 +6,293 @@ import { jsx, jsxs } from "preact/jsx-runtime";
|
|
|
6
6
|
const css = `@import url("https://unpkg.com/tailwindcss@3.4.15/src/css/preflight.css");
|
|
7
7
|
|
|
8
8
|
:root {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
--font-family:
|
|
69
|
-
ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
|
|
70
|
-
"Segoe UI Symbol", "Noto Color Emoji";
|
|
71
|
-
--font-scale: 1;
|
|
72
|
-
|
|
73
|
-
--font-size-xs: calc(0.75rem * var(--font-scale));
|
|
74
|
-
--font-size-sm: calc(0.875rem * var(--font-scale));
|
|
75
|
-
--font-size-md: calc(1rem * var(--font-scale));
|
|
76
|
-
--font-size-lg: calc(1.125rem * var(--font-scale));
|
|
77
|
-
--font-size-xl: calc(1.25rem * var(--font-scale));
|
|
78
|
-
--font-size-2xl: calc(1.5rem * var(--font-scale));
|
|
9
|
+
--color-background-dark: #0e0e11;
|
|
10
|
+
--color-background-light: #ffffff;
|
|
11
|
+
--color-primary-dark: #6772e5;
|
|
12
|
+
--color-primary-light: #6772e5;
|
|
13
|
+
|
|
14
|
+
--color-background-success-dark: oklch(0.3 0.04 172);
|
|
15
|
+
--color-background-success-light: oklch(from var(--color-background-success-dark) 0.83 c h);
|
|
16
|
+
--color-success-dark: oklch(from var(--color-background-success-dark) 0.92 c h);
|
|
17
|
+
--color-success-light: oklch(from var(--color-background-success-dark) 0.25 c h);
|
|
18
|
+
|
|
19
|
+
--color-background-error-dark: oklch(0.32 0.07 15);
|
|
20
|
+
--color-background-error-light: oklch(from var(--color-background-error-dark) 0.92 c h);
|
|
21
|
+
--color-error-dark: oklch(from var(--color-background-error-dark) 0.92 c h);
|
|
22
|
+
--color-error-light: oklch(from var(--color-background-error-dark) 0.25 c h);
|
|
23
|
+
|
|
24
|
+
--border-radius: 0;
|
|
25
|
+
|
|
26
|
+
--color-background: var(--color-background-dark);
|
|
27
|
+
--color-primary: var(--color-primary-dark);
|
|
28
|
+
|
|
29
|
+
--color-background-success: var(--color-background-success-dark);
|
|
30
|
+
--color-success: var(--color-success-dark);
|
|
31
|
+
--color-background-error: var(--color-background-error-dark);
|
|
32
|
+
--color-error: var(--color-error-dark);
|
|
33
|
+
|
|
34
|
+
@media (prefers-color-scheme: light) {
|
|
35
|
+
--color-background: var(--color-background-light);
|
|
36
|
+
--color-primary: var(--color-primary-light);
|
|
37
|
+
|
|
38
|
+
--color-background-success: var(--color-background-success-light);
|
|
39
|
+
--color-success: var(--color-success-light);
|
|
40
|
+
--color-background-error: var(--color-background-error-light);
|
|
41
|
+
--color-error: var(--color-error-light);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
--color-high: oklch(
|
|
45
|
+
from var(--color-background) clamp(0, calc((l - 0.714) * -1000), 1) 0 0
|
|
46
|
+
);
|
|
47
|
+
--color-low: oklch(from var(--color-background) clamp(0, calc((l - 0.714) * 1000), 1) 0 0);
|
|
48
|
+
--lightness-high: color-mix(
|
|
49
|
+
in oklch,
|
|
50
|
+
var(--color-high) 0%,
|
|
51
|
+
oklch(var(--color-high) 0 0)
|
|
52
|
+
);
|
|
53
|
+
--lightness-low: color-mix(
|
|
54
|
+
in oklch,
|
|
55
|
+
var(--color-low) 0%,
|
|
56
|
+
oklch(var(--color-low) 0 0)
|
|
57
|
+
);
|
|
58
|
+
--font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
|
|
59
|
+
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
60
|
+
--font-scale: 1;
|
|
61
|
+
|
|
62
|
+
--font-size-xs: calc(0.75rem * var(--font-scale));
|
|
63
|
+
--font-size-sm: calc(0.875rem * var(--font-scale));
|
|
64
|
+
--font-size-md: calc(1rem * var(--font-scale));
|
|
65
|
+
--font-size-lg: calc(1.125rem * var(--font-scale));
|
|
66
|
+
--font-size-xl: calc(1.25rem * var(--font-scale));
|
|
67
|
+
--font-size-2xl: calc(1.5rem * var(--font-scale));
|
|
79
68
|
}
|
|
80
69
|
|
|
81
70
|
[data-component="root"] {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
71
|
+
font-family: var(--font-family);
|
|
72
|
+
background-color: var(--color-background);
|
|
73
|
+
padding: 1rem;
|
|
74
|
+
color: white;
|
|
75
|
+
position: absolute;
|
|
76
|
+
inset: 0;
|
|
77
|
+
display: flex;
|
|
78
|
+
align-items: center;
|
|
79
|
+
justify-content: center;
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
user-select: none;
|
|
82
|
+
color: var(--color-high);
|
|
94
83
|
}
|
|
95
84
|
|
|
96
85
|
[data-component="center"] {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
86
|
+
width: 380px;
|
|
87
|
+
display: flex;
|
|
88
|
+
flex-direction: column;
|
|
89
|
+
gap: 1.5rem;
|
|
101
90
|
}
|
|
102
91
|
|
|
103
92
|
[data-component="center"][data-size="small"] {
|
|
104
|
-
|
|
93
|
+
width: 300px;
|
|
105
94
|
}
|
|
106
95
|
|
|
107
|
-
[data-component="
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
font-weight: 500;
|
|
112
|
-
font-size: var(--font-size-sm);
|
|
113
|
-
border-radius: calc(var(--border-radius) * 0.25rem);
|
|
114
|
-
display: flex;
|
|
115
|
-
gap: 0.75rem;
|
|
116
|
-
align-items: center;
|
|
117
|
-
justify-content: center;
|
|
118
|
-
background: var(--color-primary);
|
|
119
|
-
color: oklch(
|
|
120
|
-
from var(--color-primary) clamp(0, calc((l - 0.714) * -1000), 1) 0 0
|
|
121
|
-
);
|
|
96
|
+
[data-component="link"] {
|
|
97
|
+
text-decoration: underline;
|
|
98
|
+
text-underline-offset: 0.125rem;
|
|
99
|
+
font-weight: 600;
|
|
122
100
|
}
|
|
123
101
|
|
|
124
|
-
[data-component="
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
from var(--color-background)
|
|
130
|
-
calc(
|
|
131
|
-
clamp(
|
|
132
|
-
0.22,
|
|
133
|
-
l +
|
|
134
|
-
(-0.12 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.06),
|
|
135
|
-
0.88
|
|
136
|
-
)
|
|
137
|
-
)
|
|
138
|
-
c h
|
|
139
|
-
);
|
|
102
|
+
[data-component="label"] {
|
|
103
|
+
display: flex;
|
|
104
|
+
gap: 0.75rem;
|
|
105
|
+
flex-direction: column;
|
|
106
|
+
font-size: var(--font-size-xs);
|
|
140
107
|
}
|
|
141
108
|
|
|
142
|
-
[data-component="
|
|
143
|
-
|
|
144
|
-
|
|
109
|
+
[data-component="logo"] {
|
|
110
|
+
margin: 0 auto;
|
|
111
|
+
height: 2.5rem;
|
|
112
|
+
width: auto;
|
|
113
|
+
display: none;
|
|
145
114
|
}
|
|
146
115
|
|
|
147
|
-
[data-component="
|
|
148
|
-
|
|
149
|
-
height: 100%;
|
|
116
|
+
[data-component="logo"][data-mode="light"] {
|
|
117
|
+
display: none;
|
|
150
118
|
}
|
|
151
119
|
|
|
152
|
-
[data-component="
|
|
153
|
-
|
|
154
|
-
display: flex;
|
|
155
|
-
flex-direction: column;
|
|
156
|
-
gap: 1rem;
|
|
157
|
-
margin: 0;
|
|
120
|
+
[data-component="logo"][data-mode="dark"] {
|
|
121
|
+
display: block;
|
|
158
122
|
}
|
|
159
123
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
l +
|
|
169
|
-
(-0.12 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.06),
|
|
170
|
-
0.88
|
|
171
|
-
)
|
|
172
|
-
)
|
|
173
|
-
c h
|
|
174
|
-
);
|
|
175
|
-
border-radius: calc(var(--border-radius) * 0.25rem);
|
|
176
|
-
background: var(--color-background);
|
|
177
|
-
color: var(--color-high);
|
|
178
|
-
padding: 0 0.75rem;
|
|
179
|
-
font-size: var(--font-size-sm);
|
|
180
|
-
font-family: var(--font-family);
|
|
124
|
+
@media (prefers-color-scheme: light) {
|
|
125
|
+
[data-component="logo"][data-mode="light"] {
|
|
126
|
+
display: block;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
[data-component="logo"][data-mode="dark"] {
|
|
130
|
+
display: none;
|
|
131
|
+
}
|
|
181
132
|
}
|
|
182
133
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
134
|
+
@media (prefers-color-scheme: dark) {
|
|
135
|
+
[data-component="logo"][data-mode="dark"] {
|
|
136
|
+
display: block;
|
|
137
|
+
}
|
|
186
138
|
}
|
|
187
139
|
|
|
188
|
-
[data-component="
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
c
|
|
193
|
-
h /
|
|
194
|
-
0.6
|
|
195
|
-
);
|
|
140
|
+
[data-component="logo-default"] {
|
|
141
|
+
margin: 0 auto;
|
|
142
|
+
height: 2.5rem;
|
|
143
|
+
width: auto;
|
|
196
144
|
}
|
|
197
145
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
align-items: center;
|
|
203
|
-
gap: 0.75rem;
|
|
204
|
-
font-size: var(--font-size-sm);
|
|
146
|
+
@media (prefers-color-scheme: light) {
|
|
147
|
+
[data-component="logo-default"] {
|
|
148
|
+
color: var(--color-high);
|
|
149
|
+
}
|
|
205
150
|
}
|
|
206
151
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
152
|
+
@media (prefers-color-scheme: dark) {
|
|
153
|
+
[data-component="logo-default"] {
|
|
154
|
+
color: var(--color-high);
|
|
155
|
+
}
|
|
211
156
|
}
|
|
212
157
|
|
|
213
|
-
[data-component="
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
158
|
+
[data-component="input"] {
|
|
159
|
+
width: 100%;
|
|
160
|
+
height: 2.5rem;
|
|
161
|
+
padding: 0 1rem;
|
|
162
|
+
border: 1px solid transparent;
|
|
163
|
+
--background: oklch(
|
|
164
|
+
from var(--color-background) calc(l + (-0.06 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.03)) c h
|
|
165
|
+
);
|
|
166
|
+
background: var(--background);
|
|
167
|
+
border-color: oklch(
|
|
168
|
+
from var(--color-background)
|
|
169
|
+
calc(clamp(0.22, l + (-0.12 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.06), 0.88)) c h
|
|
170
|
+
);
|
|
171
|
+
border-radius: calc(var(--border-radius) * 0.25rem);
|
|
172
|
+
font-size: var(--font-size-sm);
|
|
173
|
+
outline: none;
|
|
217
174
|
}
|
|
218
175
|
|
|
219
|
-
[data-component="
|
|
220
|
-
|
|
176
|
+
[data-component="input"]:focus {
|
|
177
|
+
border-color: oklch(
|
|
178
|
+
from var(--color-background)
|
|
179
|
+
calc(clamp(0.3, l + (-0.2 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.1), 0.7)) c h
|
|
180
|
+
);
|
|
221
181
|
}
|
|
222
182
|
|
|
223
|
-
[data-component="
|
|
224
|
-
|
|
183
|
+
[data-component="input"]:user-invalid:not(:focus) {
|
|
184
|
+
border-color: oklch(0.4 0.09 7.91);
|
|
225
185
|
}
|
|
226
186
|
|
|
227
|
-
[data-component="
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
187
|
+
[data-component="button"] {
|
|
188
|
+
height: 2.5rem;
|
|
189
|
+
cursor: pointer;
|
|
190
|
+
border: 0;
|
|
191
|
+
font-weight: 500;
|
|
192
|
+
font-size: var(--font-size-sm);
|
|
193
|
+
border-radius: calc(var(--border-radius) * 0.25rem);
|
|
194
|
+
display: flex;
|
|
195
|
+
gap: 0.75rem;
|
|
196
|
+
align-items: center;
|
|
197
|
+
justify-content: center;
|
|
198
|
+
background: var(--color-primary);
|
|
199
|
+
color: oklch(from var(--color-primary) clamp(0, calc((l - 0.714) * -1000), 1) 0 0);
|
|
231
200
|
}
|
|
232
201
|
|
|
233
|
-
[data-component="
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
202
|
+
[data-component="button"][data-color="ghost"] {
|
|
203
|
+
background: transparent;
|
|
204
|
+
color: var(--color-high);
|
|
205
|
+
border: 1px solid
|
|
206
|
+
oklch(
|
|
207
|
+
from var(--color-background)
|
|
208
|
+
calc(clamp(0.22, l + (-0.12 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.06), 0.88)) c h
|
|
209
|
+
);
|
|
237
210
|
}
|
|
238
211
|
|
|
239
|
-
[data-component="
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
font-size: var(--font-size-sm);
|
|
212
|
+
[data-component="button"] [data-slot="icon"] {
|
|
213
|
+
width: 16px;
|
|
214
|
+
height: 16px;
|
|
243
215
|
}
|
|
244
216
|
|
|
245
|
-
[data-component="
|
|
246
|
-
|
|
217
|
+
[data-component="button"] [data-slot="icon"] svg {
|
|
218
|
+
width: 100%;
|
|
219
|
+
height: 100%;
|
|
247
220
|
}
|
|
248
221
|
|
|
249
|
-
[data-component="form
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
222
|
+
[data-component="form"] {
|
|
223
|
+
max-width: 100%;
|
|
224
|
+
display: flex;
|
|
225
|
+
flex-direction: column;
|
|
226
|
+
gap: 1rem;
|
|
227
|
+
margin: 0;
|
|
255
228
|
}
|
|
256
229
|
|
|
257
|
-
[data-component="form-
|
|
258
|
-
|
|
230
|
+
[data-component="form-alert"] {
|
|
231
|
+
height: 2.5rem;
|
|
232
|
+
display: flex;
|
|
233
|
+
align-items: center;
|
|
234
|
+
padding: 0 1rem;
|
|
235
|
+
border-radius: calc(var(--border-radius) * 0.25rem);
|
|
236
|
+
background: var(--color-background-error);
|
|
237
|
+
color: var(--color-error);
|
|
238
|
+
text-align: left;
|
|
239
|
+
font-size: 0.75rem;
|
|
240
|
+
gap: 0.5rem;
|
|
259
241
|
}
|
|
260
242
|
|
|
261
|
-
[data-component="
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
width: auto;
|
|
243
|
+
[data-component="form-alert"][data-color="success"] {
|
|
244
|
+
background: var(--color-background-success);
|
|
245
|
+
color: var(--color-success);
|
|
265
246
|
}
|
|
266
247
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
color: var(--color-high);
|
|
270
|
-
}
|
|
248
|
+
[data-component="form-alert"][data-color="success"] [data-slot="icon-success"] {
|
|
249
|
+
display: block;
|
|
271
250
|
}
|
|
272
251
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
color: var(--color-high);
|
|
276
|
-
}
|
|
252
|
+
[data-component="form-alert"][data-color="success"] [data-slot="icon-danger"] {
|
|
253
|
+
display: none;
|
|
277
254
|
}
|
|
278
255
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
display: none;
|
|
256
|
+
[data-component="form-alert"]:has([data-slot="message"]:empty) {
|
|
257
|
+
display: none;
|
|
282
258
|
}
|
|
283
259
|
|
|
284
|
-
[data-component="
|
|
285
|
-
|
|
260
|
+
[data-component="form-alert"] [data-slot="icon-success"],
|
|
261
|
+
[data-component="form-alert"] [data-slot="icon-danger"] {
|
|
262
|
+
width: 1rem;
|
|
263
|
+
height: 1rem;
|
|
286
264
|
}
|
|
287
265
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
266
|
+
[data-component="form-alert"] [data-slot="icon-success"] {
|
|
267
|
+
display: none;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
[data-component="form-footer"] {
|
|
271
|
+
display: flex;
|
|
272
|
+
gap: 1rem;
|
|
273
|
+
font-size: 0.75rem;
|
|
274
|
+
align-items: center;
|
|
275
|
+
justify-content: center;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
[data-component="form-footer"]:has(> :nth-child(2)) {
|
|
279
|
+
justify-content: space-between;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
[data-component="title"] {
|
|
283
|
+
font-size: var(--font-size-2xl);
|
|
284
|
+
font-weight: 600;
|
|
285
|
+
margin: 0 0 0.5rem 0;
|
|
286
|
+
color: var(--color-high);
|
|
287
|
+
text-align: center;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
[data-component="description"] {
|
|
291
|
+
font-size: var(--font-size-sm);
|
|
292
|
+
color: var(--color-high);
|
|
293
|
+
margin: 0 0 1.5rem 0;
|
|
294
|
+
text-align: center;
|
|
295
|
+
opacity: 0.8;
|
|
296
296
|
}
|
|
297
297
|
`;
|
|
298
298
|
/**
|
package/dist/ui/code.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Layout, renderToHTML } from "./base.js";
|
|
2
|
+
import { FormAlert } from "./form.js";
|
|
2
3
|
import { jsx, jsxs } from "preact/jsx-runtime";
|
|
3
4
|
|
|
4
5
|
//#region src/ui/code.tsx
|
|
@@ -18,74 +19,6 @@ const DEFAULT_COPY = {
|
|
|
18
19
|
code_resend: "Resend"
|
|
19
20
|
};
|
|
20
21
|
/**
|
|
21
|
-
* FormAlert component for displaying messages
|
|
22
|
-
*/
|
|
23
|
-
const FormAlert = ({ message, color = "danger" }) => {
|
|
24
|
-
if (!message) return null;
|
|
25
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
26
|
-
"data-component": "form-alert",
|
|
27
|
-
"data-color": color,
|
|
28
|
-
children: [/* @__PURE__ */ jsx("i", {
|
|
29
|
-
"data-slot": color === "success" ? "icon-success" : "icon-danger",
|
|
30
|
-
children: color === "success" ? /* @__PURE__ */ jsx("svg", {
|
|
31
|
-
fill: "none",
|
|
32
|
-
stroke: "currentColor",
|
|
33
|
-
viewBox: "0 0 24 24",
|
|
34
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
35
|
-
"aria-label": "Success",
|
|
36
|
-
role: "img",
|
|
37
|
-
children: /* @__PURE__ */ jsx("path", {
|
|
38
|
-
strokeLinecap: "round",
|
|
39
|
-
strokeLinejoin: "round",
|
|
40
|
-
strokeWidth: 2,
|
|
41
|
-
d: "M5 13l4 4L19 7"
|
|
42
|
-
})
|
|
43
|
-
}) : /* @__PURE__ */ jsx("svg", {
|
|
44
|
-
fill: "none",
|
|
45
|
-
stroke: "currentColor",
|
|
46
|
-
viewBox: "0 0 24 24",
|
|
47
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
48
|
-
"aria-label": "Error",
|
|
49
|
-
role: "img",
|
|
50
|
-
children: /* @__PURE__ */ jsx("path", {
|
|
51
|
-
strokeLinecap: "round",
|
|
52
|
-
strokeLinejoin: "round",
|
|
53
|
-
strokeWidth: 2,
|
|
54
|
-
d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L4.232 16.5c-.77.833.192 2.5 1.732 2.5z"
|
|
55
|
-
})
|
|
56
|
-
})
|
|
57
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
58
|
-
"data-slot": "message",
|
|
59
|
-
children: message
|
|
60
|
-
})]
|
|
61
|
-
});
|
|
62
|
-
};
|
|
63
|
-
/**
|
|
64
|
-
* Input component with consistent styling
|
|
65
|
-
*/
|
|
66
|
-
const Input = ({ type, name, placeholder, value, required, autoComplete, autoFocus,...props }) => /* @__PURE__ */ jsx("input", {
|
|
67
|
-
type,
|
|
68
|
-
name,
|
|
69
|
-
placeholder,
|
|
70
|
-
value,
|
|
71
|
-
required,
|
|
72
|
-
autoComplete,
|
|
73
|
-
"data-component": "input",
|
|
74
|
-
...props
|
|
75
|
-
});
|
|
76
|
-
/**
|
|
77
|
-
* Button component with consistent styling
|
|
78
|
-
*/
|
|
79
|
-
const Button = ({ type = "submit", children,...props }) => /* @__PURE__ */ jsx("button", {
|
|
80
|
-
type,
|
|
81
|
-
"data-component": "button",
|
|
82
|
-
...props,
|
|
83
|
-
children
|
|
84
|
-
});
|
|
85
|
-
/**
|
|
86
|
-
* Link component with consistent styling
|
|
87
|
-
*/
|
|
88
|
-
/**
|
|
89
22
|
* Gets the appropriate error message for display
|
|
90
23
|
*/
|
|
91
24
|
const getErrorMessage = (error, copy) => {
|
|
@@ -129,7 +62,8 @@ const CodeUI = (options) => {
|
|
|
129
62
|
message: success.message,
|
|
130
63
|
color: "success"
|
|
131
64
|
}) : /* @__PURE__ */ jsx(FormAlert, { message: getErrorMessage(error, copy) }),
|
|
132
|
-
/* @__PURE__ */ jsx(
|
|
65
|
+
/* @__PURE__ */ jsx("input", {
|
|
66
|
+
"data-component": "input",
|
|
133
67
|
type: mode === "email" ? "email" : "tel",
|
|
134
68
|
name: mode,
|
|
135
69
|
placeholder: copy.email_placeholder,
|
|
@@ -142,17 +76,13 @@ const CodeUI = (options) => {
|
|
|
142
76
|
name: "action",
|
|
143
77
|
value: "request"
|
|
144
78
|
}),
|
|
145
|
-
/* @__PURE__ */ jsx(
|
|
79
|
+
/* @__PURE__ */ jsx("button", {
|
|
80
|
+
"data-component": "button",
|
|
146
81
|
type: "submit",
|
|
147
82
|
children: copy.button_continue
|
|
148
83
|
}),
|
|
149
84
|
/* @__PURE__ */ jsx("p", {
|
|
150
|
-
|
|
151
|
-
fontSize: "0.875rem",
|
|
152
|
-
color: "var(--color-high)",
|
|
153
|
-
textAlign: "center",
|
|
154
|
-
margin: "1rem 0 0 0"
|
|
155
|
-
},
|
|
85
|
+
"data-component": "description",
|
|
156
86
|
children: copy.code_info
|
|
157
87
|
})
|
|
158
88
|
]
|
|
@@ -177,7 +107,8 @@ const CodeUI = (options) => {
|
|
|
177
107
|
type: "hidden",
|
|
178
108
|
value: "verify"
|
|
179
109
|
}),
|
|
180
|
-
/* @__PURE__ */ jsx(
|
|
110
|
+
/* @__PURE__ */ jsx("input", {
|
|
111
|
+
"data-component": "input",
|
|
181
112
|
type: "text",
|
|
182
113
|
name: "code",
|
|
183
114
|
placeholder: copy.code_placeholder,
|
|
@@ -187,10 +118,10 @@ const CodeUI = (options) => {
|
|
|
187
118
|
maxLength: 6,
|
|
188
119
|
minLength: 6,
|
|
189
120
|
pattern: "[0-9]{6}",
|
|
190
|
-
autoFocus: true,
|
|
191
121
|
required: true
|
|
192
122
|
}),
|
|
193
|
-
/* @__PURE__ */ jsx(
|
|
123
|
+
/* @__PURE__ */ jsx("button", {
|
|
124
|
+
"data-component": "button",
|
|
194
125
|
type: "submit",
|
|
195
126
|
children: copy.button_continue
|
|
196
127
|
})
|
|
@@ -210,12 +141,9 @@ const CodeUI = (options) => {
|
|
|
210
141
|
}),
|
|
211
142
|
/* @__PURE__ */ jsxs("div", {
|
|
212
143
|
"data-component": "form-footer",
|
|
213
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
214
|
-
|
|
215
|
-
children: copy.code_didnt_get
|
|
216
|
-
}), /* @__PURE__ */ jsx(Button, {
|
|
144
|
+
children: [/* @__PURE__ */ jsx("span", { children: copy.code_didnt_get }), /* @__PURE__ */ jsx("button", {
|
|
145
|
+
"data-component": "button",
|
|
217
146
|
type: "submit",
|
|
218
|
-
"data-component": "link",
|
|
219
147
|
children: copy.code_resend
|
|
220
148
|
})]
|
|
221
149
|
})
|
package/dist/ui/form.d.ts
CHANGED
package/dist/ui/form.js
CHANGED
|
@@ -2,56 +2,46 @@ import { jsx, jsxs } from "preact/jsx-runtime";
|
|
|
2
2
|
|
|
3
3
|
//#region src/ui/form.tsx
|
|
4
4
|
/**
|
|
5
|
-
* Success icon component showing a checkmark in a circle.
|
|
6
|
-
* Used for positive feedback messages.
|
|
7
|
-
*/
|
|
8
|
-
const SuccessIcon = () => /* @__PURE__ */ jsx("svg", {
|
|
9
|
-
"aria-hidden": "true",
|
|
10
|
-
"data-slot": "icon-success",
|
|
11
|
-
fill: "none",
|
|
12
|
-
stroke: "currentColor",
|
|
13
|
-
strokeWidth: "1.5",
|
|
14
|
-
viewBox: "0 0 24 24",
|
|
15
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
16
|
-
children: /* @__PURE__ */ jsx("path", {
|
|
17
|
-
d: "M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z",
|
|
18
|
-
strokeLinecap: "round",
|
|
19
|
-
strokeLinejoin: "round"
|
|
20
|
-
})
|
|
21
|
-
});
|
|
22
|
-
/**
|
|
23
|
-
* Danger icon component showing an exclamation mark in a circle.
|
|
24
|
-
* Used for error and warning messages.
|
|
25
|
-
*/
|
|
26
|
-
const DangerIcon = () => /* @__PURE__ */ jsx("svg", {
|
|
27
|
-
"aria-hidden": "true",
|
|
28
|
-
"data-slot": "icon-danger",
|
|
29
|
-
fill: "none",
|
|
30
|
-
stroke: "currentColor",
|
|
31
|
-
strokeWidth: "1.5",
|
|
32
|
-
viewBox: "0 0 24 24",
|
|
33
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
34
|
-
children: /* @__PURE__ */ jsx("path", {
|
|
35
|
-
d: "M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z",
|
|
36
|
-
strokeLinecap: "round",
|
|
37
|
-
strokeLinejoin: "round"
|
|
38
|
-
})
|
|
39
|
-
});
|
|
40
|
-
/**
|
|
41
5
|
* Form alert component that displays error or success messages.
|
|
42
|
-
* Returns a Preact component or null if no message.
|
|
43
6
|
*/
|
|
44
7
|
const FormAlert = ({ message, color = "danger" }) => {
|
|
45
|
-
if (!message) return null;
|
|
46
8
|
return /* @__PURE__ */ jsxs("div", {
|
|
47
|
-
"aria-live": "polite",
|
|
48
|
-
"data-color": color,
|
|
49
9
|
"data-component": "form-alert",
|
|
50
|
-
|
|
51
|
-
children: [
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
10
|
+
"data-color": color,
|
|
11
|
+
children: [
|
|
12
|
+
/* @__PURE__ */ jsx("svg", {
|
|
13
|
+
"aria-hidden": "true",
|
|
14
|
+
"data-slot": "icon-success",
|
|
15
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
16
|
+
fill: "none",
|
|
17
|
+
viewBox: "0 0 24 24",
|
|
18
|
+
"stroke-width": "1.5",
|
|
19
|
+
stroke: "currentColor",
|
|
20
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
21
|
+
"stroke-linecap": "round",
|
|
22
|
+
"stroke-linejoin": "round",
|
|
23
|
+
d: "M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
|
|
24
|
+
})
|
|
25
|
+
}),
|
|
26
|
+
/* @__PURE__ */ jsx("svg", {
|
|
27
|
+
"aria-hidden": "true",
|
|
28
|
+
"data-slot": "icon-danger",
|
|
29
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
30
|
+
fill: "none",
|
|
31
|
+
viewBox: "0 0 24 24",
|
|
32
|
+
"stroke-width": "1.5",
|
|
33
|
+
stroke: "currentColor",
|
|
34
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
35
|
+
"stroke-linecap": "round",
|
|
36
|
+
"stroke-linejoin": "round",
|
|
37
|
+
d: "M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z"
|
|
38
|
+
})
|
|
39
|
+
}),
|
|
40
|
+
/* @__PURE__ */ jsx("span", {
|
|
41
|
+
"data-slot": "message",
|
|
42
|
+
children: message
|
|
43
|
+
})
|
|
44
|
+
]
|
|
55
45
|
});
|
|
56
46
|
};
|
|
57
47
|
|
package/dist/ui/passkey.js
CHANGED
|
@@ -33,37 +33,16 @@ const PasskeyUI = (options) => {
|
|
|
33
33
|
window.addEventListener("load", async () => {
|
|
34
34
|
const { startAuthentication } = SimpleWebAuthnBrowser;
|
|
35
35
|
const authorizeForm = document.getElementById("authorizeForm");
|
|
36
|
+
const message = document.querySelector("[data-slot='message']");
|
|
36
37
|
const origin = window.location.origin;
|
|
37
38
|
const rpID = window.location.hostname;
|
|
38
39
|
|
|
39
|
-
const showMessage = (msg) => {
|
|
40
|
-
const messageEl = document.querySelector("[data-slot='message']");
|
|
41
|
-
if (messageEl) {
|
|
42
|
-
messageEl.innerHTML = msg;
|
|
43
|
-
} else {
|
|
44
|
-
// Create alert if it doesn't exist
|
|
45
|
-
const alertDiv = document.createElement("div");
|
|
46
|
-
alertDiv.setAttribute("data-component", "form-alert");
|
|
47
|
-
alertDiv.setAttribute("role", "alert");
|
|
48
|
-
alertDiv.setAttribute("aria-live", "polite");
|
|
49
|
-
alertDiv.setAttribute("data-color", "error");
|
|
50
|
-
alertDiv.innerHTML = '<span data-slot="message">' + msg + '</span>';
|
|
51
|
-
authorizeForm.insertBefore(alertDiv, authorizeForm.firstChild);
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const clearMessage = () => {
|
|
56
|
-
const alertDiv = document.querySelector("[data-component='form-alert']");
|
|
57
|
-
if (alertDiv) {
|
|
58
|
-
alertDiv.remove();
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
|
|
62
40
|
authorizeForm.addEventListener("submit", async (e) => {
|
|
63
41
|
e.preventDefault();
|
|
64
42
|
const formData = new FormData(authorizeForm);
|
|
65
43
|
const email = formData.get("email");
|
|
66
|
-
|
|
44
|
+
|
|
45
|
+
message.textContent = "";
|
|
67
46
|
|
|
68
47
|
// GET authentication options from the endpoint that calls
|
|
69
48
|
// @simplewebauthn/server -> generateAuthenticationOptions()
|
|
@@ -74,7 +53,7 @@ const PasskeyUI = (options) => {
|
|
|
74
53
|
const optionsJSON = await resp.json();
|
|
75
54
|
|
|
76
55
|
if (optionsJSON.error) {
|
|
77
|
-
|
|
56
|
+
message.textContent = optionsJSON.error;
|
|
78
57
|
return;
|
|
79
58
|
}
|
|
80
59
|
|
|
@@ -83,7 +62,7 @@ const PasskeyUI = (options) => {
|
|
|
83
62
|
// Pass the options to the authenticator and wait for a response
|
|
84
63
|
attResp = await startAuthentication({ optionsJSON });
|
|
85
64
|
} catch (error) {
|
|
86
|
-
|
|
65
|
+
message.textContent = error;
|
|
87
66
|
throw error;
|
|
88
67
|
}
|
|
89
68
|
|
|
@@ -116,25 +95,35 @@ const PasskeyUI = (options) => {
|
|
|
116
95
|
);
|
|
117
96
|
try {
|
|
118
97
|
const errorData = await verificationResp.json();
|
|
119
|
-
|
|
98
|
+
message.textContent = errorData.error;
|
|
120
99
|
} catch (error) {
|
|
121
|
-
|
|
100
|
+
message.textContent = "Something went wrong";
|
|
122
101
|
}
|
|
123
102
|
}
|
|
124
103
|
});
|
|
125
104
|
});
|
|
126
105
|
` } }),
|
|
127
|
-
/* @__PURE__ */ jsx("h1", {
|
|
128
|
-
|
|
106
|
+
/* @__PURE__ */ jsx("h1", {
|
|
107
|
+
"data-component": "title",
|
|
108
|
+
children: copy.authorize_title
|
|
109
|
+
}),
|
|
110
|
+
/* @__PURE__ */ jsx("p", {
|
|
111
|
+
"data-component": "description",
|
|
112
|
+
children: copy.authorize_description
|
|
113
|
+
}),
|
|
129
114
|
/* @__PURE__ */ jsxs("form", {
|
|
130
115
|
id: "authorizeForm",
|
|
131
116
|
"data-component": "form",
|
|
132
117
|
children: [
|
|
133
118
|
/* @__PURE__ */ jsx(FormAlert, {}),
|
|
134
119
|
/* @__PURE__ */ jsx("input", {
|
|
120
|
+
id: "auth-email",
|
|
135
121
|
"data-component": "input",
|
|
136
122
|
type: "email",
|
|
137
123
|
name: "email",
|
|
124
|
+
"aria-required": "true",
|
|
125
|
+
"aria-describedby": "auth-email-help",
|
|
126
|
+
autoComplete: "email",
|
|
138
127
|
required: true,
|
|
139
128
|
placeholder: copy.input_email
|
|
140
129
|
}),
|
|
@@ -171,37 +160,15 @@ const PasskeyUI = (options) => {
|
|
|
171
160
|
window.addEventListener("load", async () => {
|
|
172
161
|
const { startRegistration } = SimpleWebAuthnBrowser;
|
|
173
162
|
const registerForm = document.getElementById("registerForm");
|
|
163
|
+
const message = document.querySelector("[data-slot='message']");
|
|
174
164
|
const origin = window.location.origin;
|
|
175
165
|
const rpID = window.location.hostname;
|
|
176
166
|
|
|
177
|
-
const showMessage = (msg) => {
|
|
178
|
-
const messageEl = document.querySelector("[data-slot='message']");
|
|
179
|
-
if (messageEl) {
|
|
180
|
-
messageEl.innerHTML = msg;
|
|
181
|
-
} else {
|
|
182
|
-
// Create alert if it doesn't exist
|
|
183
|
-
const alertDiv = document.createElement("div");
|
|
184
|
-
alertDiv.setAttribute("data-component", "form-alert");
|
|
185
|
-
alertDiv.setAttribute("role", "alert");
|
|
186
|
-
alertDiv.setAttribute("aria-live", "polite");
|
|
187
|
-
alertDiv.setAttribute("data-color", "error");
|
|
188
|
-
alertDiv.innerHTML = '<span data-slot="message">' + msg + '</span>';
|
|
189
|
-
registerForm.insertBefore(alertDiv, registerForm.firstChild);
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
const clearMessage = () => {
|
|
194
|
-
const alertDiv = document.querySelector("[data-component='form-alert']");
|
|
195
|
-
if (alertDiv) {
|
|
196
|
-
alertDiv.remove();
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
|
|
200
167
|
// Start registration when the user clicks a button
|
|
201
168
|
const register = async (otherDevice = false) => {
|
|
202
169
|
const formData = new FormData(registerForm);
|
|
203
170
|
const email = formData.get("email");
|
|
204
|
-
|
|
171
|
+
message.textContent = "";
|
|
205
172
|
|
|
206
173
|
// GET registration options from the endpoint that calls
|
|
207
174
|
// @simplewebauthn/server -> generateRegistrationOptions()
|
|
@@ -218,7 +185,7 @@ const PasskeyUI = (options) => {
|
|
|
218
185
|
const optionsJSON = await resp.json();
|
|
219
186
|
|
|
220
187
|
if (optionsJSON.error) {
|
|
221
|
-
|
|
188
|
+
message.textContent = optionsJSON.error;
|
|
222
189
|
return;
|
|
223
190
|
}
|
|
224
191
|
|
|
@@ -227,7 +194,7 @@ const PasskeyUI = (options) => {
|
|
|
227
194
|
// Pass the options to the authenticator and wait for a response
|
|
228
195
|
attResp = await startRegistration({ optionsJSON });
|
|
229
196
|
} catch (error) {
|
|
230
|
-
|
|
197
|
+
message.textContent = error;
|
|
231
198
|
throw error;
|
|
232
199
|
}
|
|
233
200
|
|
|
@@ -263,14 +230,14 @@ const PasskeyUI = (options) => {
|
|
|
263
230
|
);
|
|
264
231
|
try {
|
|
265
232
|
const errorData = await verificationResp.json();
|
|
266
|
-
|
|
233
|
+
message.textContent = errorData.error;
|
|
267
234
|
} catch (error) {
|
|
268
|
-
|
|
235
|
+
message.textContent = "Something went wrong";
|
|
269
236
|
}
|
|
270
237
|
}
|
|
271
238
|
} catch (error) {
|
|
272
239
|
console.error(error);
|
|
273
|
-
|
|
240
|
+
message.textContent = "Something went wrong";
|
|
274
241
|
}
|
|
275
242
|
};
|
|
276
243
|
|
|
@@ -280,17 +247,27 @@ const PasskeyUI = (options) => {
|
|
|
280
247
|
});
|
|
281
248
|
});
|
|
282
249
|
` } }),
|
|
283
|
-
/* @__PURE__ */ jsx("h1", {
|
|
284
|
-
|
|
250
|
+
/* @__PURE__ */ jsx("h1", {
|
|
251
|
+
"data-component": "title",
|
|
252
|
+
children: copy.register_title
|
|
253
|
+
}),
|
|
254
|
+
/* @__PURE__ */ jsx("p", {
|
|
255
|
+
"data-component": "description",
|
|
256
|
+
children: copy.register_description
|
|
257
|
+
}),
|
|
285
258
|
/* @__PURE__ */ jsxs("form", {
|
|
286
259
|
id: "registerForm",
|
|
287
260
|
"data-component": "form",
|
|
288
261
|
children: [
|
|
289
262
|
/* @__PURE__ */ jsx(FormAlert, {}),
|
|
290
263
|
/* @__PURE__ */ jsx("input", {
|
|
264
|
+
id: "reg-email",
|
|
291
265
|
"data-component": "input",
|
|
292
266
|
type: "email",
|
|
293
267
|
name: "email",
|
|
268
|
+
"aria-required": "true",
|
|
269
|
+
"aria-describedby": "reg-email-help",
|
|
270
|
+
autoComplete: "email",
|
|
294
271
|
required: true,
|
|
295
272
|
placeholder: copy.input_email
|
|
296
273
|
}),
|