Skip to content

Commit f793084

Browse files
committed
Change how TextInput handles Buttons
1 parent f6528cf commit f793084

7 files changed

Lines changed: 51 additions & 45 deletions

File tree

src/lib/components/input/EmailInput.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<script lang="ts">
22
import TextInput from '$lib/components/input/TextInput.svelte';
3-
import type { ButtonSettings } from '$lib/components/input/impl/ButtonSettings';
43
import { validateEmail } from '$lib/inputvalidation/emailValidator';
54
import type { AnyComponent } from '$lib/types/AnyComponent';
65
import type { ValidationResult } from '$lib/types/ValidationResult';
6+
import type { Snippet } from 'svelte';
77
import type { FullAutoFill } from 'svelte/elements';
88
99
interface Props {
@@ -14,7 +14,7 @@
1414
valid?: boolean;
1515
validate?: boolean;
1616
Icon?: AnyComponent;
17-
button?: ButtonSettings;
17+
after?: Snippet;
1818
}
1919
2020
let {
@@ -25,7 +25,7 @@
2525
valid = $bindable(false),
2626
validate = true,
2727
Icon,
28-
button,
28+
after,
2929
}: Props = $props();
3030
3131
let validationResult = $derived<ValidationResult | null>(
@@ -37,4 +37,4 @@
3737
});
3838
</script>
3939

40-
<TextInput {label} {placeholder} {autocomplete} bind:value {validationResult} {Icon} {button} />
40+
<TextInput {label} {placeholder} {autocomplete} bind:value {validationResult} {Icon} {after} />

src/lib/components/input/PasswordInput.svelte

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { Eye, EyeOff } from '@lucide/svelte';
33
import { checkPwnedCount } from '$lib/api/pwnedPasswords';
44
import TextInput from '$lib/components/input/TextInput.svelte';
5+
import { Button } from '$lib/components/ui/button';
56
import { handleApiError } from '$lib/errorhandling/apiErrorHandling';
67
import { validatePassword } from '$lib/inputvalidation/passwordValidator';
78
import type { AnyComponent } from '$lib/types/AnyComponent';
@@ -131,11 +132,22 @@
131132
bind:value
132133
{validationResult}
133134
{Icon}
134-
button={{
135-
Icon: valueShown ? EyeOff : Eye,
136-
class: 'cursor-pointer',
137-
onClick: () => (valueShown = !valueShown),
138-
}}
139135
onblur={() => (showPopup = false)}
140136
popup={showPopup ? popup : undefined}
141-
/>
137+
>
138+
{#snippet after()}
139+
<Button
140+
type="button"
141+
class="cursor-pointer"
142+
onclick={() => (valueShown = !valueShown)}
143+
variant="ghost"
144+
disabled={validationResult === null || (validationResult && !validationResult.valid)}
145+
>
146+
{#if valueShown}
147+
<EyeOff />
148+
{:else}
149+
<Eye />
150+
{/if}
151+
</Button>
152+
{/snippet}
153+
</TextInput>

src/lib/components/input/TextInput.svelte

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
<script lang="ts">
2-
import { Button } from '$lib/components/ui/button';
32
import { Input } from '$lib/components/ui/input';
43
import type { AnyComponent } from '$lib/types/AnyComponent';
54
import { GetValResColor, type ValidationResult } from '$lib/types/ValidationResult';
65
import type { Snippet } from 'svelte';
76
import type { FocusEventHandler, FullAutoFill } from 'svelte/elements';
8-
import type { ButtonSettings } from './impl/ButtonSettings';
97
108
interface Props {
119
type?: 'text' | 'password';
12-
label: string;
10+
label?: string;
1311
placeholder?: string;
1412
autocomplete?: FullAutoFill;
1513
value: string;
1614
validationResult?: ValidationResult | null;
1715
Icon?: AnyComponent;
18-
button?: ButtonSettings;
16+
after?: Snippet;
1917
popup?: Snippet;
2018
onblur?: FocusEventHandler<HTMLInputElement> | null;
2119
}
@@ -31,14 +29,16 @@
3129
value = $bindable(),
3230
validationResult,
3331
Icon,
34-
button,
32+
after,
3533
popup,
3634
onblur,
3735
}: Props = $props();
3836
</script>
3937

4038
<label for={inputId} class="w-full">
41-
<span>{label}</span>
39+
{#if label}
40+
<span>{label}</span>
41+
{/if}
4242
<div class="relative flex grow flex-row items-center gap-2">
4343
{#if Icon}
4444
<Icon />
@@ -63,21 +63,8 @@
6363
{@render popup()}
6464
</div>
6565
{/if}
66-
{#if button}
67-
<Button
68-
type="button"
69-
class={button.class ?? 'disabled:opacity-50'}
70-
onclick={button.onClick}
71-
variant="ghost"
72-
disabled={button.submits &&
73-
(validationResult === null || (validationResult && !validationResult.valid))}
74-
>
75-
{#if 'Icon' in button}
76-
<button.Icon />
77-
{:else if 'text' in button}
78-
{button.text}
79-
{/if}
80-
</Button>
66+
{#if after}
67+
{@render after()}
8168
{/if}
8269
</div>
8370
{#if validationResult?.message}

src/lib/components/input/UsernameInput.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<script lang="ts">
22
import { accountV2Api } from '$lib/api';
33
import TextInput from '$lib/components/input/TextInput.svelte';
4-
import type { ButtonSettings } from '$lib/components/input/impl/ButtonSettings';
54
import { handleApiError } from '$lib/errorhandling/apiErrorHandling';
65
import {
76
UsernameCheckingAvailabilityValRes,
@@ -12,6 +11,7 @@
1211
import type { AnyComponent } from '$lib/types/AnyComponent';
1312
import type { ValidationResult } from '$lib/types/ValidationResult';
1413
import type { TimeoutHandle } from '$lib/types/WAPI';
14+
import type { Snippet } from 'svelte';
1515
import type { FullAutoFill } from 'svelte/elements';
1616
1717
interface Props {
@@ -22,7 +22,7 @@
2222
valid?: boolean;
2323
validate?: boolean;
2424
Icon?: AnyComponent;
25-
button?: ButtonSettings;
25+
after?: Snippet;
2626
}
2727
2828
let {
@@ -33,7 +33,7 @@
3333
valid = $bindable(false),
3434
validate = true,
3535
Icon,
36-
button,
36+
after,
3737
}: Props = $props();
3838
3939
let validationResult = $state<ValidationResult | null>(null);
@@ -83,4 +83,4 @@
8383
});
8484
</script>
8585

86-
<TextInput {label} {placeholder} {autocomplete} bind:value {validationResult} {Icon} {button} />
86+
<TextInput {label} {placeholder} {autocomplete} bind:value {validationResult} {Icon} {after} />

src/routes/(authenticated)/settings/account/ChangeEmail.svelte

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script lang="ts">
22
import Mail from '@lucide/svelte/icons/mail';
33
import EmailInput from '$lib/components/input/EmailInput.svelte';
4+
import { Button } from '$lib/components/ui/button';
45
import type { ApiUserSelf } from '$lib/types/ApiUser';
56
67
interface Props {
@@ -22,5 +23,8 @@
2223
autocomplete="off"
2324
bind:value={email}
2425
Icon={Mail}
25-
button={{ text: 'Change', submits: true, onClick: submitEmail }}
26-
/>
26+
>
27+
{#snippet after()}
28+
<Button type="button" onclick={submitEmail} variant="ghost">Change</Button>
29+
{/snippet}
30+
</EmailInput>

src/routes/(authenticated)/settings/account/ChangeUsername.svelte

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import User from '@lucide/svelte/icons/user';
33
import { accountV1Api } from '$lib/api';
44
import UsernameInput from '$lib/components/input/UsernameInput.svelte';
5+
import { Button } from '$lib/components/ui/button';
56
import { handleApiError } from '$lib/errorhandling/apiErrorHandling';
67
import { UserStore } from '$lib/stores/UserStore';
78
import type { ApiUserSelf } from '$lib/types/ApiUser';
@@ -42,5 +43,8 @@
4243
autocomplete="off"
4344
bind:value={username}
4445
Icon={User}
45-
button={{ text: 'Change', submits: true, onClick: submitUsername }}
46-
/>
46+
>
47+
{#snippet after()}
48+
<Button type="button" onclick={submitUsername} variant="ghost">Change</Button>
49+
{/snippet}
50+
</UsernameInput>

src/routes/flashtool/+page.svelte

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,11 +228,10 @@
228228
>
229229
<pre id="terminal" class="text-left text-xs">{terminalText}</pre>
230230
</div>
231-
<TextInput
232-
label="Command"
233-
placeholder="Command"
234-
button={{ text: 'Run', onClick: RunCommand }}
235-
bind:value={terminalCommand}
236-
/>
231+
<TextInput label="Command" placeholder="Command" bind:value={terminalCommand}>
232+
{#snippet after()}
233+
<Button type="button" onclick={RunCommand} variant="ghost">Run</Button>
234+
{/snippet}
235+
</TextInput>
237236
</SheetContent>
238237
</Sheet>

0 commit comments

Comments
 (0)