nova_forms/components/
modal.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use leptos::*;

use crate::Button;

use super::DialogKind;

/// A modal dialog.
#[component]
pub fn Modal(
    #[prop(into)] id: String,
    /// The kind of dialog to display.
    kind: DialogKind,
    /// Whether the dialog is open.
    #[prop(into)] open: Signal<bool>,
    /// The callback to close the dialog.
    #[prop(into, optional)] close: Option<Callback<(), ()>>,
    /// The title of the dialog.
    #[prop(into)] title: TextProp,
    /// The message of the dialog.
    #[prop(into)] msg: TextProp,
) -> impl IntoView {
    
    let id_clone = id.clone();
    create_effect(move |_| {
        if open.get() {
            js_sys::eval(format!(r#"
                document.getElementById('{id}').showModal();
                document.getElementById('{id}').addEventListener('cancel', (event) => {{
                    event.preventDefault();
                }});
            "#, id=id_clone).as_str())
                .expect("Failed to show modal");
        } else {
            js_sys::eval(format!("document.getElementById('{}').close()", id_clone).as_str())
                .expect("Failed to close modal");
        }
    });

    view! {
        <Show when=move || open.get()>
            //<Body attr:inert=move || open.get() />
            <div class="modal-background"></div>
        </Show>
        <dialog
            id=id
            class=format!("modal {}", kind.class())
            tabindex="-1"
        >
            <div class="modal-header">{
                let title = title.clone();
                move || title.clone()
            }</div>
            <div class="modal-main">{
                let msg = msg.clone();
                move || msg.clone()
            }</div>
            {
                if let Some(close) = close {
                    view! {
                        <div class="modal-footer">
                            <Button icon="close" label="Close" on:click=move |_ev| close.call(()) />
                        </div>
                    }.into_view()
                } else {
                    View::default()
                }
            }
        </dialog>
    }
}