We'll never share your email

import { Input } from "@cloudflare/kumo";

export function InputBasicDemo() {
  return (
    <Input
      label="Email"
      placeholder="you@example.com"
      description="We'll never share your email"
    />
  );
}

Installation

Barrel

import { Input } from "@cloudflare/kumo";

Granular

import { Input } from "@cloudflare/kumo/components/input";

Usage

Use the label prop to enable the built-in Field wrapper with label, description, and error support.

import { Input } from "@cloudflare/kumo";

export default function Example() {
  return (
    <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.

import { Input } from "@cloudflare/kumo";

export default function Example() {
  return <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

import { Input } from "@cloudflare/kumo";

export function InputWithLabelDemo() {
  return (
    <Input
      label="Username"
      placeholder="Choose a username"
      description="3-20 characters, alphanumeric only"
    />
  );
}

With Error (String)

Pass error as a string for simple error messages. Error replaces description when present.

Please enter a valid email address
import { Input } from "@cloudflare/kumo";

export function InputErrorStringDemo() {
  return (
    <Input
      label="Email"
      placeholder="you@example.com"
      value="invalid-email"
      variant="error"
      error="Please enter a valid email address"
    />
  );
}

With Error (Validation Object)

Pass error as an object with message and match for HTML5 validation. Error shows when field validity matches.

import { Input } from "@cloudflare/kumo";

export function InputErrorObjectDemo() {
  return (
    <Input
      label="Password"
      type="password"
      value="short"
      variant="error"
      error={{
        message: "Password must be at least 8 characters",
        match: "tooShort",
      }}
      minLength={8}
    />
  );
}

Input Sizes

Four sizes available: xs, sm, base (default), lg.

import { Input } from "@cloudflare/kumo";

export function InputSizesDemo() {
  return (
    <div className="flex flex-col gap-4">
      <Input size="xs" label="Extra Small" placeholder="Extra small input" />
      <Input size="sm" label="Small" placeholder="Small input" />
      <Input label="Base" placeholder="Base input (default)" />
      <Input size="lg" label="Large" placeholder="Large input" />
    </div>
  );
}

Disabled

import { Input } from "@cloudflare/kumo";

export function InputDisabledDemo() {
  return <Input label="Disabled field" placeholder="Cannot edit" disabled />;
}

Optional Field

Set required={false} to show “(optional)” text after the label.

import { Input } from "@cloudflare/kumo";

export function InputOptionalFieldDemo() {
  return (
    <Input
      label="Phone Number"
      required={false}
      placeholder="+1 (555) 000-0000"
    />
  );
}

With Label Tooltip

Use labelTooltip to add an info icon with additional context on hover.

import { Input } from "@cloudflare/kumo";

export function InputLabelTooltipDemo() {
  return (
    <Input
      label="API Key"
      labelTooltip="Find this in your dashboard under Settings > API Keys"
      placeholder="sk_live_..."
    />
  );
}

ReactNode Label

The label prop accepts ReactNode for rich formatting.

import { Input } from "@cloudflare/kumo";

export function InputReactNodeLabelDemo() {
  return (
    <Input
      label={
        <span>
          Email for <strong>billing</strong>
        </span>
      }
      required
      placeholder="billing@company.com"
      type="email"
    />
  );
}

Bare Input (No Label)

Input without label renders as a bare input. Must provide aria-label for accessibility.

import { Input } from "@cloudflare/kumo";

export function InputBareDemo() {
  return <Input placeholder="Search..." aria-label="Search products" />;
}

Input Types

Supports all HTML input types: text, email, password, number, tel, url, etc.

import { Input } from "@cloudflare/kumo";

export function InputTypesDemo() {
  return (
    <div className="flex flex-col gap-4">
      <Input type="email" label="Email" placeholder="you@example.com" />
      <Input type="password" label="Password" placeholder="••••••••" />
      <Input type="number" label="Age" placeholder="18" />
      <Input type="tel" label="Phone" placeholder="+1 (555) 000-0000" />
    </div>
  );
}

API Reference

Input accepts all standard HTML input attributes plus the following:

PropTypeDefaultDescription
labelReactNode-Label content for the input (enables Field wrapper) - can be a string or any React node
labelTooltipReactNode-Tooltip content to display next to the label via an info icon
descriptionReactNode-Helper text displayed below the input
errorstring | object-Error message or validation error object
size"xs" | "sm" | "base" | "lg""base"Input size. - `"xs"` — Extra small for compact UIs - `"sm"` — Small for secondary fields - `"base"` — Default size - `"lg"` — Large for prominent fields
variant"default" | "error""default"Visual variant. - `"default"` — Standard input - `"error"` — Error state for validation failures

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

Missing accessible names trigger console warnings in development.

Error Association

Error messages are automatically associated with the input via ARIA attributes for screen reader announcement.