Skip to main content

shadow_design/
modal.rs

1use crate::icon::{Icon, IconKind};
2use dioxus::prelude::*;
3
4#[component]
5pub fn Modal(
6    is_open: Signal<bool>,
7    #[props(default)] title: Option<String>,
8    #[props(default)] glow: Option<bool>,
9    #[props(default)] class: String,
10    children: Element,
11) -> Element {
12    if !*is_open.read() {
13        return rsx! {};
14    }
15
16    #[cfg(feature = "theme")]
17    let theme_val = crate::theme::use_theme()();
18    #[cfg(feature = "theme")]
19    let base_override = theme_val.resolve_component_base("modal").unwrap_or("");
20    #[cfg(feature = "theme")]
21    let class_modifiers = theme_val.resolve_class_modifiers("modal", &class);
22    #[cfg(feature = "theme")]
23    let glow_class = theme_val.resolve_elevation_class("modal", glow);
24
25    #[cfg(not(feature = "theme"))]
26    let base_override = "";
27    #[cfg(not(feature = "theme"))]
28    let class_modifiers = String::new();
29    #[cfg(not(feature = "theme"))]
30    let glow_class = if glow == Some(true) {
31        "sd-modal-dialog--glow".to_string()
32    } else {
33        String::new()
34    };
35
36    #[cfg(feature = "animation")]
37    let anim_class = crate::animation::Animations::MODAL_ENTER;
38    #[cfg(not(feature = "animation"))]
39    let anim_class = "animate-modal-enter";
40
41    rsx! {
42        div {
43            class: "sd-modal-backdrop",
44            onclick: move |_| *is_open.write() = false,
45            div {
46                class: "sd-modal-dialog {base_override} {glow_class} {anim_class} {class_modifiers} {class}",
47                onclick: move |e| e.stop_propagation(),
48                div {
49                    class: "sd-modal-dialog__header",
50                    h3 { class: "sd-modal-dialog__title", "{title.as_deref().unwrap_or_default()}" }
51                    button {
52                        class: "sd-modal-dialog__close",
53                        onclick: move |_| *is_open.write() = false,
54                        Icon { kind: IconKind::X, size: 16 }
55                    }
56                }
57                div { class: "sd-modal-dialog__body", {children} }
58            }
59        }
60    }
61}