Text Field

A native editable field with look-specific styling.

This page describes the SDK control. Code uses the Radix Look; builders use the ambient Look or built-in fallback.

Try it

Interact with the control below. This preview runs the exact code sample shown on this page.

Open example separately ↗

Create it

Radix · integration snippet
use gpui::{Context};
use xgpui_luma_look_radix as radix;

struct Example {
    control: xgpui_luma::controls::textfield::TextField,
    name: String,
}

impl Example {
    fn new(cx: &mut Context<Self>) -> Self {
        let control = radix::TextField::new("name")
            .on_value_changed(cx, |app, value, cx| {
                app.name = value.clone();
                cx.notify();
            })
            .spawn(cx);

        Self { control, name: String::new() }
    }
}

Checked against the current SDK and Radix crates. The control retains its callbacks; callback owners are held weakly. Render self.control.clone() in its view.

Customize & handle input

Inspect the builder for value, validation, and event options. Text fields have a dedicated template contract; do not copy Button template assumptions.

SDK exports · Radix builder

Events

Callbacks follow the existing SDK event stream. Registrations append, hold the owner weakly, and live until the control is released. cx.notify() requests an owner redraw. Compound payloads are borrowed; scalar values are passed by value.

Event / payloadCallback
Change { value: String }.on_value_changed(cx, |app, value, cx| { … })
Submit { value: String }.on_submit(cx, |app, value, cx| { … })
FocusChanged { focused: bool }.on_focus_changed(cx, |app, focused, cx| { … })
EnabledChanged { enabled: bool }.on_enabled_changed(cx, |app, enabled, cx| { … })

Use .on_event(cx, |app, event, cx| { … }) for all events. Factory-created controls support the same callbacks through TextFieldEventExt. Existing cx.subscribe observers remain supported.