Input
Takes one line of text.
Mode
textdefault
password
search
copy
Sizes
sm
defaultdefault
lg
States
rest
hover
focus
filled
invalid
disabled
read-only
Usage
When to use it
- Use
- The answer fits on one line: a name, an email, a URL, a bucket path, a limit.
- Use
- The person filters a list already on the page (mode="search").
- Use
- The person reads a value to paste elsewhere, like an endpoint or a connection string (mode="copy").
- Not for
- The answer runs to more than one line, like a query or a note. Use Textarea.
- Not for
- The value is one of a known list. Use Select.
- Not for
- The value is on or off and applies at once. Use Switch.
Rules
10 rules
- Must
- Put an Input in a Field with a FieldLabel, or give it aria-label when a visible label sits elsewhere. Because a placeholder vanishes on the first keystroke and is not a reliable accessible name.
- Must
- Pass an icon, a scheme, a unit or a button as leading or trailing, never beside the Input. Because outside the edge it sits outside the line that turns gold on focus, and a press on it does not put the cursor in the text.
- Must
- Use InputAction for a button inside the field; it is a cell of the field, its full height and flush with the edge. Because a plain Button keeps its own height and edge, so it floats inside the field with a double line beside it.
- Must
- Give a primary InputAction only to a field that is a whole one-line form, with no other slab beside it. Because the slab at the field's end is the group's one action, and a second one next to it splits the eye.
- Never
- Draw a ring, an outline or a shadow on an Input to show focus. Because the field draws its own focus, a white body with the gold edge doubled inward and a 1px pale yellow halo, and a second ring outside it reads as another box.
- Never
- Set an Input's height, corners, text size or side padding in className; pass size. Because corners are square, a fixed height clips at 200% zoom, and the size sets the inset so the nearest thing you see sits as far from the side as from the top: text 10px in at 32px, a glyph 7px, a key cap 5px, measured.
- Must
- Set mono on a field that holds an ID, a key, a path or a command; leave names and emails in the sans. Because mono keeps every character the same width, so 0 and O, l and 1 are told apart, while a name in mono reads as code.
- Must
- Use mode="search" for a search box, never an icon placed over an input. Because a hand-placed icon misses the clear button, Escape to clear, the pending mark and the key hint.
- Must
- Give shortcut to one search per page; pass shortcutOwner={false} on another that only shows the hint. Because only the first claiming field in document order gets the key, so a second claim does nothing.
- Should
- Set type and autoComplete on an email, a URL or a phone number. Because without type a phone shows the text keyboard and autofill cannot offer the address.
State order
6 states, highest first
- 1
- disabled
- 2
- invalid
- 3
- focus
- 4
- read-only
- 5
- hover
- 6
- rest
Accessibility
6 checks
- The control is a native textbox named by FieldLabel or aria-label, with aria-invalid and aria-describedby from the Field.
- The edge is --line, the rule colour, 1.3:1 on the page, so the label, the placeholder and the off-white fill identify the field; focus turns it --focus at 2px, 6.2:1 in light and 12.9:1 in dark, with a pale halo outside, and forced colours draw a Highlight outline.
- Invalid adds the error sentence under the field, so it never rests on the red edge alone.
- The password toggle sets aria-pressed and names itself Show or Hide; its glyph changes with it.
- Escape in a search clears the query; a second Escape leaves the field. The key hint is aria-hidden.
- Text is 16px under a coarse pointer, so a phone browser never zooms the page on focus.
Keyboard
3 keys
- Escape
- In a search, clears the query; with no query, leaves the field.
- / (or the shortcut)
- Focuses the search that owns it, from anywhere outside a field, dialog or menu.
- Enter
- Submits the form around it.
Edge cases
6 edge cases
- Long value
- Scrolls inside the field; a copy value truncates and still copies all of it.
- Narrow row, 160px
- The text shrinks before any slot; slots and actions keep their size.
- Right to left
- Leading and trailing swap sides; a scheme like https:// keeps its own order.
- Zoom 200%
- The field grows with the text past its token, and its action cells grow with it.
- Slow search
- The magnifier turns into the pending mark in the same width, so the text never moves.
- Disabled Field or FieldSet
- The text, the slots and every action inside go quiet together.
API
10 props
mode'text' | 'password' | 'search' | 'copy'default'text'size'sm' | 'default' | 'lg'default'default'leading, trailingReactNodemonobooleandefaultfalsearia-invalidbooleanclassName, controlClassNamestringdefaultRevealedbooleandefaultfalseshortcut, shortcutOwner, pending, clearLabelstring, boolean, boolean, stringdefault, true, false, 'Clear search'value, noun, onCopystring, string, (v) => voidInputAction size, variant'icon' | 'text', 'ghost' | 'primary'default'icon', 'ghost'
Tokens
32 tokens
--field-bg- #f8f7f3
--field-hover- #fefefd
--field-edge- var(--line)
--field-edge-hover- #ecebe5
--field-ring-hover- #f4f3ee
--field-focus-bg- #ffffff
--field-ring-focus- #fff1b8
--field-ring-fail- #fbdcd8
--field-inset-sm- 7px
--field-inset- 10px
--field-inset-lg- 11px
--well- #f4f3ee
--focus- #7a5d00
--fail- #b3261e
--text-1- #161512
--text-2- #55524a
--text-3- #6b675e
--text-disabled- #a8a499
--control-sm- 26px
--control- 32px
--control-lg- 36px
--line-width- 1px
--type-body-sm- 400 14px/20px var(--font-sans)
--type-caption- 400 13px/18px var(--font-sans)
--type-body- 400 15px/24px var(--font-sans)
--type-code- 400 13px/20px var(--font-mono)
--type-code-sm- 400 12px/16px var(--font-mono)
--icon- 16px
--icon-sm- 14px
--pending-cell- 3px
--dur-light- 240ms
--ease-soft- cubic-bezier(0.22, 0.8, 0.24, 1)