Form controls

TextField
v3.0.1
Ready for Production

A versatile single-line text input with icon slots, tag support, and validation states.

Prefer AI-assisted development?

This documentation is available via the Catalyst MCP Server. Learn how to connect →

Catalyst TextField is a compound component built around a native <input> element. It provides a slot-based architecture for icons and tags, danger and disabled states driven by design tokens, and a composed mode for embedding the field inside other bordered containers.

Preview

Installation

npm install @pmi/catalyst-text-field
import { TextFieldRoot, TextFieldInput, TextFieldSlot } from '@pmi/catalyst-text-field';

Variants

Sizes

TextFieldRoot supports three sizes via the size prop: sm, md (default), and lg. Scale icons inside TextFieldSlot to match - use xs for sm, sm for md, and md for lg.

Preview

Danger

Set danger on TextFieldRoot to apply error styling. Pair with aria-invalid on the input and an associated error message via aria-describedby.

Preview
Error: This field is required.

Disabled

Set disabled on TextFieldRoot to lock the field. The prop propagates to the inner <input> via context.

Preview

Common Patterns

With Icons

Use TextFieldSlot with side="left" or side="right" to place icons beside the input.

Preview

With Tags

Place TextFieldSlot elements with tag children to the left of the input for multi-value chip patterns.

Preview
Tag

Password Field

Use type="password" on TextFieldInput and a TextFieldSlot with a toggle button.

Preview

With Helper Text

Use HelperText below the field linked via aria-describedby for guidance or character counts.

Preview
Subtext

Payment Field

Compose a SelectRoot in a side="none" slot alongside the input for combined selector + text patterns.

Preview

File Upload

Use asChild on TextFieldInput and a hidden native <input type="file"> for custom file selection UI.

Preview

No file chosen

SVG, PNG, JPG or GIF (MAX. 800x400px).

Quantity Number

Use type="number" with min, max, and step to constrain integer input. Pair with increment/decrement buttons in a TextFieldSlot for a stepper pattern.

Preview
Current value:

Phone Number

Combine a country SelectRoot in a precomposed container with a bare <input type="tel"> for international phone inputs. This example uses intl-tel-input for flag rendering and phone validation. The utils.js asset is served locally from /intl-tel-input-utils.js (copied from node_modules at build time) to avoid a CDN dependency in the Content Security Policy.

Preview
Enter a valid phone number

API Reference

TextFieldRoot

Prop

Type

TextFieldInput

Prop

Type

TextFieldSlot

Prop

Type

Accessibility

TextField targets WCAG 2.2 AA conformance.

Prefer a visible label by using <Label htmlFor="..."> with a matching id on TextFieldInput. Never rely on placeholder as the only label - placeholder text disappears on input and fails SC 1.3.1 (Info and Relationships) and SC 4.1.2 (Name, Role, Value). When a visible label is not feasible (e.g. an icon-only search field in a toolbar), use aria-label on TextFieldInput to provide the accessible name instead.

Error states must be communicated beyond color alone (SC 1.4.1). Use aria-invalid="true" on the input and link an error message via aria-describedby pointing to a <HelperText> with role="alert" (SC 3.3.1, Error Identification).

Focus visibility is handled by the component's inset ring styles (SC 2.4.7, Focus Visible; SC 2.4.11, Focus Not Obscured).

Input purpose - set the appropriate type and autocomplete attribute to satisfy SC 1.3.5 (Identify Input Purpose) and trigger the correct mobile keyboard.

Keyboard Interactions

The following keys are supported when the field or one of its slots has focus.

KeyBehavior
TabMoves focus into and out of the field
Standard input keysNative <input> behavior - type, delete, select, copy/paste

ARIA Attributes

Set these attributes on TextFieldInput to communicate state and purpose to assistive technology.

AttributePurpose
aria-invalidSignal validation error state to assistive technology
aria-describedbyLink helper text or error message
aria-labelProvide the accessible name when a visible <Label> is not feasible - e.g. aria-label="Search" on an icon-only search field
aria-requiredIndicate a required field when not using the native required attribute

Choosing the Right Component

Use this table to select the most appropriate input component for a given scenario.

ScenarioComponent
Single-line text, email, password, searchTextField
Multi-line text entryTextArea
Choosing from a fixed list of optionsSelect
Multi-value tag selectionTextField + Tag
  • Label - Associate a visible label with the field using htmlFor
  • HelperText - Helper text and validation messages below the field
  • TextArea - Multi-line text input
  • Select - Dropdown option selection
  • Tag - Chip elements for multi-value inputs

On this page