From 32df9256c3fbcf4ba63c0f5291dd666f8c93827f Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Mon, 23 Jun 2025 19:55:21 -0300 Subject: [PATCH] notification: Add built-in dismiss button in the Status Toast component (#33278) There may be cases where we're needing to pass a button just so it is dismissible, so I figured this out help! It also helps when you want to have two buttons, one to perform an action and another to dismiss and cancel. Release Notes: - N/A --- crates/notifications/src/status_toast.rs | 40 ++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/crates/notifications/src/status_toast.rs b/crates/notifications/src/status_toast.rs index 446b3a60f9..ffd87e0b8b 100644 --- a/crates/notifications/src/status_toast.rs +++ b/crates/notifications/src/status_toast.rs @@ -39,6 +39,7 @@ pub struct StatusToast { icon: Option, text: SharedString, action: Option, + show_dismiss: bool, this_handle: Entity, focus_handle: FocusHandle, } @@ -57,6 +58,7 @@ impl StatusToast { text: text.into(), icon: None, action: None, + show_dismiss: false, this_handle: cx.entity(), focus_handle, }, @@ -87,20 +89,33 @@ impl StatusToast { )); self } + + pub fn dismiss_button(mut self, show: bool) -> Self { + self.show_dismiss = show; + self + } } impl Render for StatusToast { fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { + let has_action_or_dismiss = self.action.is_some() || self.show_dismiss; + h_flex() .id("status-toast") .elevation_3(cx) .gap_2() .py_1p5() - .px_2p5() + .pl_2p5() + .map(|this| { + if has_action_or_dismiss { + this.pr_1p5() + } else { + this.pr_2p5() + } + }) .flex_none() .bg(cx.theme().colors().surface_background) .shadow_lg() - .items_center() .when_some(self.icon.as_ref(), |this, icon| { this.child(Icon::new(icon.icon).color(icon.color)) }) @@ -118,6 +133,20 @@ impl Render for StatusToast { }), ) }) + .when(self.show_dismiss, |this| { + let handle = self.this_handle.clone(); + this.child( + IconButton::new("dismiss", IconName::Close) + .icon_size(IconSize::XSmall) + .icon_color(Color::Muted) + .tooltip(Tooltip::text("Dismiss")) + .on_click(move |_click_event, _window, cx| { + handle.update(cx, |_, cx| { + cx.emit(DismissEvent); + }); + }), + ) + }) } } @@ -147,6 +176,9 @@ impl Component for StatusToast { this.action("Restart", |_, _| {}) }); + let dismiss_button_example = + StatusToast::new("Dismiss Button", cx, |this, _| this.dismiss_button(true)); + let icon_example = StatusToast::new( "Nathan Sobo accepted your contact request", cx, @@ -193,6 +225,10 @@ impl Component for StatusToast { div().child(action_example).into_any_element(), ), single_example("Icon", div().child(icon_example).into_any_element()), + single_example( + "Dismiss Button", + div().child(dismiss_button_example).into_any_element(), + ), ], ), example_group_with_title(