Text Input
Warning
This page is in draft and has not yet been edited or approved.
Text inputs allow users to enter and edit short-form text content. They are foundational form controls used across nearly every data-entry workflow — from login screens to complex enterprise forms.
Core capabilities:
- Single-line text entry (text, email, password, URL, search, telephone)
- Numeric entry with optional stepper controls
- Multi-line entry via text area
- Inline validation with actionable error messages
- Suffix text for units (e.g., "kg", "USD")
- Optional leading/trailing icons and hint tooltips
Anatomy
A text input consists of the following elements:
- Label — describes the expected input; always visible above the field. Uses semibold weight to distinguish from input value.
- Required indicator — an asterisk (*) preceding the label, colored in the accent red token, signals a mandatory field.
- Hint icon — an optional help icon (ⓘ) beside the label that reveals a tooltip on hover or focus.
- Input container / field — the bordered area where users type. This is the core interactive region.
- Placeholder text — hint text inside the field that disappears once the user begins typing.
- Value text — the user-entered content displayed inside the field.
- Leading icon (optional) — a visual cue at the start of the input (e.g., search icon).
- Trailing icon / action (optional) — an interactive icon at the end of the field (e.g., clear ✕, password visibility toggle).
- Suffix text (optional) — static text appended inside the field to indicate units (e.g., "kg", "USD"). Supported on numeric inputs.
- Helper / hint text — persistent guidance below the field (e.g., format instructions).
- Validation / error message — replaces or appears below helper text when input is invalid.
- Character count (optional) — displays current / maximum characters for constrained inputs.
Specifications
All text input variants share a single size. The field height is 36px (8px padding top + 20px line-height + 8px padding bottom).
| Token / Property | Value |
|---|---|
| Field height | 36px |
| Border width | 1px (border-width-thin) |
| Border radius | 4px (border-radius-md) |
| Padding (inner) | 8px (padding-component-md) |
| Label font | Source Sans 3 SemiBold, 14px (font-size-sm) |
| Value font | Source Sans 3 Regular, 14px (font-size-sm) |
| Line height | 20px (line-height-sm) |
| Default max-width | 400px (field-short-max-width) |
| Long field max-width | 800px |
States
Text inputs support the following states:
- Default (Value) — field displays user-entered content with a base border color.
- Default (Placeholder) — empty field showing placeholder text in a muted color.
- Hovered — border color shifts to indicate interactivity. Cursor changes to
cursor: text. - Focused / Active (Hint) — field is selected via click or keyboard tab; border highlights with the focus color and hint text may appear below.
- Focused / Active (Field) — cursor is active and the user is typing in the field.
- Disabled — field is non-interactive; reduced opacity,
cursor: not-allowed. Disabled fields are not focusable and their values are not included in form submission. - Invalid — border turns to the critical/red token; an error icon and message appear below the field.
- Focused + Invalid — the field is focused while in an error state; combines the focus ring styling with the error border.
- Read-only — displays the value but is not editable; border is removed or visually reduced. Read-only fields are included in form submission, unlike disabled fields.
Disabled vs. Read-only
A disabled field is non-interactive and its value is not submitted with the form. A read-only field can be interacted with (tabbed to, text selected) and its value is submitted. Use read-only when the value is important for context or form processing but should not be changed by the user.
Variants
| Variant | Description |
|---|---|
| Text input | Standard single-line text field for general text entry. |
| Password input | Masked input with a visibility toggle icon. Includes a password-creation variant with a strength indicator (weak / medium / strong — future feature). |
| Numeric input | Constrained to numeric values; supports suffix text for units (e.g., "kg"). |
| Numeric input — stepper | Numeric field with increment / decrement buttons on either side of the field. |
| Text area | Multi-line text input with a taller container; supports vertical resize. |
Width behavior:
- Default width — field max-width is 400px, suitable for most single-line inputs (names, emails).
- Long field — max-width of 800px for inputs that expect longer content (descriptions, URLs).
- Full width —
width: 100%to fill the parent container. - Minimum width — apply a sensible minimum to prevent labels or values from being clipped.
Size the field width to match the expected content length. A ZIP code field should be narrower than a street address field.
Read-only display (Display Field)
The Figma source includes read-only label-value pairs in both horizontal and vertical layouts. These are the same component as Display Field (pwc-display-field) — a purely presentational, read-only element for showing static label-value data. The read-only pairs in the text input Figma section are not a separate component; they are pwc-display-field.
When to use which:
- Display Field (
pwc-display-field) — use for static, non-editable label-value display. This is the standard read-only pattern across forms and detail views. - Text input read-only state — use only when the field may become editable again in the same context (e.g., toggling between view and edit mode). The read-only input retains its field styling so the transition to editable feels seamless.
For component API and framework examples, see Display Field.
Choosing the right input type
| Input type | When to use |
|---|---|
| Text input | Use when the expected input is a single line of free-form text — names, email addresses, search queries. |
| Password input | Use for sensitive credential fields. Always include the visibility toggle so users can verify their entry. |
| Numeric input | Use when the value is strictly a number — quantity, age, price. Add suffix text to indicate units when appropriate. |
| Numeric stepper | Use when users benefit from increment / decrement controls for small bounded ranges (e.g., quantity 1–10). |
| Text area | Use when multi-line or free-form text is expected — descriptions, comments, notes. |
When not to use:
- Don't use a text input for selecting from a predefined list — use a Select or Combobox instead.
- Don't use a text area for single-line entries.
- Don't use a text input for date entry — use the dedicated Date Picker component.
- Autocomplete / typeahead behavior is handled by the Combobox component, not the text input.
Labels and helper text
- Always use a visible label — do not rely solely on placeholder text as a label. Placeholder text disappears on input, leaving users without context (ref: Google M3, IBM Carbon).
- Keep labels concise: 1–3 words (e.g., "Email address", not "Please enter your email address here").
- Use helper text for formatting guidance (e.g., "MM/DD/YYYY") or character limits.
- Helper text should remain visible while the user types.
Placeholder text
- Use placeholder text as a supplementary hint, not a replacement for the label.
- Example: Label = "Phone number", Placeholder = "(555) 123-4567".
- Placeholder text disappears when the user begins typing.
- Avoid critical information in placeholder text — once typing starts, it's gone.
Validation and errors
- Validate on blur (when the user leaves the field), not on every keystroke — unless real-time feedback is beneficial (e.g., password strength).
- Error messages should be specific and actionable:
- ❌ "Invalid input"
- ✅ "Enter a valid email address (e.g., name@example.com)"
- Position the error message below the field, replacing or supplementing the helper text.
- Use the critical/red border and error icon to draw attention to the field in error.
Required vs. optional fields
- Mark required fields with the asterisk (*) indicator preceding the label.
- If most fields in a form are required, consider marking the optional ones instead with "(optional)" — this reduces visual noise (ref: Shopify Polaris).
- Be consistent within a form: choose one convention and stick with it.
Character limits
- Show a character counter when there is a maximum length.
- Format: "12 / 100" — current count / maximum.
- The counter should update in real time as the user types.
- When the limit is reached, prevent further input or clearly indicate overflow.
Placement and alignment
- Left-align labels above inputs — this is the most readable arrangement for forms (ref: Google M3, IBM Carbon).
- Maintain consistent field widths within a form group.
- Size the input width to match the expected content length (e.g., a ZIP code input should be narrower than a "Street address" field).
- Group related fields logically (e.g., first name + last name on the same row).
Do's and Don'ts
- Always pair inputs with visible labels above the field.
- Use appropriate input types (
email,tel,url) for built-in browser validation and mobile keyboard hints. - Provide clear, specific error messages that tell users how to fix the problem.
- Group related fields logically (e.g., first name + last name on the same row).
Storybook demo
Explore the interactive component demos and API documentation in Storybook:
For developer integration guides including framework-specific setup (React 18, React 19+, Angular, Vanilla JS), see the Input component documentation.




