Skip to content

TextField

A labelled text input (or textarea) with hint and error, replacing v1's 17 Input sets.

  • Free core, MIT
  • Version 2.0.0-rc.1
  • APG pattern: Native text input

Examples

These are the real React components. Use them with a mouse, touch or keyboard, and switch the theme and density for every example at once.

Default

Show the code

Default, code

<TextField label="Full name" defaultValue="Priya Shah" autoComplete="name" />

With hint

We only use this to send receipts.
Show the code

With hint, code

<TextField
  label="Email"
  type="email"
  autoComplete="email"
  defaultValue=""
  hint="We only use this to send receipts."
  isRequired
/>

Invalid

Error: Enter an email address like name@example.com
Show the code

Invalid, code

<TextField
  autoComplete="name"
  label="Email"
  type="email"
  defaultValue="priya@"
  isInvalid
  errorMessage="Enter an email address like name@example.com"
/>

Disabled

Show the code

Disabled, code

<TextField label="Full name" defaultValue="Priya Shah" autoComplete="name" isDisabled />

With icons

Show the code

With icons, code

<TextField
  autoComplete="name"
  label="Search team"
  type="search"
  defaultValue=""
  placeholder="Name or email"
  iconStart={Search}
/>

Email

Show the code

Email, code

<TextField
  label="Work email"
  type="email"
  autoComplete="email"
  defaultValue="priya@northwind.co.uk"
  iconStart={Mail}
/>

Multiline

160 characters at most.
Show the code

Multiline, code

<TextField
  autoComplete="name"
  label="Short bio"
  multiline
  maxLength={160}
  showCount
  defaultValue="Product designer in Leeds."
  hint="160 characters at most."
/>

Mobile size

Show the code

Mobile size, code

<TextField label="Email" type="email" autoComplete="email" defaultValue="" size="lg" />

Tokens

The 19 design tokens TextField reads, with the value each has in the theme and density chosen above. Change a token and the component follows, in Figma and in code.

Show all 19 tokens
Tokens TextField reads
TokenValue nowCSS variable
color.border.subtle…--sd-color-border-subtle
color.icon.default…--sd-color-icon-default
color.text.disabled…--sd-color-text-disabled
control.height.lg…--sd-control-height-lg
field.hint…--sd-field-hint
font.line-height.normal…--sd-font-line-height-normal
input.bg…--sd-input-bg
input.bg-disabled…--sd-input-bg-disabled
input.border…--sd-input-border
input.border-hover…--sd-input-border-hover
input.border-invalid…--sd-input-border-invalid
input.fg…--sd-input-fg
input.height…--sd-input-height
input.padding-x…--sd-input-padding-x
input.placeholder…--sd-input-placeholder
input.radius…--sd-input-radius
motion.duration.fast…--sd-motion-duration-fast
motion.easing.standard…--sd-motion-easing-standard
spacing.inset.sm…--sd-spacing-inset-sm

Install

The npm package isn’t published yet. When it is, this is the install line; until then, this page runs the same build of the package (from commit fa3abf8).

Install

npm i @superduperui/react @superduperui/tokens

Import

import { TextField } from "@superduperui/react"

Props

TextField also takes the props of the React Aria component it’s built on.

TextField props
PropTypeWhat it does
labelrequiredstringVisible label (required: placeholders are not labels).
hintstringHelp text under the field, linked by aria-describedby (3.3.5).
errorMessagestring | ((validation: ValidationResult) => string)Error text, shown with an icon and "Error:" when the field is invalid.
placeholderstring
type'text' | 'email' | 'tel' | 'url' | 'search' | 'password'Default 'text'Sets the keyboard too: email, tel and url get the matching inputmode.
iconStartLucideIconDecorative Lucide icon inside the start of the field.
iconEndLucideIconDecorative Lucide icon inside the end of the field.
multilinebooleanMulti-line (renders a textarea).
rowsnumberDefault 4
showCountbooleanWith maxLength: show "n of max characters" and announce politely when 20 or fewer remain.
inputRefRef<HTMLInputElement>
textAreaRefRef<HTMLTextAreaElement>
actionEndReactNodeAn interactive control inside the end of the field, e.g. a show-password toggle (44px).
hideLabelbooleanKeep the label for assistive technology but hide it visually (only where a visible heading or column label names the field).
size'default' | 'lg'Default 'default'default: control/height/md (44px Comfortable); lg (mobile): control/height/lg (52px), for phone form anatomy. Single-line only.

When to use it

Use it for

  • Any single-line or multi-line text entry

Use something else for

  • Choosing from a fixed list: use Select
  • Yes/no: use Checkbox or Switch

Accessibility

Screen readers announce "Email, edit text, required, invalid entry, Error: Enter an email address like name@example.com".

WCAG 2.2 AAA criteria the component meets in Comfortable density: 1.4.6, 1.4.9, 2.1.3, 2.3.2, 2.4.13, 2.5.5, 2.5.6.

Compact density meets AA (2.5.8, 24px targets), not AAA.

What your product still has to do

  • Set autoComplete for personal data fields
  • Write error messages that say how to fix the problem
  • Move focus to the first invalid field on submit

Shared patterns it ships with: 1.3.6 (set autoComplete); 3.3.5 (hint); 3.3.6 (errors with a way to recover); 3.3.8 / 3.3.9 (paste and password managers never blocked).

This release’s test results

Test results for TextField in this release
axe-core (WCAG A, AA, AAA and best practice)180 runs across every story, theme, density and width: 0 violations
Rendered text contrast260 text runs: 0 below 7:1, lowest 8.43:1
Target size44 targets: 0 under 44px in Comfortable
Focus appearance (2.4.13)36 focus stops in 3 browser engines: all pass
Keyboard scriptChromium 3 of 3, Firefox 3 of 3, WebKit 3 of 3

Manual passes with VoiceOver and NVDA haven’t been done yet.

Keyboard

Each step is scripted and run in Chromium, Firefox and WebKit.

TextField keyboard steps
KeyWhat happens
TabTab reaches the field; it is invalid and its error is its description
ControlOrMeta+ANative editing keys work (select all)
Text is entered, replacing the selection

In Figma

The Figma component is TextField, with State (Default, Hover, Focus, Disabled, Invalid); Content (Placeholder, Filled); Label visibility (Visible, Hidden); Multiline (False, True); Size (Default, Mobile). The Figma library isn’t published yet.

Figma to code: State (Default, Hover, Focus, Disabled = isDisabled, Invalid = isInvalid); Content (Placeholder = placeholder, Filled = defaultValue); Label visibility → hideLabel (Visible = false, Hidden = true); Multiline → multiline (False = false, True = true); Value → placeholder | defaultValue (by Content); Leading icon → iconStart when Show leading icon; Trailing icon → iconEnd when Show trailing icon; Size → size (Default = "default", Mobile = "lg"); nested Label → label; nested Hint → hint; nested FieldError → errorMessage.