Input
Text input fields with validation states, icons, and form integration.
Playground
<Input
error=""
helper="We will never share your email"
label="Email"
placeholder="name@example.com"
/>01 Examples
Search input
clearable with a left search icon — the most common real-world pattern. Press Escape or click the clear button to reset.<Input
clearable
bind:value={searchValue}
placeholder="Search anything..."
aria-label="Search"
>
{#snippet leftIcon()}
<SearchIcon />
{/snippet}
</Input>Password with visibility toggle
type='password' with a clickable right icon — onRightIconClick turns the icon into an accessible button (note the required rightIconAriaLabel).<Input
type={passwordVisible ? 'text' : 'password'}
label="Password"
placeholder="Enter your password"
bind:value={passwordValue}
onRightIconClick={() => (passwordVisible = !passwordVisible)}
rightIconAriaLabel={passwordVisible ? 'Hide password' : 'Show password'}
>
{#snippet leftIcon()}
<LockIcon />
{/snippet}
{#snippet rightIcon()}
{#if passwordVisible}
<EyeOffIcon />
{:else}
<EyeIcon />
{/if}
{/snippet}
</Input>Email field with validation error
error overrides helper and forces danger styling regardless of intent. Combined with a left icon for visual context.<Input
type="email"
label="Email"
placeholder="name@example.com"
value="not-an-email"
error="Please enter a valid email address"
required
>
{#snippet leftIcon()}
<MailIcon />
{/snippet}
</Input>02 Customization
Branded Search Bar
<Input
size="xl"
placeholder="Search components, patterns, tokens..."
clearable
slotClasses={{
container:
'rounded-2xl bg-surface-base shadow-[var(--blocks-shadow-lg)] ring-2 ring-primary/20 focus-within:ring-primary/50 transition-all overflow-hidden',
base: 'border-0 bg-transparent rounded-2xl focus-visible:ring-0'
}}
/>Glassmorphism Input
<Input
unstyled
placeholder="Enter your email"
slotClasses={{
base: 'w-full rounded-xl border border-white/20 bg-white/10 px-5 py-3 text-white placeholder-white/50 shadow-lg backdrop-blur-md transition-all focus-visible:border-white/40 focus-visible:bg-white/15 focus-visible:outline-none'
}}
/>Underline Form
<Input variant="underline" label="Full Name" placeholder="Jane Doe" />
<Input variant="underline" label="Email" placeholder="jane@acme.com" />
<Input variant="underline" label="Phone" placeholder="+49 123 456 789" helper="Optional" />Fully Custom (unstyled)
<Input
unstyled
label="Brutalist Input"
placeholder="Type something..."
class="text-text-primary placeholder:text-text-tertiary w-full border-2 border-current bg-transparent px-4 py-3 font-mono text-sm focus-visible:outline-none"
slotClasses={{
label: 'font-mono text-xs uppercase tracking-widest text-text-secondary mb-1'
}}
/>A field treatment shared across forms belongs in a BlocksProvider preset (presets.Input) — register matching presets for
Select and Textarea under the same name to keep the form language consistent. See Customization.
03 Accessibility
Built-in ARIA
Labels are automatically associated via for and id. Error and helper messages are linked through aria-describedby. Validation states set aria-invalid automatically.
Keyboard
Tab to focus. Native text input behavior for all key combinations. Clearable inputs respond to Escape to clear the value. Focus indication uses focus-visible: for keyboard-only visibility.
Color Contrast
Error, warning, and success states use both color and text to convey status – never color alone. Helper and error messages meet WCAG AA contrast ratios against all surface tokens.
04 API Reference
Prop | Type | Default | Description | |
|---|---|---|---|---|
autoComplete | string | — | HTML autocomplete hint for browser autofill. | |
children | Snippet | — | Snippet content rendered below the input for advanced layouts. | |
class | string | — | Extra classes merged onto the root wrapper element. | |
clearable | boolean | false | Show a clear button when the input has a value.
Press Escape or click the button to clear. Fires onClear after clearing. | |
disabled | boolean | false | Whether the Input is disabled and non-interactive | |
error | string | — | Error message below the input. When set, overrides helper and
forces danger border styling regardless of intent. | |
hasLeftIcon variant | true | false | Controls the hasLeftIcon behavior and appearance of the Input component. Available options: true. | |
hasRightIcon variant | true | false | Controls the hasRightIcon behavior and appearance of the Input component. Available options: true. | |
helper | string | — | Helper text below the input — hidden when error is present. | |
iconPosition variant | leftright | left | Controls the iconPosition behavior and appearance of the Input component. Available options: left, right. | |
intent variant | dangerdefaultsuccesswarning | default | Controls the color theme and semantic meaning of the Input. Affects the overall appearance and user perception. Available options: danger, default, success, warning. | |
label | string | — | Label text displayed above the input, auto-linked via for/id. | |
leftIcon | Snippet | — | Icon snippet rendered on the left side of the input field. | |
leftIconAriaLabel | string | — | Accessible label for the clickable left icon button. Required when
onLeftIconClick is set so screen-reader users hear a name for the
button (icons inside are aria-hidden). | |
messageType variant | errorhelper | helper | Controls the messageType behavior and appearance of the Input component. Available options: error, helper. | |
mint | MintProp | 'none' | Micro-interaction preset applied to the input element. Only applies while not disabled. | |
onClear | () => void | — | Fired after the value is cleared via the clear button or Escape key. | |
onLeftIconClick | () => void | — | When provided, the left icon becomes a clickable button. | |
onRightIconClick | () => void | — | When provided, the right icon becomes a clickable button. | |
persistDebounceMs | number | 300 | Debounce interval (ms) for storage writes. | |
persistKey | string | — | Key for persisting the input value to storage. | |
persistNamespace | string | — | Namespace (e.g. user id) to scope the persist key. | |
persistStorage | localStoragesessionStorage | 'localStorage' | Storage backend for persistence. | |
persistVersion | number | 1 | Version stamp included in the storage key. | |
preset | string | — | Apply a named preset registered via <BlocksProvider presets={{ Input: {...} }}>.
Prefer this over class overrides when the requested look falls outside the
semantic intent palette — presets keep hover/active/dark-mode logic coherent
and make the custom look reusable across the project. | |
readonly | boolean | false | Readonly property for the Input component | |
required | boolean | false | Adds a required asterisk to the label and sets the native required attribute. | |
rightIcon | Snippet | — | Icon snippet rendered on the right side of the input field. | |
rightIconAriaLabel | string | — | Accessible label for the clickable right icon button. Required when
onRightIconClick is set so screen-reader users hear a name for the
button (icons inside are aria-hidden). | |
size variant | lgmdsmxl +1 more | md | Controls the dimensions, padding, and text size of the Input. Affects the component's physical footprint. Available options: lg, md, sm, and 2 more. | |
slotClasses | Partial<Record<InputSlots, string>> | — | Per-slot class overrides merged with tv() styles. Slots: wrapper (root —
what class also targets) | container | base (the <input> element) |
label | message | iconContainer | iconButton | iconDecoration. | |
tier variant | commitmodify | modify | Selects the semantic radius tier of the Input — the shape family it belongs to (--radius-commit/-modify/-contain/-bridge). Shape is retuned per family in your theme, so this picks the family rather than a pixel value. Available options: commit, modify. | |
unstyled | boolean | — | Remove all default tv() classes — only user-provided classes apply. | |
variant variant | filledghostoutlinedunderline | outlined | Controls the visual style and presentation of the Input. Determines the component's visual treatment. Available options: filled, ghost, outlined, underline. | |
...HTMLInputAttributes inherited | HTMLAttributes | — | HTML attributes (excluding: 'size' | 'class' | 'disabled' | 'readonly' | 'children') | |
...InputVariants variant | VariantProps | — | Styling variants from InputVariants |
05 Types
Local type definitions used by this component.
Name | Kind | Category | Used by | Description | |
|---|---|---|---|---|---|
InputProps | interface | props | 0 | — | |
InputVariants | type | variant | 0 | — | |
InputSlots | type | variant | 0 | Slot names derived from the tv() config above — single source of truth for slotClasses. | |
MintProp | type | helper | 1 | — | |
MintName | type | helper | 0 | A mint name: a built-in (autocompleted), 'none' to disable, or any
consumer-registered name. (string & {}) keeps the registry open — a
custom name still type-checks, it just isn't suggested. A typo therefore
also still compiles (it resolves like an unregistered custom name and
warns at runtime); the union buys completion and docs, not validation. | |
MintConfig | interface | helper | 0 | — | |
BuiltinMintName | type | helper | 0 | Built-in mint names as a literal union, so the mint prop autocompletes
across every component — the single list the hand-curated playground knobs
and docs used to drift away from. |
06 Installation
Import
import { Input } from '@urbicon-ui/blocks';