Input
Takes one line of text, like a name, a key, a number or a code.
Examples
Hidden, ending in a1b2
Hides again 30 seconds after you show it.
Shift moves ten times as far.
Six digits. Paste works.
Mode
textdefault
password
- Hidden, ending in a1b2
secret
copy
search
number
- Code
otp
Sizes
sm
defaultdefault
lg
States
rest
hover
focus-visible
invalid
disabled
read-only
Usage
When to use it
- Use
- The answer fits on one line: a name, email, URL, ID or amount.
- Use
- The value is a secret the person pastes or reads once: a widget key, webhook secret or password.
- Use
- The person filters a list that is already on the page.
- Use
- A short code arrives by message or from an authenticator app.
- Not for
- The answer runs to more than one line. Use Textarea.
- Not for
- The person picks from more than about seven options, or adds several values. Use Combobox.
- Not for
- The value is a date, a range or a time. Use Date picker.
- Not for
- The value is on or off and applies at once. Use Switch.
- Not for
- The search covers the whole product, not this list. Use Command.
Rules
12 rules
- Must
- Put an Input that takes typed text in a Field with a FieldLabel, not a placeholder or a loose label. Because a placeholder vanishes on the first keystroke and is not a reliable accessible name.
- Must
- Use mode="secret" for a credential, token or key, never type="password". A masked key keeps its length: one dot per hidden character. Because type="password" hides the tail that tells two keys apart, offers no copy, and invites the password manager to save it.
- Must
- Pass an icon, scheme, unit or button as prefix or suffix, never beside the Input. Because outside the box the icon sits outside the edge that darkens on hover and turns ink on focus, and a click on it does not focus the text.
- Must
- Use mode="search" for a search box, never an icon and an input in a relative wrapper. Because a hand-placed icon misses the clear button, Escape to clear and the shortcut hint.
- Must
- Give shortcut to one search per page; pass shortcutOwner={false} on others to show the hint only. Because only the first claiming field in document order gets the key, so a second claim does nothing.
- Should
- Set step="auto" on a number that spans more than two orders of magnitude.
- Must
- Use generate on a password field so the generated value is revealed. Because a value set by hand stays masked with autoComplete="current-password", so the person never sees what to save.
- Must
- Set type and autoComplete for email, url and tel, or use mode="otp" for a one-time code. Because without type a phone shows the text keyboard and autofill cannot offer the address.
- Should
- Give the placeholder an example value in the expected format, not the label again.
- Should
- Pass noun on a secret or copy field so its buttons read "Show widget key" and "Copy widget key".
- Never
- Add a border or change the text size on an Input. Because the box draws its own edge and its ink focus, and text-xs drops the 16px touch size that stops iOS zoom.
- Should
- Keep an Input at least 160px wide and stack the row under 320px.
Accessibility
7 checks
- The control is a native textbox named by FieldLabel or aria-label, with aria-invalid and aria-describedby from the Field.
- Number is a spinbutton with aria-valuetext including the unit; steppers are named with the step and skipped by Tab.
- The reveal toggle sets aria-pressed; a hidden secret is described as "Hidden, ending in" the last characters.
- OTP slots name the first from the label and the rest "Character n of 6"; a rejected key is announced in a status region.
- Escape in a search clears the query; a second Escape leaves the field.
- Text is 16px under pointer: coarse so iOS does not zoom; never set a smaller size.
- Forced colors draw a 1px system border on the box; the focus edge stays.
Edge cases
11 edge cases
- Long value
- Scrolls inside the box; copy truncates and still copies all; a read-only secret keeps its start and tail.
- Empty copy value
- Reads "None" with Copy disabled; an empty read-only secret drops its buttons.
- 120px wide
- Search keeps icon and shortcut; a number shrinks its unit before its digits.
- Right to left
- Prefix and suffix swap sides; wrap Latin pieces in bdi dir="ltr".
- Slow search
- The spinner stays in the prefix and the box keeps its size; the caller owns the timeout.
- In a well
- Stays paper with its control edge, so it reads on the grey.
- Letter typed in numeric OTP
- Refused and announced as "Digits only".
- Number out of range
- Clamps when stepped; a typed value clamps on blur.
- Stepper pressed ten times
- Adds exactly ten steps from the typed number.
- Enter inside a form
- Submits the form; no button in the field submits it.
- Reduced motion
- The search spinner stops and stays visible.
API
10 props
mode'text' | 'password' | 'secret' | 'copy' | 'search' | 'number' | 'otp'default'text'size'sm' | 'default' | 'lg'default'default'prefix, suffixReactNodeclassNamestringgenerateboolean | () => stringnoun, readOnly, redacted, tailstring, boolean, boolean, numberdefault'value', false, false, 4value, copyLabel, onCopystring, string, (v) => voidshortcut, shortcutOwner, pendingstring, boolean, booleandefault, true, falsemin, max, step, unitnumber, number, number | 'auto', ReactNodelength, groups, onCompletenumber, number[], (v) => void
Tokens
23 tokens
--line-control- oklch(var(--ink-c) / 0.16)
--radius-soft- 6px
--text-1- var(--ink)
--type-label- 400 14px/16px var(--font-sans)
--control-sm- 28px
--control- 32px
--control-lg- 44px
--line-frame- oklch(var(--ink-c) / var(--line-frame-alpha))
--dur-fast- 120ms
--ease-step- cubic-bezier(0.2, 0, 0, 1)
--line-focus- 2px
--focus-halo- 0 0 0 3px oklch(var(--ink-c) / 0.08)
--border-focus- var(--ink)
--focus-offset- 2px
--accent-line- var(--ink)
--accent-mark- var(--ink)
--text-disabled- oklch(var(--ink-c) / 0.40)
--text-3- oklch(var(--ink-c) / 0.66)
--text-2- oklch(var(--ink-c) / 0.80)
--type-code- 400 13px/20px var(--font-mono)
--features-data- "tnum", "zero", "ss04"
--type-label-sm- 400 12px/16px var(--font-sans)
--type-heading-sm- 400 20px/24px var(--font-sans)