We'll never share your email
<script lang="ts">
import { Input, Label } from 'kumo-svelte';
</script>
<div class="space-y-2">
<Label>Email</Label>
<Input placeholder="you@example.com" />
<p class="text-sm text-kumo-subtle">We'll never share your email</p>
</div> Installation
Barrel
import { Input, Textarea } from 'kumo-svelte'; Granular
import { Input, Textarea } from 'kumo-svelte/components/input';Usage
With Built-in Field (Recommended)
Use the label prop to enable the built-in Field wrapper with label,
description, and error support.
<script lang="ts"> import { Input } from 'kumo-svelte';</script><Input label="Email" placeholder="you@example.com" description="We'll never share your email"/> Bare Input (Custom Layouts)
For custom form layouts, use Input without label. Must provide aria-label or aria-labelledby for accessibility.
<script lang="ts"> import { Input } from 'kumo-svelte';</script><Input placeholder="Search..." aria-label="Search products" />Examples
With Label and Description
The label prop enables the built-in Field wrapper with automatic vertical
layout (label above input).
3-20 characters, alphanumeric only
<script lang="ts">
import { Input, Label } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="w-full max-w-sm space-y-2">
<Label>Username</Label>
<Input placeholder="Choose a username" />
<p class="text-sm text-kumo-subtle">3-20 characters, alphanumeric only</p>
</div>
</div> With Error (String)
Pass error as a string for simple error messages. Error styling is
automatically applied when the error prop is truthy.
Please enter a valid email address
<script lang="ts">
import { Input, Label } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="w-full max-w-sm space-y-2">
<Label>Email</Label>
<Input value="invalid-email" invalid />
<p class="text-sm text-kumo-danger">Please enter a valid email address</p>
</div>
</div> With Error (Validation Object)
Pass error as an object with message and match for HTML5 validation.
Error shows when field validity matches.
Password must be at least 8 characters
<script lang="ts">
import { Input, Label } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="w-full max-w-sm space-y-2">
<Label>Password</Label>
<Input type="password" value="short" invalid />
<p class="text-sm text-kumo-danger">Password must be at least 8 characters</p>
</div>
</div> Input Sizes
Four sizes available: xs, sm, base (default), lg.
<script lang="ts">
import { Input, Label } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="flex w-full max-w-sm flex-col gap-4">
<div class="space-y-1.5"><Label>Extra Small</Label><Input size="xs" placeholder="Extra small input" /></div>
<div class="space-y-1.5"><Label>Small</Label><Input size="sm" placeholder="Small input" /></div>
<div class="space-y-1.5"><Label>Base</Label><Input placeholder="Base input (default)" /></div>
<div class="space-y-1.5"><Label>Large</Label><Input size="lg" placeholder="Large input" /></div>
</div>
</div> Disabled
<script lang="ts">
import { Input, Label } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="w-full max-w-sm space-y-2"><Label>Disabled field</Label><Input placeholder="Cannot edit" disabled /></div>
</div> Optional Field
Set required={false} to show "(optional)" text after the label.
<script lang="ts">
import { Input, Label } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="w-full max-w-sm space-y-2"><Label>Phone Number <span class="font-normal text-kumo-subtle">(optional)</span></Label><Input placeholder="+1 (555) 000-0000" /></div>
</div> With Label Tooltip
Use labelTooltip to add an info icon with additional context on hover.
<script lang="ts">
import { Input, Label } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="w-full max-w-sm space-y-2"><Label>API Key</Label><Input placeholder="sk_live_..." /></div>
</div> Snippet Label
The label prop accepts a Svelte snippet for rich formatting.
<script lang="ts">
import { Input, Label } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="w-full max-w-sm space-y-2">
<Label>Email for <strong>billing</strong> <span class="text-kumo-danger">*</span></Label>
<Input placeholder="billing@company.com" type="email" />
</div>
</div> Controlled with oninput
The standard Svelte oninput handler receives the full event object. Use event.currentTarget.value to get the value.
Uses e.target.value
<script lang="ts">
import { Input, Label } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="w-full max-w-sm space-y-2"><Label>{'With onChange'}</Label><Input placeholder="Type something..." /><p class="text-sm text-kumo-subtle">{'Uses e.target.value'}</p></div>
</div> Controlled with onValueChange
onValueChange is a convenience handler that gives you the string value
directly without event unwrapping.
Receives the value directly
<script lang="ts">
import { Input, Label } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="w-full max-w-sm space-y-2"><Label>{'With onValueChange'}</Label><Input placeholder="Type something..." /><p class="text-sm text-kumo-subtle">{'Receives the value directly'}</p></div>
</div> Bare Input (No Label)
Input without label renders as a bare input. Must provide aria-label for
accessibility.
<script lang="ts">
import { Input } from '$lib';
import { MagnifyingGlass as Search } from 'phosphor-svelte';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<Input placeholder="Search..." aria-label="Search products" class="max-w-sm" />
</div> Error Without Label
Error messages and descriptions render even without a visible label; use aria-label to keep the input accessible.
Please enter a valid hostname
Path must start with /
<script lang="ts">
import { Input } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="flex w-full max-w-sm flex-col gap-4">
<div class="space-y-1.5"><Input value="not a host" placeholder="example.com" invalid /><p class="text-sm text-kumo-danger">Please enter a valid hostname</p></div>
<div class="space-y-1.5"><Input value="missing-slash" placeholder="/api/v1/users" invalid /><p class="text-sm text-kumo-danger">Path must start with /</p></div>
</div>
</div> Input Types
Supports all HTML input types: text, email, password, number, tel, url, etc.
<script lang="ts">
import { Input, Label } from '$lib';
</script>
<div class="flex min-h-24 w-full items-center justify-center">
<div class="flex w-full max-w-sm flex-col gap-4">
<div class="space-y-1.5"><Label>Email</Label><Input type="email" placeholder="you@example.com" /></div>
<div class="space-y-1.5"><Label>Password</Label><Input type="password" placeholder="••••••••" /></div>
<div class="space-y-1.5"><Label>Age</Label><Input type="number" placeholder="18" /></div>
<div class="space-y-1.5"><Label>Phone</Label><Input type="tel" placeholder="+1 (555) 000-0000" /></div>
</div>
</div> Password Manager Overlays
Set passwordManagerIgnore on non-credential inputs that password managers
might incorrectly classify as login fields.
<script lang="ts">
import { Input } from 'kumo-svelte';
</script>
<div class="flex flex-col gap-4">
<Input label="API Key (default)" type="password" placeholder="sk_live_..." />
<Input
label="API Key (passwordManagerIgnore)"
type="password"
placeholder="sk_live_..."
passwordManagerIgnore
/>
</div> API Reference
Input accepts all standard HTML input attributes plus the following:
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | Snippet | - | Visible label content. |
| labelTooltip | string | Snippet | - | Optional help content for the label. |
| description | string | Snippet | - | Supporting description text. |
| error | FieldError | - | Validation error message or matcher. |
| size | 'xs' | 'sm' | 'base' | 'lg' | "base" | Size preset. |
| variant | 'default' | 'error' | "default" | Visual variant. |
| class | string | - | Additional classes merged onto the root element. |
| passwordManagerIgnore | boolean | false | Adds password-manager ignore attributes. |
| required | boolean | - | Marks the field as required. |
Validation Error Types
When using error as an object, the match property corresponds to HTML5 ValidityState values:
| Match | Description |
|---|---|
| valueMissing | Required field is empty |
| typeMismatch | Value doesn't match type (e.g., invalid email) |
| patternMismatch | Value doesn't match pattern attribute |
| tooShort | Value shorter than minLength |
| tooLong | Value longer than maxLength |
| rangeUnderflow | Value less than min |
| rangeOverflow | Value greater than max |
| true | Always show error (for server-side validation) |
Accessibility
Label Requirement
Inputs require an accessible name via one of:
- `label` prop (recommended)
- `placeholder` + `aria-label` for bare inputs
- `aria-labelledby` for custom label association
Error Association
Error messages are automatically associated with the input via ARIA attributes for screen reader announcement.