input: add use & focus utilities

This commit is contained in:
Elijah Duffy
2025-07-04 03:17:38 -07:00
parent 604cf0ee0d
commit e6e58ab106
2 changed files with 28 additions and 0 deletions

View File

@@ -6,11 +6,14 @@
type ValidatorOptions type ValidatorOptions
} from '@svelte-toolkit/validate'; } from '@svelte-toolkit/validate';
import { generateIdentifier } from './util'; import { generateIdentifier } from './util';
import { onMount } from 'svelte';
type $Props = Omit<HTMLInputAttributes, 'name' | 'value'> & { type $Props = Omit<HTMLInputAttributes, 'name' | 'value'> & {
name?: string; name?: string;
value?: string; value?: string;
validate?: ValidatorOptions; validate?: ValidatorOptions;
focus?: boolean;
use?: (node: HTMLInputElement) => void;
ref?: HTMLInputElement | null; ref?: HTMLInputElement | null;
onvalidate?: (e: InputValidatorEvent) => void; onvalidate?: (e: InputValidatorEvent) => void;
}; };
@@ -21,6 +24,8 @@
value = $bindable(''), value = $bindable(''),
placeholder, placeholder,
validate: validateOpts, validate: validateOpts,
focus: focusOnMount = false,
use,
ref = $bindable<HTMLInputElement | null>(null), ref = $bindable<HTMLInputElement | null>(null),
onvalidate, onvalidate,
...others ...others
@@ -28,12 +33,24 @@
let valid: boolean = $state(true); let valid: boolean = $state(true);
export const focus = () => {
if (ref) ref.focus();
};
const conditionalUse = $derived(use ? use : () => {});
$effect(() => { $effect(() => {
// default autovalOnInvalid to true unless explicitly set to false // default autovalOnInvalid to true unless explicitly set to false
if (validateOpts !== undefined && validateOpts.autovalOnInvalid === undefined) { if (validateOpts !== undefined && validateOpts.autovalOnInvalid === undefined) {
validateOpts.autovalOnInvalid = true; validateOpts.autovalOnInvalid = true;
} }
}); });
onMount(() => {
if (focusOnMount && ref) {
ref.focus();
}
});
</script> </script>
<input <input
@@ -52,6 +69,7 @@
others.class others.class
]} ]}
use:validate={validateOpts} use:validate={validateOpts}
use:conditionalUse
onvalidate={(e) => { onvalidate={(e) => {
valid = e.detail.valid; valid = e.detail.valid;
if (onvalidate) onvalidate(e); if (onvalidate) onvalidate(e);

View File

@@ -14,6 +14,8 @@
type?: HTMLInputElement['type']; type?: HTMLInputElement['type'];
validate?: ValidatorOptions; validate?: ValidatorOptions;
invalidMessage?: string; invalidMessage?: string;
focus?: boolean;
use?: (node: HTMLInputElement) => void;
ref?: HTMLInputElement | null; ref?: HTMLInputElement | null;
class?: ClassValue | null | undefined; class?: ClassValue | null | undefined;
} }
@@ -27,11 +29,17 @@
type, type,
validate: validateOpts, validate: validateOpts,
invalidMessage = 'Field is required', invalidMessage = 'Field is required',
focus: focusOnMount = false,
use,
ref = $bindable<HTMLInputElement | null>(null), ref = $bindable<HTMLInputElement | null>(null),
class: classValue class: classValue
}: Props = $props(); }: Props = $props();
let valid: boolean = $state(true); let valid: boolean = $state(true);
export const focus = () => {
if (ref) ref.focus();
};
</script> </script>
<div class={['w-full', classValue]}> <div class={['w-full', classValue]}>
@@ -50,6 +58,8 @@
onvalidate={(e) => { onvalidate={(e) => {
valid = e.detail.valid; valid = e.detail.valid;
}} }}
focus={focusOnMount}
{use}
/> />
{#if validateOpts} {#if validateOpts}