TextFieldv3.0.1Ready for Production
A versatile single-line text input with icon slots, tag support, and validation states.
Prefer AI-assisted development?
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.
Installation
npm install @pmi/catalyst-text-fieldimport { 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.
Danger
Set danger on TextFieldRoot to apply error styling. Pair with aria-invalid on the input and an associated error message via aria-describedby.
Disabled
Set disabled on TextFieldRoot to lock the field. The prop propagates to the inner <input> via context.
Common Patterns
With Icons
Use TextFieldSlot with side="left" or side="right" to place icons beside the input.
With Tags
Place TextFieldSlot elements with tag children to the left of the input for multi-value chip patterns.
Password Field
Use type="password" on TextFieldInput and a TextFieldSlot with a toggle button.
With Helper Text
Use HelperText below the field linked via aria-describedby for guidance or character counts.
Payment Field
Compose a SelectRoot in a side="none" slot alongside the input for combined selector + text patterns.
File Upload
Use asChild on TextFieldInput and a hidden native <input type="file"> for custom file selection UI.
No file chosen
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.
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.
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.
| Key | Behavior |
|---|---|
Tab | Moves focus into and out of the field |
| Standard input keys | Native <input> behavior - type, delete, select, copy/paste |
ARIA Attributes
Set these attributes on TextFieldInput to communicate state and purpose to assistive technology.
| Attribute | Purpose |
|---|---|
aria-invalid | Signal validation error state to assistive technology |
aria-describedby | Link helper text or error message |
aria-label | Provide the accessible name when a visible <Label> is not feasible - e.g. aria-label="Search" on an icon-only search field |
aria-required | Indicate 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.
| Scenario | Component |
|---|---|
| Single-line text, email, password, search | TextField |
| Multi-line text entry | TextArea |
| Choosing from a fixed list of options | Select |
| Multi-value tag selection | TextField + Tag |
Related
- 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