Skip to content

Component TextInput

MeowLynxSea edited this page Feb 18, 2026 · 10 revisions

TextInput

Single-line text input.

TextInput owns cursor/selection state and is optimized for "uncontrolled" usage.

When to use

  • Forms and settings where users type short values (names, ids, paths)
  • Search bars (or use the higher-level SearchInput)

Not a good fit:

  • Multi-line input (use TextArea)

Example

use gpui::ElementId;
use yororen_ui::component::text_input;

let input = text_input()
    .key(ElementId::from((ElementId::from("settings"), "username")))
    .placeholder("Username")
    .on_change(|value, _window, _cx| {
        // value: SharedString
        // ...
    });

Notes

  • TextInput owns internal cursor/selection state, so stable key(...) is recommended in lists.

Controlling Input Value

.content() (Controlled)

Sets a persistent content value. The input will sync with external state on every render.

Use when:

  • You need the input value to always match external state
  • Loading a form with pre-filled data that should stay in sync

Avoid when:

  • User is actively typing (causes sync loops, cursor jumps, typing lag)
// OK: Initial value loading
let input = text_input()
    .content(saved_value)
    .on_change(|value, window, cx| { /* ... */ });

// Avoid: Continuous sync during typing
let input = text_input()
    .content(state_value)  // Don't do this if state_value updates on every keystroke
    .on_change(|value, window, cx| {
        state_value = value;  // Creates sync loop!
    });

.set_content() (One-time)

Sets content once programmatically without creating a sync loop.

Use when:

  • Clear button: reset input to empty after form submission
  • Initial load: set default value on first render
  • External action: populate input from saved data
// Clear after submission
let input = text_input()
    .on_submit(|value, window, cx| {
        // Submit logic...
    })
    .set_content("");  // Clear after submit

// Initial load
let input = text_input()
    .set_content(initial_value);  // Only applies once on first render

Summary

Method Sync Type Use Case
.content() Persistent Pre-filled forms, read-only displays
.set_content() One-time Clear button, initial load, reset

API

  • text_input(): constructor
  • id(...) / key(...): stable identity (recommended for keyed state management; auto-generated if not provided)
  • placeholder("...")
  • disabled(bool)
  • content(SharedString): controlled sync (see notes above)
  • set_content(SharedString): one-time set (see notes above)
  • max_length(usize): maximum number of characters allowed
  • on_change(|value, window, cx| ...)
  • on_submit(|value: SharedString, window: &mut gpui::Window, cx: &mut App| ...)
  • Styling: bg/border/focus_border/text_color/height

Defaults

  • Height: 36px
  • Placeholder: empty string

Notes

  • Relies on keyboard shortcuts registered during component library initialization (yororen_ui::component::init(cx)). No separate registration is needed for TextInput itself.

Clone this wiki locally