@mrgnw/anahtar 0.0.16 → 0.0.18
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.
|
@@ -204,22 +204,27 @@ function handlePasskeySkip() {
|
|
|
204
204
|
}}
|
|
205
205
|
class="anahtar-auth-form"
|
|
206
206
|
>
|
|
207
|
-
<input
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
207
|
+
<div class="anahtar-input-row">
|
|
208
|
+
<input
|
|
209
|
+
type="email"
|
|
210
|
+
bind:value={email}
|
|
211
|
+
required
|
|
212
|
+
autocomplete="username webauthn"
|
|
213
|
+
placeholder={m.emailPlaceholder}
|
|
214
|
+
class="anahtar-input"
|
|
215
|
+
/>
|
|
216
|
+
<button type="submit" disabled={loading} class="anahtar-submit-icon" aria-label={m.continue}>
|
|
217
|
+
{#if loading}
|
|
218
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="anahtar-spinner"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
|
|
219
|
+
{:else}
|
|
220
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
|
|
221
|
+
{/if}
|
|
222
|
+
</button>
|
|
223
|
+
</div>
|
|
215
224
|
|
|
216
225
|
{#if error}
|
|
217
226
|
<p class="anahtar-error">{error}</p>
|
|
218
227
|
{/if}
|
|
219
|
-
|
|
220
|
-
<button type="submit" disabled={loading} class="anahtar-button">
|
|
221
|
-
{loading ? '...' : m.continue}
|
|
222
|
-
</button>
|
|
223
228
|
</form>
|
|
224
229
|
{:else if step === 2}
|
|
225
230
|
<div class="anahtar-otp-step">
|
|
@@ -280,22 +285,64 @@ function handlePasskeySkip() {
|
|
|
280
285
|
.anahtar-auth-form {
|
|
281
286
|
display: flex;
|
|
282
287
|
flex-direction: column;
|
|
283
|
-
gap:
|
|
288
|
+
gap: 0.75rem;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.anahtar-input-row {
|
|
292
|
+
display: flex;
|
|
293
|
+
align-items: center;
|
|
294
|
+
border: 1px solid var(--anahtar-border, #d1d5db);
|
|
295
|
+
border-radius: 0.5rem;
|
|
296
|
+
overflow: hidden;
|
|
297
|
+
transition: box-shadow 0.15s;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.anahtar-input-row:focus-within {
|
|
301
|
+
box-shadow: 0 0 0 2px var(--anahtar-ring, #3b82f6);
|
|
284
302
|
}
|
|
285
303
|
|
|
286
304
|
.anahtar-input {
|
|
287
|
-
|
|
288
|
-
|
|
305
|
+
flex: 1;
|
|
306
|
+
min-width: 0;
|
|
307
|
+
padding: 0.625rem 0.75rem;
|
|
289
308
|
font-size: 0.875rem;
|
|
290
|
-
border:
|
|
291
|
-
border-radius: 0.375rem;
|
|
309
|
+
border: none;
|
|
292
310
|
background: var(--anahtar-bg, transparent);
|
|
293
311
|
color: var(--anahtar-fg, inherit);
|
|
294
312
|
}
|
|
295
313
|
|
|
296
314
|
.anahtar-input:focus {
|
|
297
315
|
outline: none;
|
|
298
|
-
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.anahtar-submit-icon {
|
|
319
|
+
display: flex;
|
|
320
|
+
align-items: center;
|
|
321
|
+
justify-content: center;
|
|
322
|
+
width: 2.5rem;
|
|
323
|
+
height: 2.5rem;
|
|
324
|
+
flex-shrink: 0;
|
|
325
|
+
background: var(--anahtar-primary, #3b82f6);
|
|
326
|
+
color: var(--anahtar-primary-fg, #fff);
|
|
327
|
+
border: none;
|
|
328
|
+
cursor: pointer;
|
|
329
|
+
transition: opacity 0.15s;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.anahtar-submit-icon:hover {
|
|
333
|
+
opacity: 0.85;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.anahtar-submit-icon:disabled {
|
|
337
|
+
opacity: 0.5;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
@keyframes anahtar-spin {
|
|
341
|
+
to { transform: rotate(360deg); }
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.anahtar-spinner {
|
|
345
|
+
animation: anahtar-spin 0.8s linear infinite;
|
|
299
346
|
}
|
|
300
347
|
|
|
301
348
|
.anahtar-button {
|
|
@@ -43,17 +43,26 @@ let otpStep = $state(false);
|
|
|
43
43
|
let otpDigits = $state<string[]>(['', '', '', '', '']);
|
|
44
44
|
let otpInputs = $state<HTMLInputElement[]>([]);
|
|
45
45
|
let showPasskeys = $state(false);
|
|
46
|
+
let isTouch = $state(false);
|
|
46
47
|
let hoveredKey = $state<string | null>(null);
|
|
47
48
|
let passkeyRefresh = $state(0);
|
|
48
49
|
let passkeyOnboarding = $state(false);
|
|
49
50
|
let conditionalAbort: AbortController | null = null;
|
|
50
51
|
|
|
51
52
|
const isAuthenticated = $derived(!!user);
|
|
53
|
+
|
|
54
|
+
function shortDate(ts?: number): string {
|
|
55
|
+
if (!ts) return '';
|
|
56
|
+
const d = new Date(ts);
|
|
57
|
+
const mon = d.toLocaleDateString(undefined, { month: 'short' });
|
|
58
|
+
return `${mon} ${d.getFullYear()}`;
|
|
59
|
+
}
|
|
52
60
|
const passkeyPromise = $derived(
|
|
53
61
|
isAuthenticated && getPasskeys && passkeyRefresh >= 0 ? getPasskeys() : null
|
|
54
62
|
);
|
|
55
63
|
|
|
56
64
|
onMount(() => {
|
|
65
|
+
isTouch = matchMedia('(pointer: coarse)').matches;
|
|
57
66
|
if (!isAuthenticated) tryConditionalWebAuthn();
|
|
58
67
|
return () => conditionalAbort?.abort();
|
|
59
68
|
});
|
|
@@ -390,7 +399,7 @@ async function removePasskey(id: string) {
|
|
|
390
399
|
{#await passkeyPromise then keys}
|
|
391
400
|
{#each keys as key}
|
|
392
401
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
393
|
-
|
|
402
|
+
<div
|
|
394
403
|
class="anahtar-pill-key-row"
|
|
395
404
|
onmouseenter={() => (hoveredKey = key.id)}
|
|
396
405
|
onmouseleave={() => (hoveredKey = null)}
|
|
@@ -399,7 +408,10 @@ async function removePasskey(id: string) {
|
|
|
399
408
|
<circle cx="7.5" cy="15.5" r="5.5"/><path d="m11.5 12 4-4"/><path d="m15 7 2 2"/><path d="m17.5 4.5 2 2"/>
|
|
400
409
|
</svg>
|
|
401
410
|
<span class="anahtar-pill-key-name">{key.name ?? 'Passkey'}</span>
|
|
402
|
-
{#if
|
|
411
|
+
{#if key.createdAt}
|
|
412
|
+
<span class="anahtar-pill-key-date">{shortDate(key.createdAt)}</span>
|
|
413
|
+
{/if}
|
|
414
|
+
{#if isTouch || hoveredKey === key.id}
|
|
403
415
|
<button
|
|
404
416
|
class="anahtar-pill-key-remove"
|
|
405
417
|
onclick={() => removePasskey(key.id)}
|
|
@@ -414,7 +426,7 @@ async function removePasskey(id: string) {
|
|
|
414
426
|
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
415
427
|
<line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/>
|
|
416
428
|
</svg>
|
|
417
|
-
Add
|
|
429
|
+
Add
|
|
418
430
|
</button>
|
|
419
431
|
</div>
|
|
420
432
|
{/if}
|
|
@@ -588,21 +600,21 @@ async function removePasskey(id: string) {
|
|
|
588
600
|
backdrop-filter: blur(8px);
|
|
589
601
|
border: 1px solid var(--anahtar-pill-border, rgba(0,0,0,0.06));
|
|
590
602
|
border-radius: 0.75rem;
|
|
591
|
-
padding: 0.
|
|
603
|
+
padding: 0.375rem 0.625rem;
|
|
592
604
|
box-shadow: var(--anahtar-pill-shadow, 0 2px 12px rgba(0,0,0,0.08));
|
|
593
605
|
display: flex;
|
|
594
606
|
flex-direction: column;
|
|
595
|
-
gap: 0.
|
|
596
|
-
min-width:
|
|
607
|
+
gap: 0.125rem;
|
|
608
|
+
min-width: 160px;
|
|
597
609
|
}
|
|
598
610
|
|
|
599
611
|
.anahtar-pill-key-row {
|
|
600
612
|
display: flex;
|
|
601
613
|
align-items: center;
|
|
602
|
-
gap: 0.
|
|
603
|
-
font-size: 0.
|
|
614
|
+
gap: 0.3rem;
|
|
615
|
+
font-size: 0.75rem;
|
|
604
616
|
color: var(--anahtar-pill-fg, #374151);
|
|
605
|
-
padding: 0.
|
|
617
|
+
padding: 0.15rem 0;
|
|
606
618
|
}
|
|
607
619
|
|
|
608
620
|
.anahtar-pill-key-name {
|
|
@@ -612,12 +624,18 @@ async function removePasskey(id: string) {
|
|
|
612
624
|
white-space: nowrap;
|
|
613
625
|
}
|
|
614
626
|
|
|
627
|
+
.anahtar-pill-key-date {
|
|
628
|
+
font-size: 0.6875rem;
|
|
629
|
+
color: var(--anahtar-pill-icon, #9ca3af);
|
|
630
|
+
white-space: nowrap;
|
|
631
|
+
}
|
|
632
|
+
|
|
615
633
|
.anahtar-pill-key-remove {
|
|
616
634
|
background: none;
|
|
617
635
|
border: none;
|
|
618
636
|
color: var(--anahtar-pill-icon, #9ca3af);
|
|
619
637
|
cursor: pointer;
|
|
620
|
-
font-size:
|
|
638
|
+
font-size: 0.875rem;
|
|
621
639
|
line-height: 1;
|
|
622
640
|
padding: 0 0.125rem;
|
|
623
641
|
transition: color 0.15s;
|
|
@@ -628,15 +646,14 @@ async function removePasskey(id: string) {
|
|
|
628
646
|
.anahtar-pill-key-add {
|
|
629
647
|
display: flex;
|
|
630
648
|
align-items: center;
|
|
631
|
-
gap: 0.
|
|
632
|
-
font-size: 0.
|
|
649
|
+
gap: 0.25rem;
|
|
650
|
+
font-size: 0.6875rem;
|
|
633
651
|
color: var(--anahtar-pill-icon, #6b7280);
|
|
634
652
|
background: none;
|
|
635
653
|
border: none;
|
|
636
654
|
cursor: pointer;
|
|
637
|
-
padding: 0.
|
|
655
|
+
padding: 0.15rem 0;
|
|
638
656
|
transition: color 0.15s;
|
|
639
|
-
margin-top: 0.125rem;
|
|
640
657
|
}
|
|
641
658
|
.anahtar-pill-key-add:hover:not(:disabled) { color: var(--anahtar-primary, #3730a3); }
|
|
642
659
|
.anahtar-pill-key-add:disabled { opacity: 0.4; cursor: not-allowed; }
|