use crate::ConfigInjection;
use leptos::{context::Provider, ev, prelude::*};
use thaw_components::{CSSTransition, FocusTrap, Teleport};
use thaw_utils::{class_list, mount_style, Model};
#[component]
pub fn Dialog(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(into)]
open: Model<bool>,
#[prop(default = true.into(), into)]
mask_closeable: Signal<bool>,
#[prop(default = true, into)]
close_on_esc: bool,
children: Children,
) -> impl IntoView {
mount_style("dialog", include_str!("./dialog.css"));
let config_provider = ConfigInjection::expect_context();
let on_mask_click = move |_| {
if mask_closeable.get_untracked() {
open.set(false);
}
};
let on_esc = move |_: ev::KeyboardEvent| {
open.set(false);
};
view! {
<Teleport immediate=open.signal()>
<FocusTrap disabled=!close_on_esc active=open.signal() on_esc>
<div
class=class_list!["thaw-config-provider thaw-dialog", class]
data-thaw-id=config_provider.id()
>
<CSSTransition
appear=open.get_untracked()
show=open.signal()
name="fade-in-transition"
>
<div
class="thaw-dialog-surface__backdrop"
on:click=on_mask_click
aria-hidden="true"
></div>
</CSSTransition>
<Provider value=DialogInjection { open }>{children()}</Provider>
</div>
</FocusTrap>
</Teleport>
}
}
#[derive(Clone)]
pub(super) struct DialogInjection {
pub open: Model<bool>,
}
impl DialogInjection {
pub fn expect_context() -> Self {
expect_context::<Self>()
}
}