Forms
Input
Capture user text input with a flexible, accessible field. Supports variants, colors, icons, avatars, loading, highlight, and custom snippets.
Playground
Experiment with different props in real-time.
Basic Usage
A simple text input.
<script lang="ts">
import { Input } from 'sv5ui';
</script>
<Input placeholder="Enter text..." />Variants
5 visual styles.
<Input variant="outline" placeholder="Outline" />
<Input variant="soft" placeholder="Soft" />
<Input variant="subtle" placeholder="Subtle" />
<Input variant="ghost" placeholder="Ghost" />
<Input variant="none" placeholder="None" />Sizes
5 sizes.
<Input size="xs" placeholder="Extra Small" />
<Input size="sm" placeholder="Small" />
<Input size="md" placeholder="Medium" />
<Input size="lg" placeholder="Large" />
<Input size="xl" placeholder="Extra Large" />Colors
Color schemes visible when highlight is active.
<Input color="primary" highlight placeholder="Primary" />
<Input color="secondary" highlight placeholder="Secondary" />
<Input color="success" highlight placeholder="Success" />
<Input color="warning" highlight placeholder="Warning" />
<Input color="error" highlight placeholder="Error" />
<Input color="info" highlight placeholder="Info" />With Icons
Add icons in various positions.
<!-- Leading icon (shorthand) -->
<Input icon="lucide:search" placeholder="Search..." />
<!-- Leading icon (explicit) -->
<Input leadingIcon="lucide:mail" placeholder="Email" />
<!-- Trailing icon -->
<Input trailingIcon="lucide:eye" placeholder="Password" type="password" />
<!-- Both icons -->
<Input leadingIcon="lucide:link" trailingIcon="lucide:copy" placeholder="https://example.com" />
<!-- Trailing prop: moves icon to right -->
<Input icon="lucide:calendar" trailing placeholder="Pick a date" />With Avatar
Display an avatar in the leading position.
U
<Input
avatar={{ src: 'https://i.pravatar.cc/40', alt: 'User' }}
placeholder="What's on your mind?"
/>Input Types
All HTML input types are supported.
<Input type="text" placeholder="Text" />
<Input type="password" placeholder="Password" trailingIcon="lucide:eye" />
<Input type="number" placeholder="Number" />
<Input type="email" placeholder="Email address" leadingIcon="lucide:mail" />
<Input type="url" placeholder="https://..." leadingIcon="lucide:globe" />
<Input type="tel" placeholder="Phone number" leadingIcon="lucide:phone" />Loading
Show a spinner.
<Input loading placeholder="Loading..." />
<Input loading leadingIcon="lucide:search" placeholder="Searching..." />Highlight
Show a colored ring. Auto-enabled on form errors.
<!-- Normal highlight -->
<Input highlight placeholder="Highlighted input" />
<!-- Error highlight -->
<Input highlight color="error" placeholder="Error highlight" />
<!-- Success highlight -->
<Input highlight color="success" placeholder="Success highlight" />Disabled
Prevent interaction.
<Input disabled placeholder="Disabled input" />
<Input disabled value="Cannot edit this" />Controlled
Use bind:value for two-way binding.
You typed: (empty)
<script lang="ts">
import { Input } from 'sv5ui';
let value = $state('');
</script>
<Input bind:value placeholder="Type something..." />
<p>You typed: {value}</p>UI Slots
Use the ui prop to override classes on internal elements.
| Slot | Description |
|---|---|
root | Outermost wrapper — controls overall layout |
base | Inner input element — controls shape, padding, typography |
leading | Leading content wrapper |
leadingIcon | Icon before input |
leadingAvatar | Avatar before input |
leadingAvatarSize | Avatar size override |
trailing | Trailing content wrapper |
trailingIcon | Icon after input |
<Input
placeholder="Custom styled"
leadingIcon="lucide:search"
ui={{
root: 'rounded-full',
base: 'rounded-full',
leadingIcon: 'text-primary'
}}
/>Snippets
Use snippets to replace leading or trailing content.
| Snippet | Description |
|---|---|
leadingSlot | Custom content before input — replaces icon and avatar |
trailingSlot | Custom content after input — replaces trailing icon |
https://
<Input placeholder="example.com" ui={{ base: 'ps-18' }}>
{#snippet leadingSlot()}
<span class="border-r border-on-surface/15 pr-2 text-xs font-medium text-on-surface/50">https://</span>
{/snippet}
{#snippet trailingSlot()}
<Button size="xs" variant="solid" color="primary" label="Go" />
{/snippet}
</Input>Props
| Prop | Type | Default |
|---|---|---|
value | string | - |
type | string | 'text' |
variant | 'outline' | 'soft' | 'subtle' | 'ghost' | 'none' | 'outline' |
color | ColorType | 'primary' |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' |
highlight | boolean | false |
loading | boolean | false |
loadingIcon | string | icons.loading |
icon | string | - |
leadingIcon | string | - |
trailingIcon | string | - |
trailing | boolean | false |
avatar | AvatarProps | - |
placeholder | string | - |
disabled | boolean | false |
id | string | - |
name | string | - |
ref | HTMLInputElement | null | - |
class | string | - |
ui | Record<Slot, Class> | - |