@nqmcreative/ui 0.2.2 → 0.3.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/README.md +15 -15
- package/cli/index.mjs +81 -42
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/toast.svelte.d.ts +3 -0
- package/dist/core/trigger.d.ts +6 -0
- package/dist/core/trigger.js +13 -0
- package/dist/styles/matte/AccordionItem.svelte +5 -0
- package/dist/styles/matte/AccordionItem.svelte.d.ts +2 -0
- package/dist/styles/matte/Avatar.svelte +15 -0
- package/dist/styles/matte/Avatar.svelte.d.ts +3 -0
- package/dist/styles/matte/Badge.svelte +5 -0
- package/dist/styles/matte/Badge.svelte.d.ts +2 -0
- package/dist/styles/matte/Breadcrumb.svelte +11 -4
- package/dist/styles/matte/Breadcrumb.svelte.d.ts +3 -0
- package/dist/styles/matte/Button.svelte +62 -11
- package/dist/styles/matte/Button.svelte.d.ts +14 -2
- package/dist/styles/matte/Card.svelte +9 -4
- package/dist/styles/matte/Card.svelte.d.ts +2 -0
- package/dist/styles/matte/CheckboxGroup.svelte +6 -0
- package/dist/styles/matte/CheckboxGroup.svelte.d.ts +2 -0
- package/dist/styles/matte/Combobox.svelte +7 -2
- package/dist/styles/matte/Combobox.svelte.d.ts +3 -0
- package/dist/styles/matte/CommandPalette.svelte +38 -7
- package/dist/styles/matte/CommandPalette.svelte.d.ts +8 -0
- package/dist/styles/matte/DatePicker.svelte +2 -2
- package/dist/styles/matte/Drawer.svelte +7 -2
- package/dist/styles/matte/Drawer.svelte.d.ts +2 -0
- package/dist/styles/matte/Dropzone.svelte +1 -1
- package/dist/styles/matte/FeatureCard.svelte +1 -1
- package/dist/styles/matte/Footer.svelte +6 -2
- package/dist/styles/matte/Footer.svelte.d.ts +2 -0
- package/dist/styles/matte/Input.svelte +4 -4
- package/dist/styles/matte/Link.svelte +9 -0
- package/dist/styles/matte/Link.svelte.d.ts +4 -0
- package/dist/styles/matte/MenuItem.svelte +3 -2
- package/dist/styles/matte/Modal.svelte +8 -3
- package/dist/styles/matte/Modal.svelte.d.ts +2 -0
- package/dist/styles/matte/MultiSelect.svelte +7 -1
- package/dist/styles/matte/MultiSelect.svelte.d.ts +3 -0
- package/dist/styles/matte/Navbar.svelte +18 -4
- package/dist/styles/matte/Navbar.svelte.d.ts +2 -0
- package/dist/styles/matte/PricingCard.svelte +19 -11
- package/dist/styles/matte/PricingCard.svelte.d.ts +2 -0
- package/dist/styles/matte/RadioGroup.svelte +6 -0
- package/dist/styles/matte/RadioGroup.svelte.d.ts +2 -0
- package/dist/styles/matte/SegmentedControl.svelte +17 -3
- package/dist/styles/matte/SegmentedControl.svelte.d.ts +5 -0
- package/dist/styles/matte/Select.svelte +1 -1
- package/dist/styles/matte/Sidebar.svelte +76 -26
- package/dist/styles/matte/Sidebar.svelte.d.ts +15 -1
- package/dist/styles/matte/Stat.svelte +8 -1
- package/dist/styles/matte/Stat.svelte.d.ts +3 -0
- package/dist/styles/matte/StatsBand.svelte +1 -1
- package/dist/styles/matte/Steps.svelte +7 -0
- package/dist/styles/matte/Steps.svelte.d.ts +3 -0
- package/dist/styles/matte/Table.svelte +154 -98
- package/dist/styles/matte/Table.svelte.d.ts +12 -0
- package/dist/styles/matte/Tabs.svelte +5 -0
- package/dist/styles/matte/Tabs.svelte.d.ts +3 -0
- package/dist/styles/matte/Testimonial.svelte +2 -2
- package/dist/styles/matte/Textarea.svelte +1 -1
- package/dist/styles/matte/Toaster.svelte +3 -0
- package/dist/styles/matte/icon.d.ts +21 -0
- package/dist/styles/matte/icon.js +21 -0
- package/dist/styles/matte/index.d.ts +1 -3
- package/dist/styles/matte/index.js +0 -2
- package/dist/styles/paper/AccordionItem.svelte +5 -0
- package/dist/styles/paper/AccordionItem.svelte.d.ts +2 -0
- package/dist/styles/paper/Avatar.svelte +15 -0
- package/dist/styles/paper/Avatar.svelte.d.ts +3 -0
- package/dist/styles/paper/Badge.svelte +5 -0
- package/dist/styles/paper/Badge.svelte.d.ts +2 -0
- package/dist/styles/paper/Breadcrumb.svelte +8 -4
- package/dist/styles/paper/Breadcrumb.svelte.d.ts +3 -0
- package/dist/styles/paper/Button.svelte +58 -7
- package/dist/styles/paper/Button.svelte.d.ts +14 -2
- package/dist/styles/paper/Card.svelte +6 -1
- package/dist/styles/paper/Card.svelte.d.ts +2 -0
- package/dist/styles/paper/CheckboxGroup.svelte +6 -0
- package/dist/styles/paper/CheckboxGroup.svelte.d.ts +2 -0
- package/dist/styles/paper/Combobox.svelte +5 -0
- package/dist/styles/paper/Combobox.svelte.d.ts +3 -0
- package/dist/styles/paper/CommandPalette.svelte +31 -2
- package/dist/styles/paper/CommandPalette.svelte.d.ts +8 -0
- package/dist/styles/paper/Drawer.svelte +5 -0
- package/dist/styles/paper/Drawer.svelte.d.ts +2 -0
- package/dist/styles/paper/Footer.svelte +6 -2
- package/dist/styles/paper/Footer.svelte.d.ts +2 -0
- package/dist/styles/paper/Link.svelte +9 -0
- package/dist/styles/paper/Link.svelte.d.ts +4 -0
- package/dist/styles/paper/MenuItem.svelte +2 -1
- package/dist/styles/paper/Modal.svelte +14 -1
- package/dist/styles/paper/Modal.svelte.d.ts +2 -0
- package/dist/styles/paper/MultiSelect.svelte +7 -1
- package/dist/styles/paper/MultiSelect.svelte.d.ts +3 -0
- package/dist/styles/paper/Navbar.svelte +18 -4
- package/dist/styles/paper/Navbar.svelte.d.ts +2 -0
- package/dist/styles/paper/PricingCard.svelte +23 -15
- package/dist/styles/paper/PricingCard.svelte.d.ts +2 -0
- package/dist/styles/paper/RadioGroup.svelte +6 -0
- package/dist/styles/paper/RadioGroup.svelte.d.ts +2 -0
- package/dist/styles/paper/SegmentedControl.svelte +16 -2
- package/dist/styles/paper/SegmentedControl.svelte.d.ts +5 -0
- package/dist/styles/paper/Sidebar.svelte +76 -26
- package/dist/styles/paper/Sidebar.svelte.d.ts +15 -1
- package/dist/styles/paper/Stat.svelte +8 -1
- package/dist/styles/paper/Stat.svelte.d.ts +3 -0
- package/dist/styles/paper/Steps.svelte +7 -0
- package/dist/styles/paper/Steps.svelte.d.ts +3 -0
- package/dist/styles/paper/Table.svelte +153 -97
- package/dist/styles/paper/Table.svelte.d.ts +12 -0
- package/dist/styles/paper/Tabs.svelte +5 -0
- package/dist/styles/paper/Tabs.svelte.d.ts +3 -0
- package/dist/styles/paper/Toaster.svelte +3 -0
- package/dist/styles/paper/fonts.css +34 -7
- package/dist/styles/paper/icon.d.ts +21 -0
- package/dist/styles/paper/icon.js +21 -0
- package/dist/styles/paper/index.d.ts +1 -3
- package/dist/styles/paper/index.js +0 -2
- package/dist/styles/paper/theme.css +11 -8
- package/dist/styles/sprout/AccordionItem.svelte +5 -0
- package/dist/styles/sprout/AccordionItem.svelte.d.ts +2 -0
- package/dist/styles/sprout/Avatar.svelte +15 -0
- package/dist/styles/sprout/Avatar.svelte.d.ts +3 -0
- package/dist/styles/sprout/Badge.svelte +5 -0
- package/dist/styles/sprout/Badge.svelte.d.ts +2 -0
- package/dist/styles/sprout/Breadcrumb.svelte +8 -4
- package/dist/styles/sprout/Breadcrumb.svelte.d.ts +3 -0
- package/dist/styles/sprout/Button.svelte +58 -7
- package/dist/styles/sprout/Button.svelte.d.ts +14 -2
- package/dist/styles/sprout/Card.svelte +6 -1
- package/dist/styles/sprout/Card.svelte.d.ts +2 -0
- package/dist/styles/sprout/CheckboxGroup.svelte +6 -0
- package/dist/styles/sprout/CheckboxGroup.svelte.d.ts +2 -0
- package/dist/styles/sprout/Combobox.svelte +5 -0
- package/dist/styles/sprout/Combobox.svelte.d.ts +3 -0
- package/dist/styles/sprout/CommandPalette.svelte +31 -2
- package/dist/styles/sprout/CommandPalette.svelte.d.ts +8 -0
- package/dist/styles/sprout/Drawer.svelte +5 -0
- package/dist/styles/sprout/Drawer.svelte.d.ts +2 -0
- package/dist/styles/sprout/Footer.svelte +6 -2
- package/dist/styles/sprout/Footer.svelte.d.ts +2 -0
- package/dist/styles/sprout/Link.svelte +9 -0
- package/dist/styles/sprout/Link.svelte.d.ts +4 -0
- package/dist/styles/sprout/MenuItem.svelte +2 -1
- package/dist/styles/sprout/Modal.svelte +14 -1
- package/dist/styles/sprout/Modal.svelte.d.ts +2 -0
- package/dist/styles/sprout/MultiSelect.svelte +7 -1
- package/dist/styles/sprout/MultiSelect.svelte.d.ts +3 -0
- package/dist/styles/sprout/Navbar.svelte +18 -4
- package/dist/styles/sprout/Navbar.svelte.d.ts +2 -0
- package/dist/styles/sprout/PricingCard.svelte +23 -15
- package/dist/styles/sprout/PricingCard.svelte.d.ts +2 -0
- package/dist/styles/sprout/RadioGroup.svelte +6 -0
- package/dist/styles/sprout/RadioGroup.svelte.d.ts +2 -0
- package/dist/styles/sprout/SegmentedControl.svelte +16 -2
- package/dist/styles/sprout/SegmentedControl.svelte.d.ts +5 -0
- package/dist/styles/sprout/Sidebar.svelte +76 -26
- package/dist/styles/sprout/Sidebar.svelte.d.ts +15 -1
- package/dist/styles/sprout/Stat.svelte +8 -1
- package/dist/styles/sprout/Stat.svelte.d.ts +3 -0
- package/dist/styles/sprout/Steps.svelte +7 -0
- package/dist/styles/sprout/Steps.svelte.d.ts +3 -0
- package/dist/styles/sprout/Table.svelte +153 -97
- package/dist/styles/sprout/Table.svelte.d.ts +12 -0
- package/dist/styles/sprout/Tabs.svelte +5 -0
- package/dist/styles/sprout/Tabs.svelte.d.ts +3 -0
- package/dist/styles/sprout/Toaster.svelte +3 -0
- package/dist/styles/sprout/fonts.css +7 -8
- package/dist/styles/sprout/icon.d.ts +21 -0
- package/dist/styles/sprout/icon.js +21 -0
- package/dist/styles/sprout/index.d.ts +1 -3
- package/dist/styles/sprout/index.js +0 -2
- package/dist/styles/sprout/theme.css +6 -6
- package/package.json +2 -26
- package/registry.json +3 -36
- package/dist/styles/matte/NumberInput.svelte +0 -96
- package/dist/styles/matte/NumberInput.svelte.d.ts +0 -15
- package/dist/styles/matte/PasswordInput.svelte +0 -95
- package/dist/styles/matte/PasswordInput.svelte.d.ts +0 -12
- package/dist/styles/paper/NumberInput.svelte +0 -96
- package/dist/styles/paper/NumberInput.svelte.d.ts +0 -15
- package/dist/styles/paper/PasswordInput.svelte +0 -100
- package/dist/styles/paper/PasswordInput.svelte.d.ts +0 -12
- package/dist/styles/sprout/NumberInput.svelte +0 -97
- package/dist/styles/sprout/NumberInput.svelte.d.ts +0 -15
- package/dist/styles/sprout/PasswordInput.svelte +0 -101
- package/dist/styles/sprout/PasswordInput.svelte.d.ts +0 -12
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
|
|
4
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
|
-
import { clampToStep } from '../../core/number.js';
|
|
6
|
-
|
|
7
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
|
|
8
|
-
value?: number;
|
|
9
|
-
min?: number;
|
|
10
|
-
max?: number;
|
|
11
|
-
step?: number;
|
|
12
|
-
tone?: Tone;
|
|
13
|
-
invalid?: boolean;
|
|
14
|
-
/** Short unit rendered inside the field, e.g. `'px'` or `'%'`. */
|
|
15
|
-
unit?: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
let {
|
|
19
|
-
value = $bindable(0),
|
|
20
|
-
min = -Infinity,
|
|
21
|
-
max = Infinity,
|
|
22
|
-
step = 1,
|
|
23
|
-
tone = 'brand',
|
|
24
|
-
invalid = false,
|
|
25
|
-
unit,
|
|
26
|
-
disabled = false,
|
|
27
|
-
class: className = '',
|
|
28
|
-
...rest
|
|
29
|
-
}: Props = $props();
|
|
30
|
-
|
|
31
|
-
const t = useLocale();
|
|
32
|
-
|
|
33
|
-
const clamp = (next: number) => clampToStep(next, min, max, step);
|
|
34
|
-
|
|
35
|
-
function nudge(direction: 1 | -1) {
|
|
36
|
-
value = clamp(value + direction * step);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function onKeydown(event: KeyboardEvent) {
|
|
40
|
-
if (event.key === 'ArrowUp') {
|
|
41
|
-
event.preventDefault();
|
|
42
|
-
nudge(1);
|
|
43
|
-
} else if (event.key === 'ArrowDown') {
|
|
44
|
-
event.preventDefault();
|
|
45
|
-
nudge(-1);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const stepper =
|
|
50
|
-
'flex size-8 shrink-0 items-center justify-center text-text-secondary transition-colors duration-150 hover:bg-bg-inset hover:text-text disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current';
|
|
51
|
-
</script>
|
|
52
|
-
|
|
53
|
-
<span
|
|
54
|
-
class="inline-flex w-full items-center border bg-bg pr-1 pl-4 transition-colors duration-150 ease-brand-out
|
|
55
|
-
{invalid ? 'border-danger' : `border-hairline ${toneFocusWithinBorder[tone]}`}
|
|
56
|
-
{disabled ? 'pointer-events-none opacity-50' : ''} {className}"
|
|
57
|
-
>
|
|
58
|
-
<input
|
|
59
|
-
type="number"
|
|
60
|
-
{min}
|
|
61
|
-
{max}
|
|
62
|
-
{step}
|
|
63
|
-
{disabled}
|
|
64
|
-
{value}
|
|
65
|
-
oninput={(event) => (value = clamp(event.currentTarget.valueAsNumber))}
|
|
66
|
-
onkeydown={onKeydown}
|
|
67
|
-
aria-invalid={invalid ? 'true' : undefined}
|
|
68
|
-
class="h-11 w-full min-w-0 [appearance:textfield] bg-transparent font-sans text-[15px] text-text tabular-nums placeholder:text-text-muted focus:outline-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
|
|
69
|
-
{...rest}
|
|
70
|
-
/>
|
|
71
|
-
{#if unit}
|
|
72
|
-
<span class="shrink-0 px-2 font-mono text-xs text-text-muted">{unit}</span>
|
|
73
|
-
{/if}
|
|
74
|
-
<button
|
|
75
|
-
type="button"
|
|
76
|
-
class={stepper}
|
|
77
|
-
onclick={() => nudge(-1)}
|
|
78
|
-
disabled={disabled || value <= min}
|
|
79
|
-
aria-label={t.current.decrease}
|
|
80
|
-
>
|
|
81
|
-
<svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
|
|
82
|
-
<path d="M2.5 7h9" stroke="currentColor" stroke-width="1.5" />
|
|
83
|
-
</svg>
|
|
84
|
-
</button>
|
|
85
|
-
<button
|
|
86
|
-
type="button"
|
|
87
|
-
class={stepper}
|
|
88
|
-
onclick={() => nudge(1)}
|
|
89
|
-
disabled={disabled || value >= max}
|
|
90
|
-
aria-label={t.current.increase}
|
|
91
|
-
>
|
|
92
|
-
<svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
|
|
93
|
-
<path d="M7 2.5v9M2.5 7h9" stroke="currentColor" stroke-width="1.5" />
|
|
94
|
-
</svg>
|
|
95
|
-
</button>
|
|
96
|
-
</span>
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Tone } from '../../core/tones.js';
|
|
3
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
|
|
4
|
-
value?: number;
|
|
5
|
-
min?: number;
|
|
6
|
-
max?: number;
|
|
7
|
-
step?: number;
|
|
8
|
-
tone?: Tone;
|
|
9
|
-
invalid?: boolean;
|
|
10
|
-
/** Short unit rendered inside the field, e.g. `'px'` or `'%'`. */
|
|
11
|
-
unit?: string;
|
|
12
|
-
}
|
|
13
|
-
declare const NumberInput: import("svelte").Component<Props, {}, "value">;
|
|
14
|
-
type NumberInput = ReturnType<typeof NumberInput>;
|
|
15
|
-
export default NumberInput;
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
|
|
4
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
|
-
import { passwordScore } from '../../core/password.js';
|
|
6
|
-
|
|
7
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
|
|
8
|
-
value?: string;
|
|
9
|
-
tone?: Tone;
|
|
10
|
-
invalid?: boolean;
|
|
11
|
-
/** Draws a four-segment strength meter under the field. */
|
|
12
|
-
strength?: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let {
|
|
16
|
-
value = $bindable(''),
|
|
17
|
-
tone = 'brand',
|
|
18
|
-
invalid = false,
|
|
19
|
-
strength = false,
|
|
20
|
-
disabled = false,
|
|
21
|
-
class: className = '',
|
|
22
|
-
...rest
|
|
23
|
-
}: Props = $props();
|
|
24
|
-
|
|
25
|
-
const t = useLocale();
|
|
26
|
-
|
|
27
|
-
let visible = $state(false);
|
|
28
|
-
|
|
29
|
-
const score = $derived(passwordScore(value));
|
|
30
|
-
|
|
31
|
-
const bars = ['bg-danger', 'bg-danger', 'bg-warning', 'bg-info', 'bg-success'];
|
|
32
|
-
const texts = ['text-danger', 'text-danger', 'text-warning', 'text-info', 'text-success'];
|
|
33
|
-
</script>
|
|
34
|
-
|
|
35
|
-
<div class="flex w-full flex-col gap-2">
|
|
36
|
-
<span
|
|
37
|
-
class="inline-flex w-full items-center gap-2 border bg-bg pr-2 pl-4 transition-colors duration-150 ease-brand-out
|
|
38
|
-
{invalid ? 'border-danger' : `border-hairline ${toneFocusWithinBorder[tone]}`}
|
|
39
|
-
{disabled ? 'pointer-events-none opacity-50' : ''} {className}"
|
|
40
|
-
>
|
|
41
|
-
<input
|
|
42
|
-
bind:value
|
|
43
|
-
{disabled}
|
|
44
|
-
type={visible ? 'text' : 'password'}
|
|
45
|
-
aria-invalid={invalid ? 'true' : undefined}
|
|
46
|
-
class="h-11 w-full min-w-0 bg-transparent font-sans text-[15px] text-text placeholder:text-text-muted focus:outline-none"
|
|
47
|
-
{...rest}
|
|
48
|
-
/>
|
|
49
|
-
<button
|
|
50
|
-
type="button"
|
|
51
|
-
onclick={() => (visible = !visible)}
|
|
52
|
-
aria-label={visible ? t.current.hidePassword : t.current.showPassword}
|
|
53
|
-
aria-pressed={visible}
|
|
54
|
-
class="shrink-0 p-2 text-text-muted transition-colors duration-150 hover:text-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current"
|
|
55
|
-
>
|
|
56
|
-
{#if visible}
|
|
57
|
-
<svg class="size-4" viewBox="0 0 20 20" fill="none" aria-hidden="true">
|
|
58
|
-
<path
|
|
59
|
-
d="M2.5 10S5.5 4.5 10 4.5 17.5 10 17.5 10 14.5 15.5 10 15.5 2.5 10 2.5 10Z"
|
|
60
|
-
stroke="currentColor"
|
|
61
|
-
stroke-width="1.4"
|
|
62
|
-
/>
|
|
63
|
-
<circle cx="10" cy="10" r="2.4" stroke="currentColor" stroke-width="1.4" />
|
|
64
|
-
<path d="m3.5 16.5 13-13" stroke="currentColor" stroke-width="1.4" />
|
|
65
|
-
</svg>
|
|
66
|
-
{:else}
|
|
67
|
-
<svg class="size-4" viewBox="0 0 20 20" fill="none" aria-hidden="true">
|
|
68
|
-
<path
|
|
69
|
-
d="M2.5 10S5.5 4.5 10 4.5 17.5 10 17.5 10 14.5 15.5 10 15.5 2.5 10 2.5 10Z"
|
|
70
|
-
stroke="currentColor"
|
|
71
|
-
stroke-width="1.4"
|
|
72
|
-
/>
|
|
73
|
-
<circle cx="10" cy="10" r="2.4" stroke="currentColor" stroke-width="1.4" />
|
|
74
|
-
</svg>
|
|
75
|
-
{/if}
|
|
76
|
-
</button>
|
|
77
|
-
</span>
|
|
78
|
-
|
|
79
|
-
{#if strength}
|
|
80
|
-
<div class="flex items-center gap-3">
|
|
81
|
-
<div class="flex flex-1 gap-1" aria-hidden="true">
|
|
82
|
-
{#each [0, 1, 2, 3] as segment (segment)}
|
|
83
|
-
<span
|
|
84
|
-
class="h-1 flex-1 transition-colors duration-200 {segment < score
|
|
85
|
-
? bars[score]
|
|
86
|
-
: 'bg-bg-inset'}"
|
|
87
|
-
></span>
|
|
88
|
-
{/each}
|
|
89
|
-
</div>
|
|
90
|
-
<span class="font-mono text-xs {value ? texts[score] : 'text-text-muted'}">
|
|
91
|
-
{value ? t.current.passwordStrength[score] : '—'}
|
|
92
|
-
</span>
|
|
93
|
-
</div>
|
|
94
|
-
{/if}
|
|
95
|
-
</div>
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Tone } from '../../core/tones.js';
|
|
3
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
|
|
4
|
-
value?: string;
|
|
5
|
-
tone?: Tone;
|
|
6
|
-
invalid?: boolean;
|
|
7
|
-
/** Draws a four-segment strength meter under the field. */
|
|
8
|
-
strength?: boolean;
|
|
9
|
-
}
|
|
10
|
-
declare const PasswordInput: import("svelte").Component<Props, {}, "value">;
|
|
11
|
-
type PasswordInput = ReturnType<typeof PasswordInput>;
|
|
12
|
-
export default PasswordInput;
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
|
|
4
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
|
-
import { clampToStep } from '../../core/number.js';
|
|
6
|
-
|
|
7
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
|
|
8
|
-
value?: number;
|
|
9
|
-
min?: number;
|
|
10
|
-
max?: number;
|
|
11
|
-
step?: number;
|
|
12
|
-
tone?: Tone;
|
|
13
|
-
invalid?: boolean;
|
|
14
|
-
/** Short unit rendered inside the field, e.g. `'px'` or `'%'`. */
|
|
15
|
-
unit?: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
let {
|
|
19
|
-
value = $bindable(0),
|
|
20
|
-
min = -Infinity,
|
|
21
|
-
max = Infinity,
|
|
22
|
-
step = 1,
|
|
23
|
-
tone = 'brand',
|
|
24
|
-
invalid = false,
|
|
25
|
-
unit,
|
|
26
|
-
disabled = false,
|
|
27
|
-
class: className = '',
|
|
28
|
-
...rest
|
|
29
|
-
}: Props = $props();
|
|
30
|
-
|
|
31
|
-
const t = useLocale();
|
|
32
|
-
|
|
33
|
-
const clamp = (next: number) => clampToStep(next, min, max, step);
|
|
34
|
-
|
|
35
|
-
function nudge(direction: 1 | -1) {
|
|
36
|
-
value = clamp(value + direction * step);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function onKeydown(event: KeyboardEvent) {
|
|
40
|
-
if (event.key === 'ArrowUp') {
|
|
41
|
-
event.preventDefault();
|
|
42
|
-
nudge(1);
|
|
43
|
-
} else if (event.key === 'ArrowDown') {
|
|
44
|
-
event.preventDefault();
|
|
45
|
-
nudge(-1);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const stepper =
|
|
50
|
-
'flex size-7 shrink-0 items-center justify-center rounded text-text-secondary transition-colors duration-150 hover:bg-bg-inset hover:text-text disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current';
|
|
51
|
-
</script>
|
|
52
|
-
|
|
53
|
-
<span
|
|
54
|
-
class="inline-flex w-full items-center rounded-md border bg-bg pr-1 pl-3 shadow-xs transition-colors duration-150 ease-brand-out
|
|
55
|
-
{invalid ? 'border-danger' : `border-hairline-strong ${toneFocusWithinBorder[tone]}`}
|
|
56
|
-
{disabled ? 'pointer-events-none opacity-50' : ''} {className}"
|
|
57
|
-
>
|
|
58
|
-
<input
|
|
59
|
-
type="number"
|
|
60
|
-
{min}
|
|
61
|
-
{max}
|
|
62
|
-
{step}
|
|
63
|
-
{disabled}
|
|
64
|
-
{value}
|
|
65
|
-
oninput={(event) => (value = clamp(event.currentTarget.valueAsNumber))}
|
|
66
|
-
onkeydown={onKeydown}
|
|
67
|
-
aria-invalid={invalid ? 'true' : undefined}
|
|
68
|
-
class="h-10 w-full min-w-0 [appearance:textfield] bg-transparent font-sans text-sm text-text tabular-nums placeholder:text-text-muted focus:outline-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
|
|
69
|
-
{...rest}
|
|
70
|
-
/>
|
|
71
|
-
{#if unit}
|
|
72
|
-
<span class="shrink-0 px-1.5 text-xs text-text-muted">{unit}</span>
|
|
73
|
-
{/if}
|
|
74
|
-
<button
|
|
75
|
-
type="button"
|
|
76
|
-
class={stepper}
|
|
77
|
-
onclick={() => nudge(-1)}
|
|
78
|
-
disabled={disabled || value <= min}
|
|
79
|
-
aria-label={t.current.decrease}
|
|
80
|
-
>
|
|
81
|
-
<svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
|
|
82
|
-
<path d="M2.5 7h9" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" />
|
|
83
|
-
</svg>
|
|
84
|
-
</button>
|
|
85
|
-
<button
|
|
86
|
-
type="button"
|
|
87
|
-
class={stepper}
|
|
88
|
-
onclick={() => nudge(1)}
|
|
89
|
-
disabled={disabled || value >= max}
|
|
90
|
-
aria-label={t.current.increase}
|
|
91
|
-
>
|
|
92
|
-
<svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
|
|
93
|
-
<path d="M7 2.5v9M2.5 7h9" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" />
|
|
94
|
-
</svg>
|
|
95
|
-
</button>
|
|
96
|
-
</span>
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Tone } from '../../core/tones.js';
|
|
3
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
|
|
4
|
-
value?: number;
|
|
5
|
-
min?: number;
|
|
6
|
-
max?: number;
|
|
7
|
-
step?: number;
|
|
8
|
-
tone?: Tone;
|
|
9
|
-
invalid?: boolean;
|
|
10
|
-
/** Short unit rendered inside the field, e.g. `'px'` or `'%'`. */
|
|
11
|
-
unit?: string;
|
|
12
|
-
}
|
|
13
|
-
declare const NumberInput: import("svelte").Component<Props, {}, "value">;
|
|
14
|
-
type NumberInput = ReturnType<typeof NumberInput>;
|
|
15
|
-
export default NumberInput;
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
|
|
4
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
|
-
import { passwordScore } from '../../core/password.js';
|
|
6
|
-
|
|
7
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
|
|
8
|
-
value?: string;
|
|
9
|
-
tone?: Tone;
|
|
10
|
-
invalid?: boolean;
|
|
11
|
-
/** Draws a four-segment strength meter under the field. */
|
|
12
|
-
strength?: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let {
|
|
16
|
-
value = $bindable(''),
|
|
17
|
-
tone = 'brand',
|
|
18
|
-
invalid = false,
|
|
19
|
-
strength = false,
|
|
20
|
-
disabled = false,
|
|
21
|
-
class: className = '',
|
|
22
|
-
...rest
|
|
23
|
-
}: Props = $props();
|
|
24
|
-
|
|
25
|
-
const t = useLocale();
|
|
26
|
-
|
|
27
|
-
let visible = $state(false);
|
|
28
|
-
|
|
29
|
-
const score = $derived(passwordScore(value));
|
|
30
|
-
|
|
31
|
-
const bars = ['bg-danger', 'bg-danger', 'bg-warning', 'bg-info', 'bg-success'];
|
|
32
|
-
const texts = ['text-danger', 'text-danger', 'text-warning', 'text-info', 'text-success'];
|
|
33
|
-
</script>
|
|
34
|
-
|
|
35
|
-
<div class="flex w-full flex-col gap-2">
|
|
36
|
-
<span
|
|
37
|
-
class="inline-flex w-full items-center gap-2 rounded-md border bg-bg pr-1 pl-3 shadow-xs transition-colors duration-150 ease-brand-out
|
|
38
|
-
{invalid ? 'border-danger' : `border-hairline-strong ${toneFocusWithinBorder[tone]}`}
|
|
39
|
-
{disabled ? 'pointer-events-none opacity-50' : ''} {className}"
|
|
40
|
-
>
|
|
41
|
-
<input
|
|
42
|
-
bind:value
|
|
43
|
-
{disabled}
|
|
44
|
-
type={visible ? 'text' : 'password'}
|
|
45
|
-
aria-invalid={invalid ? 'true' : undefined}
|
|
46
|
-
class="h-10 w-full min-w-0 bg-transparent font-sans text-sm text-text placeholder:text-text-muted focus:outline-none"
|
|
47
|
-
{...rest}
|
|
48
|
-
/>
|
|
49
|
-
<button
|
|
50
|
-
type="button"
|
|
51
|
-
onclick={() => (visible = !visible)}
|
|
52
|
-
aria-label={visible ? t.current.hidePassword : t.current.showPassword}
|
|
53
|
-
aria-pressed={visible}
|
|
54
|
-
class="shrink-0 rounded p-1.5 text-text-muted transition-colors duration-150 hover:bg-bg-inset hover:text-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current"
|
|
55
|
-
>
|
|
56
|
-
{#if visible}
|
|
57
|
-
<svg class="size-4" viewBox="0 0 20 20" fill="none" aria-hidden="true">
|
|
58
|
-
<path
|
|
59
|
-
d="M2.5 10S5.5 4.5 10 4.5 17.5 10 17.5 10 14.5 15.5 10 15.5 2.5 10 2.5 10Z"
|
|
60
|
-
stroke="currentColor"
|
|
61
|
-
stroke-width="1.4"
|
|
62
|
-
/>
|
|
63
|
-
<circle cx="10" cy="10" r="2.4" stroke="currentColor" stroke-width="1.4" />
|
|
64
|
-
<path
|
|
65
|
-
d="m3.5 16.5 13-13"
|
|
66
|
-
stroke="currentColor"
|
|
67
|
-
stroke-width="1.4"
|
|
68
|
-
stroke-linecap="round"
|
|
69
|
-
/>
|
|
70
|
-
</svg>
|
|
71
|
-
{:else}
|
|
72
|
-
<svg class="size-4" viewBox="0 0 20 20" fill="none" aria-hidden="true">
|
|
73
|
-
<path
|
|
74
|
-
d="M2.5 10S5.5 4.5 10 4.5 17.5 10 17.5 10 14.5 15.5 10 15.5 2.5 10 2.5 10Z"
|
|
75
|
-
stroke="currentColor"
|
|
76
|
-
stroke-width="1.4"
|
|
77
|
-
/>
|
|
78
|
-
<circle cx="10" cy="10" r="2.4" stroke="currentColor" stroke-width="1.4" />
|
|
79
|
-
</svg>
|
|
80
|
-
{/if}
|
|
81
|
-
</button>
|
|
82
|
-
</span>
|
|
83
|
-
|
|
84
|
-
{#if strength}
|
|
85
|
-
<div class="flex items-center gap-3">
|
|
86
|
-
<div class="flex flex-1 gap-1" aria-hidden="true">
|
|
87
|
-
{#each [0, 1, 2, 3] as segment (segment)}
|
|
88
|
-
<span
|
|
89
|
-
class="h-1 flex-1 rounded-full transition-colors duration-200 {segment < score
|
|
90
|
-
? bars[score]
|
|
91
|
-
: 'bg-bg-inset'}"
|
|
92
|
-
></span>
|
|
93
|
-
{/each}
|
|
94
|
-
</div>
|
|
95
|
-
<span class="text-xs font-medium {value ? texts[score] : 'text-text-muted'}">
|
|
96
|
-
{value ? t.current.passwordStrength[score] : '—'}
|
|
97
|
-
</span>
|
|
98
|
-
</div>
|
|
99
|
-
{/if}
|
|
100
|
-
</div>
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Tone } from '../../core/tones.js';
|
|
3
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
|
|
4
|
-
value?: string;
|
|
5
|
-
tone?: Tone;
|
|
6
|
-
invalid?: boolean;
|
|
7
|
-
/** Draws a four-segment strength meter under the field. */
|
|
8
|
-
strength?: boolean;
|
|
9
|
-
}
|
|
10
|
-
declare const PasswordInput: import("svelte").Component<Props, {}, "value">;
|
|
11
|
-
type PasswordInput = ReturnType<typeof PasswordInput>;
|
|
12
|
-
export default PasswordInput;
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
|
|
4
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
|
-
import { clampToStep } from '../../core/number.js';
|
|
6
|
-
import { edge } from './lift.js';
|
|
7
|
-
|
|
8
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
|
|
9
|
-
value?: number;
|
|
10
|
-
min?: number;
|
|
11
|
-
max?: number;
|
|
12
|
-
step?: number;
|
|
13
|
-
tone?: Tone;
|
|
14
|
-
invalid?: boolean;
|
|
15
|
-
/** Short unit rendered inside the field, e.g. `'px'` or `'%'`. */
|
|
16
|
-
unit?: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
let {
|
|
20
|
-
value = $bindable(0),
|
|
21
|
-
min = -Infinity,
|
|
22
|
-
max = Infinity,
|
|
23
|
-
step = 1,
|
|
24
|
-
tone = 'brand',
|
|
25
|
-
invalid = false,
|
|
26
|
-
unit,
|
|
27
|
-
disabled = false,
|
|
28
|
-
class: className = '',
|
|
29
|
-
...rest
|
|
30
|
-
}: Props = $props();
|
|
31
|
-
|
|
32
|
-
const t = useLocale();
|
|
33
|
-
|
|
34
|
-
const clamp = (next: number) => clampToStep(next, min, max, step);
|
|
35
|
-
|
|
36
|
-
function nudge(direction: 1 | -1) {
|
|
37
|
-
value = clamp(value + direction * step);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function onKeydown(event: KeyboardEvent) {
|
|
41
|
-
if (event.key === 'ArrowUp') {
|
|
42
|
-
event.preventDefault();
|
|
43
|
-
nudge(1);
|
|
44
|
-
} else if (event.key === 'ArrowDown') {
|
|
45
|
-
event.preventDefault();
|
|
46
|
-
nudge(-1);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const stepper =
|
|
51
|
-
'flex size-7 shrink-0 items-center justify-center rounded text-text-secondary transition-colors duration-150 hover:bg-bg-inset hover:text-text disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current';
|
|
52
|
-
</script>
|
|
53
|
-
|
|
54
|
-
<span
|
|
55
|
-
class="inline-flex w-full items-center rounded-xl border bg-bg pr-1 pl-3 {edge} transition-colors duration-150 ease-brand-out
|
|
56
|
-
{invalid ? 'border-danger' : `border-hairline-strong ${toneFocusWithinBorder[tone]}`}
|
|
57
|
-
{disabled ? 'pointer-events-none opacity-50' : ''} {className}"
|
|
58
|
-
>
|
|
59
|
-
<input
|
|
60
|
-
type="number"
|
|
61
|
-
{min}
|
|
62
|
-
{max}
|
|
63
|
-
{step}
|
|
64
|
-
{disabled}
|
|
65
|
-
{value}
|
|
66
|
-
oninput={(event) => (value = clamp(event.currentTarget.valueAsNumber))}
|
|
67
|
-
onkeydown={onKeydown}
|
|
68
|
-
aria-invalid={invalid ? 'true' : undefined}
|
|
69
|
-
class="h-10 w-full min-w-0 [appearance:textfield] bg-transparent font-sans text-sm text-text tabular-nums placeholder:text-text-muted focus:outline-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
|
|
70
|
-
{...rest}
|
|
71
|
-
/>
|
|
72
|
-
{#if unit}
|
|
73
|
-
<span class="shrink-0 px-1.5 text-xs text-text-muted">{unit}</span>
|
|
74
|
-
{/if}
|
|
75
|
-
<button
|
|
76
|
-
type="button"
|
|
77
|
-
class={stepper}
|
|
78
|
-
onclick={() => nudge(-1)}
|
|
79
|
-
disabled={disabled || value <= min}
|
|
80
|
-
aria-label={t.current.decrease}
|
|
81
|
-
>
|
|
82
|
-
<svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
|
|
83
|
-
<path d="M2.5 7h9" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" />
|
|
84
|
-
</svg>
|
|
85
|
-
</button>
|
|
86
|
-
<button
|
|
87
|
-
type="button"
|
|
88
|
-
class={stepper}
|
|
89
|
-
onclick={() => nudge(1)}
|
|
90
|
-
disabled={disabled || value >= max}
|
|
91
|
-
aria-label={t.current.increase}
|
|
92
|
-
>
|
|
93
|
-
<svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
|
|
94
|
-
<path d="M7 2.5v9M2.5 7h9" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" />
|
|
95
|
-
</svg>
|
|
96
|
-
</button>
|
|
97
|
-
</span>
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Tone } from '../../core/tones.js';
|
|
3
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
|
|
4
|
-
value?: number;
|
|
5
|
-
min?: number;
|
|
6
|
-
max?: number;
|
|
7
|
-
step?: number;
|
|
8
|
-
tone?: Tone;
|
|
9
|
-
invalid?: boolean;
|
|
10
|
-
/** Short unit rendered inside the field, e.g. `'px'` or `'%'`. */
|
|
11
|
-
unit?: string;
|
|
12
|
-
}
|
|
13
|
-
declare const NumberInput: import("svelte").Component<Props, {}, "value">;
|
|
14
|
-
type NumberInput = ReturnType<typeof NumberInput>;
|
|
15
|
-
export default NumberInput;
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
-
import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
|
|
4
|
-
import { useLocale } from '../../core/locale.svelte.js';
|
|
5
|
-
import { passwordScore } from '../../core/password.js';
|
|
6
|
-
import { edge } from './lift.js';
|
|
7
|
-
|
|
8
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
|
|
9
|
-
value?: string;
|
|
10
|
-
tone?: Tone;
|
|
11
|
-
invalid?: boolean;
|
|
12
|
-
/** Draws a four-segment strength meter under the field. */
|
|
13
|
-
strength?: boolean;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
let {
|
|
17
|
-
value = $bindable(''),
|
|
18
|
-
tone = 'brand',
|
|
19
|
-
invalid = false,
|
|
20
|
-
strength = false,
|
|
21
|
-
disabled = false,
|
|
22
|
-
class: className = '',
|
|
23
|
-
...rest
|
|
24
|
-
}: Props = $props();
|
|
25
|
-
|
|
26
|
-
const t = useLocale();
|
|
27
|
-
|
|
28
|
-
let visible = $state(false);
|
|
29
|
-
|
|
30
|
-
const score = $derived(passwordScore(value));
|
|
31
|
-
|
|
32
|
-
const bars = ['bg-danger', 'bg-danger', 'bg-warning', 'bg-info', 'bg-success'];
|
|
33
|
-
const texts = ['text-danger', 'text-danger', 'text-warning', 'text-info', 'text-success'];
|
|
34
|
-
</script>
|
|
35
|
-
|
|
36
|
-
<div class="flex w-full flex-col gap-2">
|
|
37
|
-
<span
|
|
38
|
-
class="inline-flex w-full items-center gap-2 rounded-xl border bg-bg pr-1 pl-3 {edge} transition-colors duration-150 ease-brand-out
|
|
39
|
-
{invalid ? 'border-danger' : `border-hairline-strong ${toneFocusWithinBorder[tone]}`}
|
|
40
|
-
{disabled ? 'pointer-events-none opacity-50' : ''} {className}"
|
|
41
|
-
>
|
|
42
|
-
<input
|
|
43
|
-
bind:value
|
|
44
|
-
{disabled}
|
|
45
|
-
type={visible ? 'text' : 'password'}
|
|
46
|
-
aria-invalid={invalid ? 'true' : undefined}
|
|
47
|
-
class="h-10 w-full min-w-0 bg-transparent font-sans text-sm text-text placeholder:text-text-muted focus:outline-none"
|
|
48
|
-
{...rest}
|
|
49
|
-
/>
|
|
50
|
-
<button
|
|
51
|
-
type="button"
|
|
52
|
-
onclick={() => (visible = !visible)}
|
|
53
|
-
aria-label={visible ? t.current.hidePassword : t.current.showPassword}
|
|
54
|
-
aria-pressed={visible}
|
|
55
|
-
class="shrink-0 rounded p-1.5 text-text-muted transition-colors duration-150 hover:bg-bg-inset hover:text-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current"
|
|
56
|
-
>
|
|
57
|
-
{#if visible}
|
|
58
|
-
<svg class="size-4" viewBox="0 0 20 20" fill="none" aria-hidden="true">
|
|
59
|
-
<path
|
|
60
|
-
d="M2.5 10S5.5 4.5 10 4.5 17.5 10 17.5 10 14.5 15.5 10 15.5 2.5 10 2.5 10Z"
|
|
61
|
-
stroke="currentColor"
|
|
62
|
-
stroke-width="1.4"
|
|
63
|
-
/>
|
|
64
|
-
<circle cx="10" cy="10" r="2.4" stroke="currentColor" stroke-width="1.4" />
|
|
65
|
-
<path
|
|
66
|
-
d="m3.5 16.5 13-13"
|
|
67
|
-
stroke="currentColor"
|
|
68
|
-
stroke-width="1.4"
|
|
69
|
-
stroke-linecap="round"
|
|
70
|
-
/>
|
|
71
|
-
</svg>
|
|
72
|
-
{:else}
|
|
73
|
-
<svg class="size-4" viewBox="0 0 20 20" fill="none" aria-hidden="true">
|
|
74
|
-
<path
|
|
75
|
-
d="M2.5 10S5.5 4.5 10 4.5 17.5 10 17.5 10 14.5 15.5 10 15.5 2.5 10 2.5 10Z"
|
|
76
|
-
stroke="currentColor"
|
|
77
|
-
stroke-width="1.4"
|
|
78
|
-
/>
|
|
79
|
-
<circle cx="10" cy="10" r="2.4" stroke="currentColor" stroke-width="1.4" />
|
|
80
|
-
</svg>
|
|
81
|
-
{/if}
|
|
82
|
-
</button>
|
|
83
|
-
</span>
|
|
84
|
-
|
|
85
|
-
{#if strength}
|
|
86
|
-
<div class="flex items-center gap-3">
|
|
87
|
-
<div class="flex flex-1 gap-1" aria-hidden="true">
|
|
88
|
-
{#each [0, 1, 2, 3] as segment (segment)}
|
|
89
|
-
<span
|
|
90
|
-
class="h-1 flex-1 rounded-full transition-colors duration-200 {segment < score
|
|
91
|
-
? bars[score]
|
|
92
|
-
: 'bg-bg-inset'}"
|
|
93
|
-
></span>
|
|
94
|
-
{/each}
|
|
95
|
-
</div>
|
|
96
|
-
<span class="text-xs font-medium {value ? texts[score] : 'text-text-muted'}">
|
|
97
|
-
{value ? t.current.passwordStrength[score] : '—'}
|
|
98
|
-
</span>
|
|
99
|
-
</div>
|
|
100
|
-
{/if}
|
|
101
|
-
</div>
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
2
|
-
import { type Tone } from '../../core/tones.js';
|
|
3
|
-
interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
|
|
4
|
-
value?: string;
|
|
5
|
-
tone?: Tone;
|
|
6
|
-
invalid?: boolean;
|
|
7
|
-
/** Draws a four-segment strength meter under the field. */
|
|
8
|
-
strength?: boolean;
|
|
9
|
-
}
|
|
10
|
-
declare const PasswordInput: import("svelte").Component<Props, {}, "value">;
|
|
11
|
-
type PasswordInput = ReturnType<typeof PasswordInput>;
|
|
12
|
-
export default PasswordInput;
|