Skip to main content

dioxus_bootstrap_css/
alert.rs

1use dioxus::prelude::*;
2
3use crate::types::Color;
4
5/// Bootstrap Alert component.
6///
7/// # Bootstrap HTML → Dioxus
8///
9/// | HTML | Dioxus |
10/// |---|---|
11/// | `<div class="alert alert-success">` | `Alert { color: Color::Success, "Text" }` |
12/// | `<div class="alert alert-danger alert-dismissible">` | `Alert { color: Color::Danger, dismissible: true, "Text" }` |
13///
14/// ```rust,no_run
15/// rsx! {
16///     Alert { color: Color::Success, "Operation completed!" }
17///     Alert { color: Color::Danger, dismissible: true,
18///         strong { "Error! " }
19///         "Something went wrong."
20///     }
21/// }
22/// ```
23#[derive(Clone, PartialEq, Props)]
24pub struct AlertProps {
25    /// Alert color variant.
26    #[props(default = Color::Primary)]
27    pub color: Color,
28    /// Show a dismiss button. When clicked, the alert hides itself.
29    #[props(default)]
30    pub dismissible: bool,
31    /// Additional CSS classes.
32    #[props(default)]
33    pub class: String,
34    /// Any additional HTML attributes.
35    #[props(extends = GlobalAttributes)]
36    attributes: Vec<Attribute>,
37    /// Child elements.
38    pub children: Element,
39}
40
41#[component]
42pub fn Alert(props: AlertProps) -> Element {
43    let mut visible = use_signal(|| true);
44
45    if !*visible.read() {
46        return rsx! {};
47    }
48
49    let dismiss_class = if props.dismissible {
50        " alert-dismissible fade show"
51    } else {
52        ""
53    };
54
55    let full_class = if props.class.is_empty() {
56        format!("alert alert-{}{dismiss_class}", props.color)
57    } else {
58        format!("alert alert-{}{dismiss_class} {}", props.color, props.class)
59    };
60
61    rsx! {
62        div {
63            class: "{full_class}",
64            role: "alert",
65            ..props.attributes,
66            {props.children}
67            if props.dismissible {
68                button {
69                    class: "btn-close",
70                    r#type: "button",
71                    "aria-label": "Close",
72                    onclick: move |_| visible.set(false),
73                }
74            }
75        }
76    }
77}