Input
Input is a pure-GPUI, IME-capable single-line text input. Editing state lives in an Entity<InputState> owned by the caller; there is no Root, Provider, or registration step.
Basic usage
Basic contains only a stable ID, state, placeholder, and accessible name.
Input types
Search
InputType::Search provides search semantics. The search icon, clear action, and Enter submission are composed explicitly from existing capabilities.
Password
Password masks each grapheme with a fixed character by default. The host controls reveal state, while Eye/EyeOff IconButton supplies a state-dependent accessible name, Tooltip, and selected/toggled semantics.
Hidden passwords allow paste but block copy and cut; revealing restores ordinary copy and cut. Toggling reveal never changes the real value, selection, IME state, or undo history, and never emits Changed. Both states retain PasswordInput semantics.
Email, Phone, and Url
These types only provide the correct semantics. They do not validate, format, or filter characters; business validation remains a host responsibility.
InputType | AccessKit role | Additional behavior |
|---|---|---|
Text | TextInput | Default plain single-line text. |
Search | SearchInput | Adds no icon, clear action, or submit logic automatically. |
Password | PasswordInput | Secure masking by default; controlled reveal is available. |
Email | EmailInput | No automatic email validation. |
Phone | PhoneNumberInput | No automatic formatting or filtering. |
Url | UrlInput | No automatic URL validation. |
Composition
Prefix, suffix, and clear
The three capabilities remain independent. Slot children keep their own roles, focus, and events. InputClear reuses IconButton and requires an accessible name.
Input group
Place a same-sized Button in attached_suffix to create one outer frame, a full-height action area, and a themed divider.
Appearance and state
Outline is the default full border, Filled uses a filled surface, Borderless retains focus and error feedback, and Underline only draws the bottom edge.
ComponentSize::{Xs, Sm, Md, Lg} uses heights of 24, 32, 36, and 40 px. Input fills available width by default while its text viewport can shrink and scroll horizontally.
The host supplies invalid, read_only, and disabled. Disabled editors leave the normal Tab order and reject input, selection, and SetValue. Read-only editors remain focusable and allow ordinary text selection and copy, but reject edits.
IME and semantic events
InputState::value() always returns the real value. User input, deletion, revealed cut, paste, undo, redo, IME commit, and built-in clear emit one Changed only when the value changes; IME preedit stays silent. Enter emits Submitted outside composition. Programmatic set_value, clear, and reset do not emit user semantic events.
set_value synchronizes a host-owned authoritative value. An actual value change ends composition and clears stale undo/redo history, so later undo cannot cross that external synchronization boundary. clear follows the same rule; reset additionally resets selection, composition, scrolling, and layout caches. UTF-16 selections returned by an IME are normalized against the complete updated value at grapheme boundaries.
Keyboard and accessibility
- Arrow keys move by grapheme; platform word modifiers move by word. Home/End, Shift selection, Backspace/Delete, Select All, and Undo/Redo are supported.
- macOS uses Option+Backspace/Delete for word deletion and Command+Backspace/Delete for deletion to the start/end of the line. Windows and Linux retain their existing Control-modifier conventions.
- Only documented modifier combinations are consumed; unknown combinations continue bubbling.
- The actual editor node uses the matching
InputTyperole. Prefix, suffix, and attached suffix keep separate accessibility subtrees. - AccessKit exposes the same extended-grapheme selectable units as the editor, so ZWJ emoji and combining sequences have no internal caret stops.
- A hidden password's painted text, accessibility value, and synthetic text runs contain masks only, never plaintext.
API
| API | Description |
|---|---|
Input::new(id, Entity<InputState>) | Binds a stable ID to caller-owned editing state. |
input_type(InputType) | Selects Text, Search, Password, Email, Phone, or Url semantics. |
password_revealed(bool) | Controlled Password reveal state; defaults to false and is ignored by other types. |
placeholder, aria_label, aria_description | Text and accessibility metadata. |
variant, size, caret_color | Visual configuration. |
disabled, read_only, invalid | Externally supplied state. |
prefix, suffix, attached_suffix, clearable | Composition slots and built-in clear. |
on_change, on_submit, on_focus, on_blur | Semantic callbacks and Entity-bound _in forms. |
Input implements Changeable<SharedString>, Focusable, Disableable, and Sizable, but not Clickable.
Themes, responsive behavior, and platforms
Light, Dark, and System resolve borders, surfaces, text, placeholder, selection, caret, and state colors through the active theme. Input shrinks within available width, while excessive slot width reduces the editor area. GPUI supplies cross-platform text and IME behavior; command modifiers follow macOS and Windows/Linux conventions.
Custom themes must now provide and validate every Input token when ResolvedTheme::from_tokens constructs the theme. Missing keys, wrong types, and invalid references return ThemeError; legacy theme fallback has been removed. Migrate custom themes by supplying all four variants, seven visual states, and four sizes, then replace string access with infallible input_state(InputVariantKind, InputVisualState) and input_size(ThemeSize) calls.
Performance contract
- Normal scales: 64KiB and 1MiB; 16MiB is stress scale.
- Goals: ≤4ms update+draw at 64KiB and ≤16.67ms at 1MiB. The 16MiB case must remain linear and avoid OOM, but need not complete in one frame.
- Equal-size programmatic replacement clears undo/redo and retains no old value. Normal text paint shapes at most a 64KiB window containing the active target; AccessKit text runs use bounded streaming chunks.
- The allocated-bytes target is at most 8× input size. The current complete 1MiB update+draw allocates about 1.74MB; see root
PERFORMANCE.md. - Benchmarks:
input/state,input/render, andinput/interaction_and_draw; see the Benchmark Guide.
Known limitations
- Input is single-line plain text only; there is no multiline, Number, Date, Time, mask template, or built-in validation message.
- Email, Phone, and Url promise no automatic validation; Password has no custom mask-character API.
- The host owns slot business state, loading, and error handling.
- Web previews require browser WebGPU and the font asset supplied by the documentation host.