diff --git a/crates/story/src/notification_story.rs b/crates/story/src/notification_story.rs index c780df92..cac6e5ee 100644 --- a/crates/story/src/notification_story.rs +++ b/crates/story/src/notification_story.rs @@ -147,7 +147,7 @@ impl Render for NotificationStory { .title("Uh oh! Something went wrong.") .message("There was a problem with your request.") .autohide(false) - .action(|_, cx| { + .action(|_, _, cx| { Button::new("try-again").primary().label("Retry").on_click( cx.listener(|this, _, window, cx| { println!("You have clicked the try again action."); @@ -171,7 +171,7 @@ impl Render for NotificationStory { .label("Show Custom Notification") .on_click(cx.listener(|_, _, window, cx| { window.push_notification( - Notification::new().content(|window, cx| { + Notification::new().content(|_, window, cx| { TextView::markdown( "notification-markdown", NOTIFICATION_MARKDOWN, diff --git a/crates/ui/src/notification.rs b/crates/ui/src/notification.rs index 2f9cc833..5a16b2dc 100644 --- a/crates/ui/src/notification.rs +++ b/crates/ui/src/notification.rs @@ -70,8 +70,8 @@ pub struct Notification { message: Option, icon: Option, autohide: bool, - action_builder: Option) -> Button>>, - content_builder: Option) -> AnyElement>>, + action_builder: Option) -> Button>>, + content_builder: Option) -> AnyElement>>, on_click: Option>, closing: bool, } @@ -110,6 +110,8 @@ struct DefaultIdType; impl Notification { /// Create a new notification. + /// + /// The default id is a random UUID. pub fn new() -> Self { let id: SharedString = uuid::Uuid::new_v4().to_string().into(); let id = (TypeId::of::(), id.into()); @@ -220,7 +222,7 @@ impl Notification { /// Set the action button of the notification. pub fn action(mut self, action: F) -> Self where - F: Fn(&mut Window, &mut Context) -> Button + 'static, + F: Fn(&mut Self, &mut Window, &mut Context) -> Button + 'static, { self.action_builder = Some(Rc::new(action)); self @@ -249,7 +251,7 @@ impl Notification { /// Set the content of the notification. pub fn content( mut self, - content: impl Fn(&mut Window, &mut Context) -> AnyElement + 'static, + content: impl Fn(&mut Self, &mut Window, &mut Context) -> AnyElement + 'static, ) -> Self { self.content_builder = Some(Rc::new(content)); self @@ -301,11 +303,11 @@ impl Render for Notification { this.child(div().text_sm().child(message)) }) .when_some(self.content_builder.clone(), |this, child_builder| { - this.child(child_builder(window, cx)) + this.child(child_builder(self, window, cx)) }), ) .when_some(self.action_builder.clone(), |this, action_builder| { - this.child(action_builder(window, cx).small().mr_3p5()) + this.child(action_builder(self, window, cx).small().mr_3p5()) }) .when_some(self.on_click.clone(), |this, on_click| { this.on_click(cx.listener(move |view, event, window, cx| { diff --git a/docs/docs/components/notification.md b/docs/docs/components/notification.md index c8508b4e..c83664ac 100644 --- a/docs/docs/components/notification.md +++ b/docs/docs/components/notification.md @@ -155,7 +155,7 @@ let markdown_content = r#" "#; Notification::new() - .content(|window, cx| { + .content(|_, window, cx| { TextView::markdown( "custom-content", markdown_content, @@ -168,6 +168,14 @@ Notification::new() ### Unique Notifications +When you need to manage notifications manually, such as for long-running processes or persistent alerts, you can use unique IDs to push and remove notifications as needed. + +In this case, you can create a special `struct` in local scope, and use `id` methods with this struct to identify the notification. + +Then you can push the notification when needed, and later remove it using the same ID. + +Like this: + ```rust // Using type-based ID for uniqueness struct UpdateNotification; @@ -185,70 +193,13 @@ Notification::warning("Task failed to complete") .title("Task Failed") ``` -### Manual Notification Management +Then remove the notification with `window.remove_notification::`, like this: ```rust -// Show persistent notification -struct PersistentNotification; - -window.push_notification( - Notification::new() - .id::() - .message("Background process running...") - .autohide(false), - cx, -); - // Later, dismiss the notification -window.remove_notification::(cx); +window.remove_notification::(cx); ``` -## API Reference - -### Notification Methods - -| Method | Description | -| --------------------- | -------------------------------------------------------- | -| `new()` | Create a new notification with default settings | -| `info(message)` | Create an info notification with blue styling | -| `success(message)` | Create a success notification with green styling | -| `warning(message)` | Create a warning notification with yellow/orange styling | -| `error(message)` | Create an error notification with red styling | -| `message(text)` | Set the notification message content | -| `title(text)` | Set the notification title (appears above message) | -| `with_type(type)` | Set the notification type for styling and icon | -| `icon(icon)` | Set a custom icon (overrides type default icon) | -| `autohide(bool)` | Control auto-dismiss behavior (default: true) | -| `id()` | Set unique type-based ID for notification | -| `id1(key)` | Set unique type + element ID for notification | -| `on_click(callback)` | Set click handler for the notification | -| `action(builder)` | Add an action button to the notification | -| `content(builder)` | Set custom content instead of title/message | -| `dismiss(window, cx)` | Manually dismiss the notification | - -### NotificationType Variants - -| Type | Description | Default Icon | Theme Color | -| --------- | ---------------------- | ------------- | ------------- | -| `Info` | Informational messages | Info | Blue | -| `Success` | Success confirmations | CircleCheck | Green | -| `Warning` | Warning messages | TriangleAlert | Yellow/Orange | -| `Error` | Error messages | CircleX | Red | - -### Window Extensions - -| Method | Description | -| -------------------------------------------- | --------------------------- | -| `window.push_notification(notification, cx)` | Show a notification | -| `window.remove_notification::(cx)` | Remove notification by type | - -### Auto-hide Behavior - -- **Default timeout**: 5 seconds -- **Auto-hide enabled**: Notification dismisses automatically -- **Auto-hide disabled**: Notification persists until manually closed -- **Hover interaction**: Auto-hide pauses while hovering over notification area - ## Examples ### Form Validation Error @@ -257,7 +208,7 @@ window.remove_notification::(cx); Notification::error("Please correct the following errors before submitting.") .title("Validation Failed") .autohide(false) - .action(|_, cx| { + .action(|_, _, cx| { Button::new("review") .outline() .label("Review Form")