Skip to content
FelicityUI

Input

A text field for short values. Native on every platform; shared intent, tokens, and naming.

Installation

terminal
npx felicityui add input --platform react

Usage

example.tsx
import { Input } from "@/components/ui/input"

<Input label="Email" placeholder="you@studio.com" />

Composition

Use the following composition to build a Input.

FieldGroup
├── legend
└── Input / Textarea
    ├── label [required] [hint]
    ├── start / control / end
    ├── description
    └── error

Use Input for a short value the user types. Do not use it for choosing from a list, picking a date, or a rich text editor.

When to use

  • Email, name, search, or a single-line setting.
  • A password (type="password" / isSecure / isPassword).
  • A few lines of notes via Textarea (React) or the multiline flag on native platforms.
  • Related fields in FieldGroup / FelicityFieldGroup.
  • Units or @ via start / end (React) or prefix / suffix (native).

When not to use

  • A select, combobox, or date picker. Use the platform control. Do not invent a Select from Input.
  • A badge, input-group, or field primitive as extra catalog items. Those patterns are props on Input.
  • A web file dropzone on iOS or Android. Use .fileImporter / ActivityResultContracts.
  • Long documents. Use the platform's text editor.

Basic

Native text field with a visible label. Unlabeled fields need an accessible name.

Field

Label plus helper text on the same control. Not a separate Field catalog item — chrome lives on Input.

We will not share this.

Field group

FieldGroup is a native fieldset. Use it to name a set of fields — not a form library.

Profile
@

Disabled

Not editable. The field wrapper sets data-disabled for styling.

Invalid

error marks the field invalid (aria-invalid) and announces with role=alert.

File

Native type=file on the web. iOS and Android use the platform document picker — do not clone a web file control.

Inline

orientation=horizontal puts the label beside the control. Pair with Button for a search row.

Grid

Place fields side by side with CSS grid or HStack / Row. Still the same Input.

Name

Required

Native required plus a visible mark. Assistive tech gets aria-required; the asterisk is aria-hidden.

Hint

A short label hint such as Recommended. Not a Badge catalog item — pass hint on Input.

Affix

start and end sit inside the control. Units, @, or a compact action — not a separate Input Group page.

@
USD

Password

Obscured value. Native password control, not a custom overlay.

Textarea

Multiline. Ships in this item — not a separate catalog component.

Form

A short form from FieldGroup, Input, Textarea, and Button. No select until that item exists — do not invent one.

Account
@

A few sentences about your work.

RTL

Pass dir=rtl on the React field or group. SwiftUI and Compose follow the system layout direction.

الحساب
@

Size

Control height. Does not apply to textarea.

API Reference

Input

PropTypeDefaultDescription
labelstringVisible label. Required unless an accessible name is provided.
descriptionstringHelper text associated with the field.
errorstringValidation message. Marks the field invalid.
hintstringShort label annotation such as Recommended. Not a Badge component.
requiredbooleanfalseNative required. Shows a mark beside the label; announced to assistive tech.
orientationvertical | horizontalverticalLabel above the control, or beside it.
start / prefixReactNode / StringAffix before the value. React start; SwiftUI/Compose prefix.
end / suffixReactNode / StringAffix after the value. React end; SwiftUI/Compose suffix.
sizesm | md | lgmdControl height. Does not apply to textarea.
invalidbooleanfalseMarks the field invalid without error copy.
disabled / enabledbooleanfalse / truePrevents editing. React/SwiftUI use disabled; Compose uses enabled.
placeholder / promptstringHint inside the empty field. Not a substitute for a label.
typeHTML input typetextNative input type (email, search, password, …).
isSecure / isPasswordbooleanfalseObscure the value. SwiftUI isSecure; Compose isPassword.
classNamestringAdditional classes.

Accessibility

WCAG 2.2 AA

  • Must be a real text field (input/textarea, TextField, OutlinedTextField), not a contenteditable div.
  • Visible label is the accessible name, or an aria-label / contentDescription when the label is omitted.
  • Description and error are programmatically associated with the field.
  • Invalid state is exposed to assistive tech.
  • Disabled fields are not editable.
  • Touch target at least 24×24 CSS pixels and preferably 44×44 on touch platforms.
  • Placeholder is not the only name.

Platform notes

React

Renders a native HTML input (and textarea). No form library. Label, description, and error are optional field chrome around the control.

  • Server Component compatible. No client JavaScript is required.
  • Prefer a visible label. Unlabeled fields need aria-label or aria-labelledby.
  • error sets aria-invalid and is announced with role="alert".
  • Textarea, FieldGroup, start/end affixes, hint, and required ship in this item — not separate catalog components.
  • type=file is a native file control. Do not restyle this into a combobox, date picker, or dropzone.

SwiftUI

SwiftUI TextField / SecureField. Multiline uses TextField with axis: .vertical. Not a UITextField wrapper.

  • Requires Xcode 15+ / iOS 17+. Add generated files to the Xcode target.
  • VoiceOver reads the label. Prompt is the placeholder.
  • Disable with .disabled(_:). isSecure swaps in SecureField.
  • Error text uses accessibilityValue. Dynamic Type follows .body.
  • prefix/suffix, hint, required, and FelicityFieldGroup ship in this file.
  • File picking is .fileImporter or PhotosPicker — not a cloned web file input.

Compose

Material 3 OutlinedTextField with FelicityUI colors — not Material color roles. Supporting text carries description or error.

  • TalkBack uses the label or contentDescription.
  • isError styles the outline and supporting text with color.danger.default.
  • isPassword uses PasswordVisualTransformation.
  • singleLine = false is the textarea equivalent. Material 3 may keep a 48dp minimum touch target.
  • prefix/suffix, hint, required, and FelicityFieldGroup ship in this file.
  • File picking is ActivityResultContracts — not type=file.