use super::shared::{EscapeBackdrop, OverlayDescription, OverlayFooter, OverlayTitle};
use crate::icons::{icondata, Icon};
use leptos::portal::Portal;
use leptos::prelude::*;
#[component]
pub fn Dialog(#[prop(into)] open: RwSignal<bool>, children: ChildrenFn) -> impl IntoView {
provide_context(open);
let children = StoredValue::new(children);
view! {
<Portal>
<Show when=move || open.get()>
<EscapeBackdrop open=open>
{children.with_value(|c| c())}
</EscapeBackdrop>
</Show>
</Portal>
}
}
#[component]
pub fn DialogContent(children: Children) -> impl IntoView {
let open = use_context::<RwSignal<bool>>().expect("DialogContent must be inside Dialog");
let close = move |_| open.set(false);
view! {
<div class="fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-50 w-full max-w-lg rounded-lg border border-border bg-card p-6 shadow-elev-lg animate-scale-in">
<button
class="absolute top-4 end-4 flex items-center justify-center w-7 h-7 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent transition-colors transition-all duration-150 ease-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
aria-label="Close"
on:click=close
>
<Icon icon=Signal::derive(|| icondata::LuX) width="16" height="16" />
</button>
{children()}
</div>
}
}
#[component]
pub fn DialogHeader(children: Children) -> impl IntoView {
view! { <div class="mb-4">{children()}</div> }
}
#[component]
pub fn DialogTitle(children: Children) -> impl IntoView {
view! { <OverlayTitle>{children()}</OverlayTitle> }
}
#[component]
pub fn DialogDescription(children: Children) -> impl IntoView {
view! { <OverlayDescription>{children()}</OverlayDescription> }
}
#[component]
pub fn DialogFooter(children: Children) -> impl IntoView {
view! { <OverlayFooter>{children()}</OverlayFooter> }
}