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/// # use dioxus::prelude::*;
16/// # use dioxus_bootstrap_css::prelude::*;
17/// # fn _doctest() -> Element {
18/// rsx! {
19/// Alert { color: Color::Success, "Operation completed!" }
20/// Alert { color: Color::Danger, dismissible: true,
21/// strong { "Error! " }
22/// "Something went wrong."
23/// }
24/// // With dismiss callback:
25/// Alert { color: Color::Warning, dismissible: true,
26/// on_dismiss: move |_| { /* clear error state */ },
27/// "Dismissible with callback."
28/// }
29/// }
30/// # }
31/// ```
32#[derive(Clone, PartialEq, Props)]
33pub struct AlertProps {
34 /// Alert color variant.
35 #[props(default = Color::Primary)]
36 pub color: Color,
37 /// Show a dismiss button. When clicked, the alert hides itself.
38 #[props(default)]
39 pub dismissible: bool,
40 /// Callback when the dismiss button is clicked. Use this to clear external state.
41 #[props(default)]
42 pub on_dismiss: Option<EventHandler<()>>,
43 /// Additional CSS classes.
44 #[props(default)]
45 pub class: String,
46 /// Any additional HTML attributes.
47 #[props(extends = GlobalAttributes)]
48 attributes: Vec<Attribute>,
49 /// Child elements.
50 pub children: Element,
51}
52
53#[component]
54pub fn Alert(props: AlertProps) -> Element {
55 let mut visible = use_signal(|| true);
56
57 if !*visible.read() {
58 return rsx! {};
59 }
60
61 let dismiss_class = if props.dismissible {
62 " alert-dismissible fade show"
63 } else {
64 ""
65 };
66
67 let full_class = if props.class.is_empty() {
68 format!("alert alert-{}{dismiss_class}", props.color)
69 } else {
70 format!("alert alert-{}{dismiss_class} {}", props.color, props.class)
71 };
72
73 rsx! {
74 div {
75 class: "{full_class}",
76 role: "alert",
77 ..props.attributes,
78 {props.children}
79 if props.dismissible {
80 button {
81 class: "btn-close",
82 r#type: "button",
83 "aria-label": "Close",
84 onclick: move |_| {
85 visible.set(false);
86 if let Some(handler) = &props.on_dismiss {
87 handler.call(());
88 }
89 },
90 }
91 }
92 }
93 }
94}