<script lang="ts"> import { Eye, EyeSlash } from 'svelte-heros-v2'; import type { Snippet } from 'svelte'; let { label, notice, id, name, type = 'text', value = $bindable(), placeholder, pattern, required = false, disabled = false, readonly = false, checked = $bindable(false), size = 'md', pickyWidth = true, containerClass = '', inputElement = $bindable(), oninput, onclick }: { label?: Snippet; notice?: Snippet; id?: string; name?: string; type?: string; value?: string; placeholder?: string; pattern?: RegExp; required?: boolean; disabled?: boolean; readonly?: boolean; checked?: boolean; size?: 'xs' | 'sm' | 'md' | 'lg'; pickyWidth?: boolean; containerClass?: string; inputElement?: HTMLInputElement; oninput?: (e: Event & { currentTarget: EventTarget & HTMLInputElement }) => void; onclick?: (e: Event) => void; } = $props(); let initialType = type; let passwordEyeSize = { xs: '14', sm: '18', md: '24', lg: '30' }; </script> <!-- the cursor-not-allowed class must be set here because a disabled button does not respect the 'cursor' css property --> <div class={containerClass} class:cursor-not-allowed={type === 'submit' && disabled}> {#if type === 'submit'} <input class="btn" class:btn-xs={size === 'xs'} class:btn-sm={size === 'sm'} class:btn-md={size === 'md'} class:btn-lg={size === 'lg'} {id} type="submit" {disabled} bind:value bind:this={inputElement} {oninput} {onclick} /> {:else} <div> {#if label} <label class="label" for={id}> <span class="label-text"> {@render label()} {#if required} <span class="text-red-700">*</span> {/if} </span> </label> {/if} <div class="relative flex items-center" class:sm:max-w-[16rem]={type !== 'checkbox' && pickyWidth} > <input class:checkbox={type === 'checkbox'} class:checkbox-xs={type === 'checkbox' && size === 'xs'} class:checkbox-sm={type === 'checkbox' && size === 'sm'} class:checkbox-md={type === 'checkbox' && size === 'md'} class:checkbox-lg={type === 'checkbox' && size === 'lg'} class:input,w-full={type !== 'checkbox'} class:input-xs={type !== 'checkbox' && size === 'xs'} class:input-sm={type !== 'checkbox' && size === 'sm'} class:input-md={type !== 'checkbox' && size === 'md'} class:input-lg={type !== 'checkbox' && size === 'lg'} class:input-bordered={type !== 'checkbox'} class:pr-11={initialType === 'password'} class:!border-none,!text-inherit={disabled} {id} {name} {type} {value} {checked} {placeholder} {required} {disabled} {readonly} bind:this={inputElement} autocomplete="off" onchange={() => { if (type === 'checkbox') { checked = !checked; } }} oninput={(e: Event & { currentTarget: EventTarget & HTMLInputElement }) => { value = e.currentTarget.value; if (pattern && !pattern.test(value)) return; oninput?.(e); }} onpaste={(e) => { if (pattern && e.clipboardData && !pattern.test(e.clipboardData.getData('text'))) { e.preventDefault(); } }} {onclick} /> {#if initialType === 'password'} <button class="absolute right-3" type="button" onclick={() => { type = type === 'password' ? 'text' : 'password'; }} > {#if type === 'password'} <EyeSlash variation="solid" size={passwordEyeSize[size]} /> {:else} <Eye variation="solid" size={passwordEyeSize[size]} /> {/if} </button> {/if} </div> {#if notice} <label class="label" for={id}> <span class="label-text-alt"> {@render notice()} </span> </label> {/if} </div> {/if} </div>