Skip to content

Commit c78fce0

Browse files
committed
Basic working password meter impl
1 parent a80d8d7 commit c78fce0

3 files changed

Lines changed: 29 additions & 9 deletions

File tree

src/lib/components/input/PasswordInput.svelte

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,29 @@
100100
$effect(() => {
101101
valid = validationResult?.valid ?? false;
102102
});
103+
104+
// Logic to hide the popup after 3 seconds of inactivity
105+
let showPopup = $state(false);
106+
let typingTimeout: ReturnType<typeof setTimeout> | null = null;
107+
$effect(() => {
108+
// If value is not empty, set isTyping to true, then start a timeout to set it to false after 3 seconds
109+
if (showStrengthMeter && value.length) {
110+
showPopup = true;
111+
if (typingTimeout) clearTimeout(typingTimeout);
112+
typingTimeout = setTimeout(() => {
113+
showPopup = false;
114+
}, 500);
115+
} else {
116+
// If value is empty, set isTyping to false
117+
showPopup = false;
118+
}
119+
});
103120
</script>
104121

122+
{#snippet popup()}
123+
<PasswordStrengthMeter password={value} />
124+
{/snippet}
125+
105126
<TextInput
106127
type={valueShown ? 'text' : 'password'}
107128
{label}
@@ -115,10 +136,6 @@
115136
class: 'cursor-pointer',
116137
onClick: () => (valueShown = !valueShown),
117138
}}
118-
>
119-
{#snippet popup()}
120-
{#if showStrengthMeter}
121-
<PasswordStrengthMeter password={value} />
122-
{/if}
123-
{/snippet}
124-
</TextInput>
139+
onblur={() => (showPopup = false)}
140+
popup={showPopup ? popup : undefined}
141+
/>

src/lib/components/input/TextInput.svelte

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import type { AnyComponent } from '$lib/types/AnyComponent';
55
import { GetValResColor, type ValidationResult } from '$lib/types/ValidationResult';
66
import type { Snippet } from 'svelte';
7-
import type { FullAutoFill } from 'svelte/elements';
7+
import type { FocusEventHandler, FullAutoFill } from 'svelte/elements';
88
import type { ButtonSettings } from './impl/ButtonSettings';
99
1010
interface Props {
@@ -17,6 +17,7 @@
1717
Icon?: AnyComponent;
1818
button?: ButtonSettings;
1919
popup?: Snippet;
20+
onblur?: FocusEventHandler<HTMLInputElement> | null;
2021
}
2122
2223
const id = $props.id();
@@ -32,6 +33,7 @@
3233
Icon,
3334
button,
3435
popup,
36+
onblur,
3537
}: Props = $props();
3638
</script>
3739

@@ -49,6 +51,7 @@
4951
{placeholder}
5052
{autocomplete}
5153
bind:value
54+
{onblur}
5255
aria-invalid={validationResult ? !validationResult.valid : undefined}
5356
aria-describedby={validationResult ? validationId : undefined}
5457
/>

src/lib/components/input/impl/PasswordStrengthMeter.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
let { percent, text, color } = $derived(getPasswordStrength(password));
1111
</script>
1212

13-
<div class="card w-72 p-4 shadow-xl">
13+
<div class="card w-72 p-4 shadow-xl" aria-hidden="true">
1414
<div class="flex flex-row items-center space-x-1">
1515
<p class="text-sm text-gray-500">Password strength:</p>
1616
<p class={`text-sm text-${color}`}>{text}</p>

0 commit comments

Comments
 (0)