Skip to main content

dioxus_element_plug/components/
message.rs

1use dioxus::prelude::*;
2
3/// Message type
4#[derive(Clone, PartialEq)]
5pub enum MessageType {
6    Success,
7    Warning,
8    Info,
9    Error,
10}
11
12impl MessageType {
13    pub fn as_class(&self) -> &'static str {
14        match self {
15            MessageType::Success => "el-message--success",
16            MessageType::Warning => "el-message--warning",
17            MessageType::Info => "el-message--info",
18            MessageType::Error => "el-message--error",
19        }
20    }
21
22    pub fn as_icon(&self) -> &'static str {
23        match self {
24            MessageType::Success => "el-icon-success",
25            MessageType::Warning => "el-icon-warning",
26            MessageType::Info => "el-icon-info",
27            MessageType::Error => "el-icon-error",
28        }
29    }
30}
31
32/// Message props
33#[derive(Props, Clone, PartialEq)]
34pub struct MessageProps {
35    /// Message text
36    pub message: String,
37
38    /// Message type
39    #[props(default = MessageType::Info)]
40    pub message_type: MessageType,
41
42    /// Whether to show close button
43    #[props(default = false)]
44    pub closable: bool,
45
46    /// Whether to show icon
47    #[props(default = true)]
48    pub show_icon: bool,
49
50    /// Whether to center the message
51    #[props(default = false)]
52    pub center: bool,
53
54    /// Display duration in ms (0 = persistent)
55    #[props(default = 3000)]
56    pub duration: u64,
57
58    /// Close event handler
59    #[props(default)]
60    pub on_close: Option<EventHandler<()>>,
61
62    #[props(default)]
63    pub class: Option<String>,
64
65    #[props(default)]
66    pub style: Option<String>,
67}
68
69/// Message component for transient notifications
70#[component]
71pub fn Message(props: MessageProps) -> Element {
72    let mut class_names = vec!["el-message".to_string()];
73    class_names.push(props.message_type.as_class().to_string());
74    if props.center { class_names.push("is-center".to_string()); }
75    if let Some(ref c) = props.class { class_names.push(c.clone()); }
76
77    rsx! {
78        div {
79            class: "{class_names.join(\" \")}",
80            style: props.style.clone().unwrap_or_default(),
81            role: "alert",
82            if props.show_icon {
83                i { class: "{props.message_type.as_icon()} el-message__icon" }
84            }
85            p {
86                class: "el-message__content",
87                "{props.message}"
88            }
89            if props.closable {
90                button {
91                    class: "el-message__closeBtn",
92                    onclick: move |_| {
93                        if let Some(handler) = props.on_close {
94                            handler.call(());
95                        }
96                    },
97                    "×"
98                }
99            }
100        }
101    }
102}