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
This commit is contained in:
Danilo Leal 2025-06-23 19:55:21 -03:00 committed by GitHub
parent 36eebb7ba8
commit 32df9256c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -39,6 +39,7 @@ pub struct StatusToast {
icon: Option<ToastIcon>,
text: SharedString,
action: Option<ToastAction>,
show_dismiss: bool,
this_handle: Entity<Self>,
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<Self>) -> 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(