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