@mrgnw/anahtar 0.0.17 → 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.
@@ -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
- <div
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 hoveredKey === key.id}
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 passkey
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.5rem 0.75rem;
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.25rem;
596
- min-width: 180px;
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.375rem;
603
- font-size: 0.8125rem;
614
+ gap: 0.3rem;
615
+ font-size: 0.75rem;
604
616
  color: var(--anahtar-pill-fg, #374151);
605
- padding: 0.2rem 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: 1rem;
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.3rem;
632
- font-size: 0.75rem;
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.2rem 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; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrgnw/anahtar",
3
- "version": "0.0.17",
3
+ "version": "0.0.18",
4
4
  "description": "Opinionated, reusable auth for SvelteKit. Email+OTP + passkeys.",
5
5
  "license": "MIT",
6
6
  "type": "module",