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

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:

PropTypeDefaultDescription
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 booleanfalseAdds 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:

MatchDescription
valueMissingRequired field is empty
typeMismatchValue doesn't match type (e.g., invalid email)
patternMismatchValue doesn't match pattern attribute
tooShortValue shorter than minLength
tooLongValue longer than maxLength
rangeUnderflowValue less than min
rangeOverflowValue greater than max
trueAlways 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.