Skip to content

Input

Single-line text input atom. Handles focus ring, error styling, and disabled state through the theme. In most form contexts, prefer FormField — it wraps Input with a label and error message handling.

When to use: When you need a bare input with no label (e.g. inside a custom layout). When building a custom field molecule.

When not to use: In a form with a label and validation — use FormField. For multi-line text — use TextArea.

import { Input } from '@/components';
<Input
value={email}
onChangeText={setEmail}
placeholder="you@example.com"
keyboardType="email-address"
autoCapitalize="none"
/>
PropTypeDefaultDescription
valuestringControlled value (required)
onChangeText(text: string) => voidChange handler (required)
placeholderstringPlaceholder text
isErrorbooleanfalseError state styling (red border)
isDisabledbooleanfalsePrevents interaction
shape'default' | 'pill''default'Border radius strategy
keyboardTypeKeyboardTypeOptions'default'RN keyboard type
autoCapitalize'none' | 'sentences' | 'words' | 'characters''sentences'
secureTextEntrybooleanfalsePassword masking
returnKeyTypeReturnKeyTypeOptionsReturn key label
onSubmitEditing() => voidCalled on return key press
onFocus() => voidFocus handler
onBlur() => voidBlur handler
testIDstringFor testing
// Default — uses theme.radius.md (rounded on Slate/Quartz, sharp on Obsidian)
<Input value={v} onChangeText={s} shape="default" />
// Pill — full radius (9999), wider horizontal padding for pill input fields
<Input value={v} onChangeText={s} shape="pill" placeholder="Search…" />

Pill shape bumps paddingHorizontal from spacing.sm to spacing.lg to compensate for the narrower usable area inside a curved pill.

<Input value={v} onChangeText={s} placeholder="Normal" />
<Input value={v} onChangeText={s} isError placeholder="Error state" />
<Input value={v} onChangeText={s} isDisabled placeholder="Disabled" />

Do: Use FormField in forms — it handles labels and error messages automatically.

// ✓ Form field with label + error
<FormField label="Email" value={email} onChangeText={setEmail} errorMessage={emailError} />
// ✓ Bare input when label isn't needed (e.g. inside a SearchBar)
<Input value={query} onChangeText={setQuery} placeholder="Search…" />

Don’t: Manually pass isError when using through FormField. FormField derives error state from errorMessage.