Input
A text field for short values. Native on every platform; shared intent, tokens, and naming.
Installation
npx felicityui add input --platform reactUsage
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
└── errorUse 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
@viastart/end(React) orprefix/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.
Disabled
Not editable. The field wrapper sets data-disabled for styling.
Invalid
error marks the field invalid (aria-invalid) and announces with role=alert.
Enter a valid email.
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.
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.
With button
Compose Input with Button. Do not invent an input-specific Button Group — use the Button you already installed.
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.
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
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | Visible label. Required unless an accessible name is provided. |
| description | string | — | Helper text associated with the field. |
| error | string | — | Validation message. Marks the field invalid. |
| hint | string | — | Short label annotation such as Recommended. Not a Badge component. |
| required | boolean | false | Native required. Shows a mark beside the label; announced to assistive tech. |
| orientation | vertical | horizontal | vertical | Label above the control, or beside it. |
| start / prefix | ReactNode / String | — | Affix before the value. React start; SwiftUI/Compose prefix. |
| end / suffix | ReactNode / String | — | Affix after the value. React end; SwiftUI/Compose suffix. |
| size | sm | md | lg | md | Control height. Does not apply to textarea. |
| invalid | boolean | false | Marks the field invalid without error copy. |
| disabled / enabled | boolean | false / true | Prevents editing. React/SwiftUI use disabled; Compose uses enabled. |
| placeholder / prompt | string | — | Hint inside the empty field. Not a substitute for a label. |
| type | HTML input type | text | Native input type (email, search, password, …). |
| isSecure / isPassword | boolean | false | Obscure the value. SwiftUI isSecure; Compose isPassword. |
| className | string | — | Additional 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/contentDescriptionwhen 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 pixelsand preferably44×44on 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 Componentcompatible. No client JavaScript is required.- Prefer a visible label. Unlabeled fields need
aria-labeloraria-labelledby. - error sets
aria-invalidand is announced withrole="alert". - Textarea, FieldGroup, start/end affixes, hint, and required ship in this item — not separate catalog components.
type=fileis 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.
VoiceOverreads the label. Prompt is the placeholder.- Disable with
.disabled(_:). isSecure swaps in SecureField. - Error text uses
accessibilityValue.Dynamic Typefollows.body. - prefix/suffix, hint, required, and FelicityFieldGroup ship in this file.
- File picking is
.fileImporteror PhotosPicker — not a cloned web file input.
Compose
Material 3 OutlinedTextField with FelicityUI colors — not Material color roles. Supporting text carries description or error.
TalkBackuses the label orcontentDescription.- 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
48dpminimum touch target. - prefix/suffix, hint, required, and FelicityFieldGroup ship in this file.
- File picking is ActivityResultContracts — not
type=file.