Button
Button is the focusable, message-emitting component for actions. ButtonWidget is the stateless paint-only layer used by the component and available for direct Ratatui rendering.
Focus the demo, use Tab to move between buttons, press Enter or Space to press a button, and press Alt+T to choose a bundled theme.
Interactive Component
Use Button inside a View. It holds no UI state. Disabled state is read from your app state through .disabled(...); pressing emits the configured message.
use ratcn::{Button, ButtonVariant};
use ratcn::view::View;
View::new("root")
.focus(|s: &AppState| &s.focus, Msg::FocusChanged)
.theme(|s: &AppState| &s.theme)
.child("save", Button::new("Save").on_press(Msg::Save))
.child(
"delete",
Button::new("Delete")
.variant(ButtonVariant::Destructive)
.disabled(|s: &AppState| !s.can_delete)
.on_press(Msg::Delete),
)
.content(|frame, _state, view| {
view.render_child(frame, "save", save_area);
view.render_child(frame, "delete", delete_area);
});Button API
Button::new(label): Creates a focusable button with the default variant..on_press(msg): Emitsmsgon unmodified Enter or Space..disabled(|state| ...): Renders disabled, ignores presses, and leaves Tab traversal while the predicate is true..variant(ButtonVariant::...): Sets the visual variant explicitly..default(): Shortcut forButtonVariant::Default..outline(): Shortcut forButtonVariant::Outline..secondary(): Shortcut forButtonVariant::Secondary..ghost(): Shortcut forButtonVariant::Ghost..destructive(): Shortcut forButtonVariant::Destructive..width(): Returns the natural width, useful when building layout constraints.
Events
Button handles unmodified Enter and Space. If .on_press(...) is configured, the button emits that message. Without .on_press(...), the press is consumed without emitting. Modified keys and disabled buttons are ignored.
Variants
ButtonVariant has five values: Default, Outline, Secondary, Ghost, and Destructive. Variants are theme-derived, so the same button adapts to terminal, dark, and light palettes.
Paint Widget
Use ButtonWidget when you only need rendering.
use ratcn::{ButtonWidget, Theme};
let theme = Theme::terminal();
frame.render_widget(
ButtonWidget::new("Save")
.secondary()
.themed(&theme)
.focused(is_focused)
.disabled(is_disabled),
area,
);| Method | Description |
|---|---|
ButtonWidget::new(label) | Creates a paint-only button. |
.themed(&theme) | Applies a theme-derived ButtonStyle for the current variant. |
.variant(...), .default(), .outline(), .secondary(), .ghost(), .destructive() | Choose the visual variant. |
.style(ButtonStyle) | Uses an explicit style instead of a theme-derived one. |
.focused(bool) | Draws focused styling. |
.is_focused() | Returns whether focused styling is enabled. |
.disabled(bool) | Draws disabled styling. |
.is_disabled() | Returns whether disabled styling is enabled. |
.width() | Returns label width plus padding. |
ButtonWidget::HEIGHT is 3; ButtonWidget::DEFAULT_GAP is the spacing used by the demos for button rows.