biji_ui/components/dialog/
root.rs

1use std::time::Duration;
2
3use leptos::{context::Provider, prelude::*};
4
5use crate::components::dialog::context::{DialogContext, RootContext};
6use crate::utils::prevent_scroll::use_prevent_scroll;
7
8#[component]
9pub fn Root(
10    children: Children,
11    #[prop(into, optional)] class: String,
12    /// Prevent scrolling when the dialog is open
13    #[prop(default = true)]
14    prevent_scroll: bool,
15    /// The timeout after which the component will be unmounted if `when == false`
16    #[prop(default = Duration::from_millis(200))]
17    hide_delay: Duration,
18) -> impl IntoView {
19    let root_ctx = RootContext {
20        ..RootContext::default()
21    };
22    let ctx = DialogContext {
23        root: RwSignal::new(root_ctx),
24        prevent_scroll,
25        hide_delay,
26        ..Default::default()
27    };
28
29    view! {
30        <Provider value={ctx}>
31            <RootEvents>
32                <div class={class}>
33                    <Provider value={root_ctx}>{children()}</Provider>
34                </div>
35            </RootEvents>
36        </Provider>
37    }
38}
39
40#[component]
41pub fn RootEvents(children: Children) -> impl IntoView {
42    let dialog_ctx = expect_context::<DialogContext>();
43
44    let eff = use_prevent_scroll(
45        move || dialog_ctx.prevent_scroll && dialog_ctx.open.get(),
46        dialog_ctx.hide_delay,
47    );
48
49    on_cleanup(move || {
50        drop(eff);
51    });
52
53    children()
54}