Textarea

Textarea is the styled control for ordinary multi-line text. Use Input for a single line and Editor for source code.

#Import

use gpui_kit::component::input::{Textarea, TextareaState};

#Basic usage

let notes = cx.new(|cx| {
    TextareaState::new(window, cx)
        .rows(5)
        .placeholder("Notes")
});

Textarea::new(&notes)

#Auto-grow

let message = cx.new(|cx| {
    TextareaState::new(window, cx)
        .auto_grow(2, 8)
        .placeholder("Write a message")
});

Textarea::new(&message)

The control grows until max_rows; overflowing content then scrolls.

#Value and events

let value = notes.read(cx).value();

notes.update(cx, |state, cx| {
    state.set_value("Updated notes", window, cx);
});

cx.subscribe(&notes, |this, state, event: &InputEvent, cx| {
    if matches!(event, InputEvent::Change) {
        this.notes = state.read(cx).value();
        cx.notify();
    }
});

insert, replace, cursor_position, soft_wrap, searchable, and submit_on_enter are available on TextareaState.

#Appearance

Textarea::new(&notes)
    .h(px(160.))
    .bordered(true)
    .disabled(false)
    .readonly(false)
    .aria_label("Notes")

Unlike disabled, a read-only textarea keeps the normal appearance and still can be focused, selected and copied, it only rejects the changes made by the user.

Textarea deliberately does not expose Input-only adornments such as prefix, suffix, mask toggle, or the clear button. Compose related actions beside the textarea.

#Atomic inline tokens

Use tokens to include mentions, file references or commands in a multi-line message. Insert a token with TextareaState::replace_with_token, or restore a saved draft with set_value. The default label is ready to use; add a renderer when you want an icon or other custom content:

Textarea::new(&state)
    .token(|token, _, _| InputToken::new(token).icon(IconName::File))

Import InputToken from gpui_kit::component::input and IconName from gpui_kit::component. A token wraps onto the next line as a whole, and auto-grow adjusts the textarea height to fit. Put line breaks in the text between tokens. See Input: atomic inline tokens for editing, activation, draft persistence, mode restrictions and JavaScript APIs.