skrewww

Forms

Text Input

Text Input is a single-line text entry for short, free-form data such as names, emails, or search terms.

State × Size — 15 variants

betaReact AvailableFigma AvailableDocs Partial
React last updated
2026-07-11
Documentation last updated
2026-06-01
Accessibility target
WCAG 2.2 AA (target)
Version
0.1.0-beta

Known open questions

  • FormField composes label/helper/error internally — confirm parity with Figma Form Field Wrapper split.
  • Hover state token mapping not explicitly documented — uses semantic/border/strong on hover.
  • Trailing action slot is a documentation convenience; confirm Figma trailing icon property semantics.

Live preview

Single-line text entry with label, helper, and error relationships wired for assistive technology.

Default

We will never share your email.

Sizes

Small / Medium / Large

States

Required / Error / Disabled

Password must be at least 8 characters.

Icons & actions

Leading icon / Trailing action

Purpose

Single-line text entry for short, free-form data (names, emails, search terms, general form fields).

Variants and states

default · error · disabled

When to use

Any single-line free-text field. Pair with FormField for the label/helper/error pattern rather than building that structure per-instance.

When not to use

Multi-line content (use Textarea). A fixed set of choices (use Select). Search-specific fields (use Search Field).

Accessibility

Must have a visible or aria-labelled <label> in code — never rely on placeholder text alone. Error state needs aria-invalid and aria-describedby. Focused state uses semantic/focus-ring at 2px outside-aligned stroke.

Common mistakes

Using placeholder text as a substitute for a real label. Not visually distinguishing Disabled from Default strongly enough.

Properties

State × Size as variants. Value (text). Show leading/trailing icon (booleans) + Leading/Trailing Icon (instance-swap).

Tokens used

component/radius/controlsemantic/border/defaultsemantic/border/strongsemantic/focus-ringsemantic/action/dangersemantic/surface/default

Component API

PropTypeDefaultDescription
labelstringVisible or visually hidden label associated via FormField.
size"sm" | "md" | "lg""md"Control height and typography scale.
supportingTextstringHelper text linked with aria-describedby when no error is present.
errorstringError message; sets aria-invalid and aria-describedby via ValidationMessage.
requiredbooleanfalseShows required indicator and sets aria-required.
readOnlybooleanfalseRead-only state — distinct from disabled; remains focusable.
leadingIconReactNodeOptional leading icon (Figma: Show leading icon + Leading Icon).
trailingIconReactNodeOptional trailing icon (Figma: Show trailing icon + Trailing Icon).
trailingActionReactNodeInteractive trailing control such as an apply button.
disabledbooleanfalseNative disabled input with non-opacity-only visual treatment.

React example

Copy React example
import { TextInput } from "@/components/ui/TextInput";

export function Example() {
  return (
    <TextInput
      label="Email address"
      type="email"
      placeholder="you@example.com"
      supportingText="Used for account notifications only."
      required
    />
  );
}