Preview
Loading GPUI
Props
Variants
It fails sometimes
When the returned future resolves to Err, the button drops into its error state.
Loading GPUI
MorphStatusButton::new("deploy")
.label("Deploy")
.on_click_async(|_, _, cx| {
let work = cx.background_executor().timer(Duration::from_millis(1200));
async move {
work.await;
Err::<(), ()>(())
}
})Install
cargo add evilbuttonsUsage
use evilbuttons::MorphStatusButton;
use gpui::{div, prelude::*, Context, IntoElement, Render, Window};
struct ButtonDemo;
impl Render for ButtonDemo {
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
div().child(
MorphStatusButton::new("save")
.label("Save changes")
.success_label("Saved")
.on_click_async(|_, _, cx| {
let save = save_changes(cx);
async move { save.await }
}),
)
}
}MorphStatusButton::new("save")
.label("Save changes")
.status(if is_pending {
MorphStatusButtonStatus::Loading
} else {
MorphStatusButtonStatus::Idle
})Props
MorphStatusButton is a GPUI RenderOnce builder; its status is keyed by id.
| Method | Type | Default | Description |
|---|---|---|---|
new(id) | impl Into<ElementId> | - | Unique id for the button state. |
label(s) | impl Into<SharedString> | "Save changes" | Idle label. |
loading_label(s) | impl Into<SharedString> | "Working…" | Label shown while the action is in flight. |
success_label(s) | impl Into<SharedString> | "Done" | Label shown after the action succeeds. |
error_label(s) | impl Into<SharedString> | "It broke. Your fault." | Label shown after the action fails. |
on_click_async(f) | Fn(&ClickEvent, &mut Window, &mut App) -> impl Future<Output = Result<T, E>> | - | Async click handler. The returned future drives the auto state machine: loading, then success (Ok) or error (Err). |
on_click(f) | Fn(&ClickEvent, &mut Window, &mut App) | - | Plain click handler; doesn't change the status. |
status(s) | MorphStatusButtonStatus | - | Controlled status (Idle, Loading, Success, Error); disables the async auto-transitions when set. |
reset_after(d) | Duration | 1800ms | How long to stay in success/error before resetting. Duration::ZERO stays. |
disabled(bool) | bool | false | Dims the button and ignores input. |
Good to know
- Return a future from
on_click_asyncand it shows loading, then success or error. - Clicks are ignored while loading, and the button stops reacting to hover and press.
- The widest label reserves the width, so swapping labels never reflows the layout.