Files
sui/components/StyledRawInput.svelte
2025-04-13 07:56:23 -07:00

55 lines
1.4 KiB
Svelte

<script lang="ts">
import type { HTMLInputAttributes } from 'svelte/elements';
import { validate, type InputValidatorEvent, type ValidatorOptions } from '@repo/validate';
type $Props = Omit<HTMLInputAttributes, 'name' | 'value'> & {
name: string;
value?: string;
validate?: ValidatorOptions;
ref?: HTMLInputElement | null;
onvalidate?: (e: InputValidatorEvent) => void;
};
let {
name,
value = $bindable(''),
placeholder,
validate: validateOpts,
ref = $bindable<HTMLInputElement | null>(null),
onvalidate,
...others
}: $Props = $props();
let valid: boolean = $state(true);
$effect(() => {
// default autovalOnInvalid to true unless explicitly set to false
if (validateOpts !== undefined && validateOpts.autovalOnInvalid === undefined) {
validateOpts.autovalOnInvalid = true;
}
});
</script>
<input
id={name}
{name}
{placeholder}
aria-label={placeholder}
{...others}
bind:value
class={[
'border-accent w-full rounded-sm border bg-white px-[1.125rem] py-3.5 font-normal transition-colors',
'text-text placeholder:text-text/60 dark:border-accent/50 dark:bg-text-800 placeholder:font-normal',
'dark:text-background dark:placeholder:text-background/60 dark:sm:bg-slate-800',
'placeholder-shown:text-ellipsis',
!valid && 'border-red-500!',
others.class
]}
use:validate={validateOpts}
onvalidate={(e) => {
valid = e.detail.valid;
if (onvalidate) onvalidate(e);
}}
bind:this={ref}
/>