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.

SlotDescription
rootOutermost wrapper — controls overall layout
baseInner input element — controls shape, padding, typography
leadingLeading content wrapper
leadingIconIcon before input
leadingAvatarAvatar before input
leadingAvatarSizeAvatar size override
trailingTrailing content wrapper
trailingIconIcon 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.

SnippetDescription
leadingSlotCustom content before input — replaces icon and avatar
trailingSlotCustom 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

PropTypeDefault
valuestring-
typestring'text'
variant'outline' | 'soft' | 'subtle' | 'ghost' | 'none''outline'
colorColorType'primary'
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'
highlightbooleanfalse
loadingbooleanfalse
loadingIconstringicons.loading
iconstring-
leadingIconstring-
trailingIconstring-
trailingbooleanfalse
avatarAvatarProps-
placeholderstring-
disabledbooleanfalse
idstring-
namestring-
refHTMLInputElement | null-
classstring-
uiRecord<Slot, Class>-