Skip to content

TextInput

TextInput

Category: Forms & inputs

<TextInput label="Email" type="email" placeholder="[email protected]" isRequired />
<TextInput type="search" label="Search" prefix={<SearchIcon />} />
<TextInput label="URL" type="url" prefix="https://" suffix=".com" />

Install: @helix-ui/core

import { TextInput } from '@helix-ui/core';

status: stable · since: 0.1.0

Tags: input, text, single-line

Live playground

Open the full editor or source on GitHub.

Anatomy

Label
[ prefix | text input | suffix ]
Help / error

Layout

  • displayblock
  • widthfill
  • heightcontent
  • intrinsicSizefills width, ~36-44px tall
  • stackabletrue
  • fullBleedfalse

Visual

A single-line input with built-in label, description, error, and prefix/suffix slots for icons or units.

Props

NameTypeDefaultDescription
labelReactNodeVisible label rendered above the input.
descriptionReactNodeHelper text below the input.
errorMessagestring | (v: ValidationResult) => stringError message below the input. Can be a function for built-in validate results.
placeholderstringPlaceholder text.
size'sm' | 'md' | 'lg'mdControl height.
prefixReactNodeInline content before the input — icon or static label.
suffixReactNodeInline content after the input.
isRequiredbooleanfalseMarks the field required for validation.
isInvalidbooleanfalseForces the invalid state.
isDisabledbooleanfalseDisables the input.
...restTextFieldProps from react-aria-componentsForwarded — value/defaultValue/onChange/onBlur/etc.

Tokens used

color.bg.surface.default, color.bg.surface.muted, color.border.default, color.border.focus, color.border.danger, color.text.primary, color.text.secondary, color.text.muted, color.text.action.danger, radius.md, space.2, space.3, font.family.sans, font.size.sm, font.size.md, font.size.lg, font.weight.medium

Accessibility

Notes

  • Built on react-aria-components TextField — keyboard, screen-reader, and validation are handled.
  • Pass label instead of relying on placeholder for accessibility.
  • Set type to match what the field holds. On iOS and Android it is the only thing that decides which keyboard opens: email shows the @ and .com keys and stops the first letter being capitalised, tel opens the dial pad, url shows / and .com, and search puts Search on the action key. A field left at the default text gets plain QWERTY, which is why an email field is the classic mobile form failure.
  • Add autoComplete on anything an OS keychain should fill — email, username, current-password, new-password, one-time-code. iOS Keychain, Android Autofill and the desktop password managers all key off those exact tokens and offer nothing without them.
  • type="search" also makes Escape clear the field in Safari and Chrome. That is usually welcome, but inside a dialog it competes with Escape-to-close, so prefer type="text" with enterKeyHint=\"search\" for a search box in an overlay.

Composes with

ComponentRelationNote
FormparentInside Form.
InputGroupparentCompose with Buttons via InputGroup.
NumberFieldalternativeNumberField for numbers.
TextareaalternativeTextarea for multi-line.
Fieldsibling

Prompt examples

These are the AI prompt → JSX mappings used by the helix-ui prompt DSL and integrations like Cursor / Claude Code.

simple text field

“email input with placeholder”

<TextInput
label="Email"
type="email"
placeholder="[email protected]"
value={email}
onChange={setEmail}
/>

with leading icon

“search input with magnifying glass prefix”

<TextInput type="search" label="Search" prefix={<SearchIcon />} value={q} onChange={setQ} />