Skip to content

Input

A flexible text input component with support for validation, masking, prefix/suffix elements, and different states.

Import

rust
use gpui_component::input::{InputState, TextInput};

Usage

Basic Input

rust
let input = cx.new(|cx| InputState::new(window, cx));

TextInput::new(&input)

With Placeholder

rust
let input = cx.new(|cx|
    InputState::new(window, cx)
        .placeholder("Enter your name...")
);

TextInput::new(&input)

With Default Value

rust
let input = cx.new(|cx|
    InputState::new(window, cx)
        .default_value("John Doe")
);

TextInput::new(&input)

Cleanable Input

rust
TextInput::new(&input)
    .cleanable() // Shows clear button when input has value

With Prefix and Suffix

rust
use gpui_component::{Icon, IconName};

// With prefix icon
TextInput::new(&input)
    .prefix(Icon::new(IconName::Search).small())
    .cleanable()

// With suffix button
TextInput::new(&input)
    .suffix(
        Button::new("info")
            .ghost()
            .icon(IconName::Info)
            .xsmall()
    )

// With both
TextInput::new(&input)
    .prefix(Icon::new(IconName::Search).small())
    .suffix(Button::new("btn").ghost().icon(IconName::Info).xsmall())
    .cleanable()

Password Input (Masked)

rust
let input = cx.new(|cx|
    InputState::new(window, cx)
        .masked(true)
        .default_value("password123")
);

TextInput::new(&input)
    .mask_toggle() // Shows toggle button to reveal password

Input Sizes

rust
TextInput::new(&input).large()
TextInput::new(&input) // medium (default)
TextInput::new(&input).small()

Disabled Input

rust
TextInput::new(&input).disabled(true)

Clean on ESC

rust
let input = cx.new(|cx|
    InputState::new(window, cx)
        .clean_on_escape() // Clear input when ESC is pressed
);

TextInput::new(&input).cleanable()

Input Validation

rust
// Validate float numbers
let input = cx.new(|cx|
    InputState::new(window, cx)
        .validate(|s, _| s.parse::<f32>().is_ok())
);

// Regex pattern validation
let input = cx.new(|cx|
    InputState::new(window, cx)
        .pattern(regex::Regex::new(r"^[a-zA-Z0-9]*$").unwrap())
);

Input Masking

rust
// Phone number mask
let input = cx.new(|cx|
    InputState::new(window, cx)
        .mask_pattern("(999)-999-9999")
);

// Custom pattern: AAA-###-AAA (A=letter, #=digit, 9=digit optional)
let input = cx.new(|cx|
    InputState::new(window, cx)
        .mask_pattern("AAA-###-AAA")
);

// Number with thousands separator
use gpui_component::input::MaskPattern;

let input = cx.new(|cx|
    InputState::new(window, cx)
        .mask_pattern(MaskPattern::Number {
            separator: Some(','),
            fraction: Some(3),
        })
);

Handle Input Events

rust
let input = cx.new(|cx| InputState::new(window, cx));

cx.subscribe_in(&input, window, |view, state, event, window, cx| {
    match event {
        InputEvent::Change => {
            let text = state.read(cx).value();
            println!("Input changed: {}", text);
        }
        InputEvent::PressEnter { secondary } => {
            println!("Enter pressed, secondary: {}", secondary);
        }
        InputEvent::Focus => println!("Input focused"),
        InputEvent::Blur => println!("Input blurred"),
    }
});

Custom Appearance

rust
// Without default styling
TextInput::new(&input).appearance(false)

// Use in custom container
div()
    .border_b_2()
    .px_6()
    .py_3()
    .border_color(cx.theme().border)
    .bg(cx.theme().secondary)
    .child(TextInput::new(&input).appearance(false))

API Reference

InputState

MethodDescription
new(window, cx)Create a new input state
placeholder(str)Set placeholder text
default_value(str)Set initial value
masked(bool)Enable password masking
clean_on_escape()Clear on ESC key
validate(fn)Set validation function
pattern(regex)Set regex pattern for validation
mask_pattern(pattern)Set input mask pattern
value()Get current value
unmask_value()Get unmasked value (for masked inputs)
set_value(str, window, cx)Set input value programmatically
focus_handle(cx)Get focus handle

TextInput

MethodDescription
new(state)Create input with state entity
prefix(el)Add prefix element
suffix(el)Add suffix element
cleanable()Show clear button
mask_toggle()Show password toggle (for masked inputs)
disabled(bool)Set disabled state
appearance(bool)Enable/disable default styling
large()Large size
small()Small size

InputEvent

EventDescription
ChangeValue changed
PressEnter { secondary }Enter key pressed
FocusInput focused
BlurInput lost focus

MaskPattern

PatternDescription
StringPattern string (9=digit, A=letter, #=digit required)
Number { separator, fraction }Number with thousands separator

Examples

Search Input

rust
let search = cx.new(|cx|
    InputState::new(window, cx)
        .placeholder("Search...")
);

TextInput::new(&search)
    .prefix(Icon::new(IconName::Search).small())
    .cleanable()

Currency Input

rust
let amount = cx.new(|cx|
    InputState::new(window, cx)
        .mask_pattern(MaskPattern::Number {
            separator: Some(','),
            fraction: Some(2),
        })
);

div()
    .child(TextInput::new(&amount))
    .child(format!("Value: {}", amount.read(cx).value()))

Form with Multiple Inputs

rust
struct FormView {
    name_input: Entity<InputState>,
    email_input: Entity<InputState>,
}

v_flex()
    .gap_3()
    .child(TextInput::new(&self.name_input))
    .child(TextInput::new(&self.email_input))

Accessibility

  • Full keyboard navigation
  • Clear focus indicators
  • Placeholder announced by screen readers
  • ESC to clear (when enabled)
  • Enter to submit