use super::{DrawerModalType, DrawerPosition, DrawerSize};
use crate::ConfigInjection;
use leptos::{either::Either, ev, prelude::*};
use thaw_components::{CSSTransition, FocusTrap, Teleport};
use thaw_utils::{class_list, mount_style, use_lock_html_scroll, Model};
#[component]
pub fn OverlayDrawer(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(optional, into)] container_class: MaybeProp<String>,
#[prop(into)]
open: Model<bool>,
#[prop(default = true.into(), into)]
mask_closeable: Signal<bool>,
#[prop(optional, into)]
close_on_esc: bool,
#[prop(optional, into)]
position: Signal<DrawerPosition>,
#[prop(optional, into)]
size: Signal<DrawerSize>,
#[prop(optional, into)]
modal_type: DrawerModalType,
children: Children,
) -> impl IntoView {
mount_style("drawer", include_str!("./drawer.css"));
mount_style("overlay-drawer", include_str!("./overlay-drawer.css"));
let config_provider = ConfigInjection::expect_context();
let open_drawer: RwSignal<bool> = RwSignal::new(open.get_untracked());
let is_lock = RwSignal::new(open.get_untracked());
Effect::new(move |_| {
let is_open = open.get();
if is_open {
is_lock.set(true);
}
open_drawer.set(is_open);
});
use_lock_html_scroll(is_lock.into());
let on_after_leave = move || {
is_lock.set(false);
};
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-overlay-drawer-container", container_class
]
data-thaw-id=config_provider.id()
>
{if modal_type == DrawerModalType::Modal {
Either::Left(
view! {
<CSSTransition
appear=open.get_untracked()
show=open.signal()
name="fade-in-transition"
>
<div
class="thaw-overlay-drawer__backdrop"
on:click=on_mask_click
></div>
</CSSTransition>
},
)
} else {
Either::Right(())
}}
<CSSTransition
appear=open_drawer.get_untracked()
show=open_drawer
name=Memo::new(move |_| {
format!("slide-in-from-{}-transition", position.get().as_str())
})
on_after_leave
>
<div
class=class_list![
"thaw-overlay-drawer",
move || format!("thaw-overlay-drawer--position-{}", position.get().as_str()),
class
]
style=move || {
format!("--thaw-drawer--size: {}", size.get().as_size_str(position))
}
role="dialog"
aria-modal=if modal_type == DrawerModalType::Modal {
"true"
} else {
"false"
}
>
{children()}
</div>
</CSSTransition>
</div>
</FocusTrap>
</Teleport>
}
}