Input

Atom
The Input component is a React Native text field with semantic boolean props (error, small, large, compact, disabled), plus prefix/suffix addons, overlaid icons (leadingIcon / trailingIcon with any Canvas glyph as icon), a passwordToggle eye for a secureTextEntry value, a clearable clear button, and a shortcut keycap. Input is single-line; for multi-line entry use the dedicated Textarea.

Playground

Every control sets a real prop of InputProps. The JSX below updates as you go.
Workspace name
Props
label
string
placeholder
string
value
string
Size
pick one
prefix
string
suffix
string
icon
icon
required
boolean
error
boolean
disabled
boolean
readOnly
boolean
clearable
boolean
passwordToggle
boolean
JSX · InputProps
<Input label="Workspace name" placeholder="e.g. Northwind" />

Variants

17 examples from src/atoms/input/input.md, each rendered live from its own JSX.
Toolbar search
<Input search systemFocus placeholder="Search work items" />
Email
Label
<Input label="Email" placeholder="rachel.chen@example.com" />
Full name
Required
<Input label="Full name" required placeholder="Rachel Chen" />
https://
Prefix
<Input prefix="https://" placeholder="canvas.dev" />
Action
<Input suffix="Copy" action defaultValue="cnv_3f9a21b8e7" />
Icon
<Input leadingIcon icon="search" placeholder="Search" />
Email address
Email
<Input label="Email address" leadingIcon icon="mail" placeholder="example@domain.com" keyboardType="email-address" autoCapitalize="none" autoComplete="email" />
Password
Password
<Input label="Password" leadingIcon icon="lock" secureTextEntry passwordToggle placeholder="••••••••" autoComplete="password" />
Username
Username
<Input label="Username" leadingIcon icon="user" placeholder="yourname" defaultValue="danello87" autoCapitalize="none" autoComplete="username" />
Date of birth
Date of birth
<Input label="Date of birth" leadingIcon icon="calendar" placeholder="MM/DD/YYYY" keyboardType="numbers-and-punctuation" autoComplete="birthdate-full" />
Amount
$
Currency
<Input label="Amount" prefix="$" placeholder="0.00" keyboardType="decimal-pad" />
Search
<Input leadingIcon icon="search" clearable placeholder="Search" defaultValue="example" />
Card Number
Card number
<Input label="Card Number" trailingIcon icon="creditCard" placeholder="•••• •••• •••• ••••" keyboardType="number-pad" autoComplete="cc-number" textContentType="creditCardNumber" />
Error
<Input error placeholder="rachel.chen@example.com" />
Disabled
<Input disabled placeholder="rachel.chen@example.com" />
Read only
<Input readOnly accessibilityLabel="Email" defaultValue="rachel.chen@example.com" />
Measure
<Column snug>
<Input xs start placeholder="xs step, pinned to the start (320)" />
<Input lg start placeholder="lg step, pinned to the start (512)" />
<Container lg start><Input placeholder="Bare, in an lg Container: fills it (512)" /></Container>
</Column>

Sizes

Workspace name
small
Workspace name
default
Workspace name
large

States

Hover, focus and press are pinned so they can be compared side by side; the rest are real props.
Workspace name
default
Workspace name
hover
Workspace name
focus
Workspace name
error
Workspace name
disabled
Workspace name
readOnly

Anatomy

Workspace URL
.canvas.dev
1
Label
2
Field
3
Leading icon
4
Value or placeholder
5
Trailing action
6
Helper or error
Dimmed parts appear only in some states or variants.

Props

47 props on InputProps, grouped as they are declared in source. Required props are marked *.
Prop
Type
Default
Description
Props
26 props
value
string
–
Current text value (controlled). Omit and use defaultValue for uncontrolled use.
onChangeText
(text: string) => void
–
Called with the new text on each keystroke.
placeholder
string
–
Placeholder shown while the field is empty.
label
string
–
The field's persistent label. Its placement is platform-adaptive: iOS and web render it ABOVE the field (the static title the Field/Form composers produce today); Android renders the Material 3 in-container FLOATING label (centered like a placeholder at rest, floating to the top once the field is focused or filled). The label is the field's programmatic name (wired via both accessibilityLabel and aria-labelledby), so a placeholder is no longer needed for the accessible name.
search
boolean
false
A toolbar search field with a magnifier and a tracked uppercase empty prompt on web.
eyebrow
boolean
false
Dense uppercase eyebrow label where the skin offers it.
systemFocus
boolean
false
Preserve the system focus outline on a framed field.
soft
boolean
false
Use the brand’s softer entry-well fill where the skin provides it.
required
boolean
false
Marks the field as required: appends a destructive "*" to the label (decorative, never in the accessible name) and announces the field as required, through aria-required on the web and with the word in its name ("Full name, required") on iOS and Android. The star takes effect only alongside label.
textContentType
'none' | 'URL' | 'addressCity' | 'addressCityAndState' | 'addressState' | 'countryName' | 'creditCardNumber' | 'creditCardExpiration' | 'cre…
–
Give the keyboard and the system information about the expected semantic meaning for the content that users enter. To disable autofill, set textContentType to none. Possible values for textContentType are: - 'none' - 'URL' - 'addressCity' - 'addressCityAndState' - 'addressState' - 'countryName' - 'creditCardNumber' - 'creditCardExpiration' (iOS 17+) - 'creditCardExpirationMonth' (iOS 17+) - 'creditCardExpirationYear' (iOS 17+) - 'creditCardSecurityCode' (iOS 17+) - 'creditCardType' (iOS 17+) - 'creditCardName' (iOS 17+) - 'creditCardGivenName' (iOS 17+) - 'creditCardMiddleName' (iOS 17+) - 'creditCardFamilyName' (iOS 17+) - 'emailAddress' - 'familyName' - 'fullStreetAddress' - 'givenName' - 'jobTitle' - 'location' - 'middleName' - 'name' - 'namePrefix' - 'nameSuffix' - 'nickname' - 'organizationName' - 'postalCode' - 'streetAddressLine1' - 'streetAddressLine2' - 'sublocality' - 'telephoneNumber' - 'username' - 'password' - 'newPassword' - 'oneTimeCode' - 'birthdate' (iOS 17+) - 'birthdateDay' (iOS 17+) - 'birthdateMonth' (iOS 17+) - 'birthdateYear' (iOS 17+) - 'cellularEID' (iOS 17.4+) - 'cellularIMEI' (iOS 17.4+) - 'dateTime' (iOS 15+) - 'flightNumber' (iOS 15+) - 'shipmentTrackingNumber' (iOS 15+)
autoCapitalize
'none' | 'sentences' | 'words' | 'characters'
–
Can tell TextInput to automatically capitalize certain characters. characters: all characters, words: first letter of each word sentences: first letter of each sentence (default) none: don't auto capitalize anything https://reactnative.dev/docs/textinput#autocapitalize
autoComplete
'2fa-app-otp' | 'additional-name' | 'address-line1' | 'address-line2' | 'birthdate-day' | 'birthdate-full' | 'birthdate-month' | 'birthdate-…
–
Specifies autocomplete hints for the system, so it can provide autofill. On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content. To disable autocomplete, set autoComplete to off. The following values work across platforms: - additional-name - address-line1 - address-line2 - cc-number - country - current-password - email - family-name - given-name - honorific-prefix - honorific-suffix - name - new-password - off - one-time-code - postal-code - street-address - tel - username The following values work on iOS only: - nickname - organization - organization-title - url The following values work on Android only: - birthdate-day - birthdate-full - birthdate-month - birthdate-year - cc-csc - cc-exp - cc-exp-day - cc-exp-month - cc-exp-year - 2fa-app-otp - email-otp - flight-confirmation-code - flight-number - gender - gift-card-number - gift-card-pin - loyalty-account-number - name-family - name-given - name-middle - name-middle-initial - name-prefix - name-suffix - password - password-new - postal-address - postal-address-country - postal-address-dependent-locality - postal-address-extended - postal-address-extended-postal-code - postal-address-locality - postal-address-region - postal-address-unit - promo-code - sms-otp - tel-country-code - tel-national - tel-device - upi-vpa - wifi-password - username-new
autoCorrect
boolean
false
If false, disables auto-correct. The default value is true.
autoFocus
boolean
false
If true, focuses the input on componentDidMount. The default value is false.
defaultValue
string
–
Provides an initial value that will change when the user starts typing. Useful for simple use-cases where you don't want to deal with listening to events and updating the value prop to keep the controlled state in sync.
keyboardType
KeyboardTypeOptions
–
enum("default", 'numeric', 'email-address', "ascii-capable", 'numbers-and-punctuation', 'url', 'number-pad', 'phone-pad', 'name-phone-pad', 'decimal-pad', 'twitter', 'web-search', 'visible-password') Determines which keyboard to open, e.g.numeric. The following values work across platforms: - default - numeric - email-address - phone-pad The following values work on iOS: - ascii-capable - numbers-and-punctuation - url - number-pad - name-phone-pad - decimal-pad - twitter - web-search The following values work on Android: - visible-password
inputMode
InputModeOptions
–
Works like the inputmode attribute in HTML, it determines which keyboard to open, e.g. numeric and has precedence over keyboardType.
maxLength
number
–
Limits the maximum number of characters that can be entered. Use this instead of implementing the logic in JS to avoid flicker.
onBlur
((e: BlurEvent) => void)
–
Callback that is called when the text input is blurred Note: If you are trying to find the last value of TextInput, you can use the onEndEditing event, which is fired upon completion of editing.
onFocus
((e: FocusEvent) => void)
–
Callback that is called when the text input is focused
onSubmitEditing
((e: TextInputSubmitEditingEvent) => void)
–
Callback that is called when the text input's submit button is pressed.
onKeyPress
((e: TextInputKeyPressEvent) => void)
–
Callback that is called when a key is pressed. This will be called with { nativeEvent: { key: keyValue } } where keyValue is 'Enter' or 'Backspace' for respective keys and the typed-in character otherwise including ' ' for space. Fires before onChange callbacks. Note: on Android only the inputs from soft keyboard are handled, not the hardware keyboard inputs.
returnKeyType
ReturnKeyTypeOptions
–
enum('default', 'go', 'google', 'join', 'next', 'route', 'search', 'send', 'yahoo', 'done', 'emergency-call') Determines how the return key should look.
secureTextEntry
boolean
false
If true, the text input obscures the text entered so that sensitive text like passwords stay secure. The default value is false.
testID
string
–
Used to locate this view in end-to-end tests
ref
React.Ref<RNTextInput>
–
Ref to the underlying React Native host. Supports object refs and callback refs; native methods follow the platform's behavior.
State
4 props
error
boolean
false
invalid
boolean
false
MeasureProps · width steps xxxs 192 · xxs 256 · xs 320 · sm 384 · md 448 · lg 512 · xl 576 · xxl 672 · xxxl 768 · wide 896 · wider 1024 · widest 1152 · page 1280, plus start to pin to the leading edge.

Accessibility and keyboard

Keyboard
Type
Edits the value
Tab
Next field
Escape
Clears when clearable
Semantics
Roles
button
States
selected
ARIA on web
aria-describedby
aria-hidden
aria-invalid
aria-label
aria-labelledby
aria-required
From the docs
Pass label (and required) to name the field: iOS and web render the label above the control, while Android floats the Material 3 in-container label. On Android the field grows with the user's text size so the floated label never meets the value, and a label longer than the field truncates on one line inside it while the field's accessible name stays the whole label. The required star is decorative: a screen reader hears the field as required, from aria-required on the web and from its name ("Full name, requir
soft uses the brand’s entry-well fill where the skin provides it. systemFocus preserves the platform’s system focus outline. An explicit accessibilityLabel takes precedence over the visible label’s accessible name.
Pass search for the toolbar search: a magnifier, a borderless editor, and a uppercase prompt while empty on web. The prompt names the editor unless accessibilityLabel or label supplies its purpose. iOS draws its search field (a 36-point muted well) and Android the Material 3 search bar (a 56-dp muted stadium). systemFocus preserves the system focus outline for the borderless editor.

Platform skins

The playground's props on each platform: same tree, native shapes, type and touch sizes.
https://
Web
control 10 · field 10 · card 16 · Instrument Sans
https://
iOS
capsule controls · field 8 · card 12 · SF Pro · 44 pt
https://
Android
Material 3 stadium · field 4 · card 12 · Roboto · 48 dp

Usage

<Input placeholder="rachel.chen@example.com" />
On the web the eye shows what pressing it does: the open eye while the value is masked, the struck-through eye once it is revealed. A field held focused by an InteractionOverride (a docs specimen) draws the web's 1.5px accent caret, blinking once a second, just after its value, since no real caret shows there.
shortcut shows a keyboard shortcut hint at the field's end, the key that focuses a search field: a compact flat keycap (<Kbd small flat>, the 22 px cap; tiny, the 20 px cap, on a small field) after the value and any inline suffix and before the trailing glyphs, 8 px from the field's end and 10 px from the value (8 on a small field). It takes the keys as Kbd's keys does: "⌘K" is one cap, "⌘ K" two. It is a hint only; bind the key yourself.
Pass label (and required) to name the field: iOS and web render the label above the control, while Android floats the Material 3 in-container label. On Android the field grows with the user's text size so the floated label never meets the value, and a label longer than the field truncates on one line inside it while the field's accessible name stays the whole label. The required star is decorative: a screen reader hears the field as required, from aria-required on the web and from its name ("Full name, required") on iOS and Android. A field fills the parent it is given; a step of its own (xs, lg, …, with start to pin it to the leading edge) or a Container step sets its measure. Select and the search field share its look, and Field and Form compose that label with helper and error text. On iOS the field is the native text field in Canvas's colors: a card-colored box with a hairline, a muted title above, a glyph that tints with focus and error, and in solid mode an error wash. Under glass a wash would cost the field's ink its contrast over the material, so the iOS field takes none (the web's field a trace in dark only), and the error border, the tinted glyph and a Field's message carry the state. A prefix or suffix addon's fill is held to the same bar: under glass it is only as dense as keeps its text at 4.5:1 over the field, so in the browser's light palettes and on the iOS field in dark it is a faint trace.

Tokens

Read from the playground render. Values follow the scheme and the ion hue.
--bg2
--fd
--ft
--ln2
--tx
--tx2

Related components