soma-ui 0.1.1

A Leptos 0.8 component library: 160+ accessible UI components, blocks, charts, and a ChartDB-style schema diagram — with a prebuilt stylesheet.
Documentation
use super::shared::{OverlayDescription, OverlayFooter, OverlayTitle};
use crate::{Button, ButtonVariant};
use leptos::portal::Portal;
use leptos::prelude::*;

/// Confirmation dialog — backdrop click does NOT dismiss; requires explicit button action.
/// ponytail: No Escape key, no backdrop dismiss — intentional semantic difference from Dialog.
#[component]
pub fn AlertDialog(#[prop(into)] open: RwSignal<bool>, children: ChildrenFn) -> impl IntoView {
    provide_context(open);

    let children = StoredValue::new(children);

    view! {
        <Portal>
            <Show when=move || open.get()>
                // Backdrop — pointer-events-none so clicks pass through (no dismiss on click).
                <div class="fixed inset-0 z-40 bg-black/60 animate-fade-in pointer-events-none" />
                {children.with_value(|c| c())}
            </Show>
        </Portal>
    }
}

#[component]
pub fn AlertDialogContent(children: Children) -> impl IntoView {
    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">
            {children()}
        </div>
    }
}

#[component]
pub fn AlertDialogHeader(children: Children) -> impl IntoView {
    view! { <div class="mb-4">{children()}</div> }
}

#[component]
pub fn AlertDialogTitle(children: Children) -> impl IntoView {
    view! { <OverlayTitle>{children()}</OverlayTitle> }
}

#[component]
pub fn AlertDialogDescription(children: Children) -> impl IntoView {
    view! { <OverlayDescription>{children()}</OverlayDescription> }
}

#[component]
pub fn AlertDialogFooter(children: Children) -> impl IntoView {
    view! { <OverlayFooter>{children()}</OverlayFooter> }
}

/// Primary action button — closes and fires the callback.
#[component]
pub fn AlertDialogAction(
    #[prop(into)] on_click: Callback<()>,
    children: Children,
) -> impl IntoView {
    let open =
        use_context::<RwSignal<bool>>().expect("AlertDialogAction must be inside AlertDialog");
    view! {
        <Button
            variant=ButtonVariant::Default
            on:click=move |_| { open.set(false); on_click.run(()); }
        >
            {children()}
        </Button>
    }
}

/// Cancel button — closes without confirming.
#[component]
pub fn AlertDialogCancel(children: Children) -> impl IntoView {
    let open =
        use_context::<RwSignal<bool>>().expect("AlertDialogCancel must be inside AlertDialog");
    view! {
        <Button
            variant=ButtonVariant::Outline
            on:click=move |_| open.set(false)
        >
            {children()}
        </Button>
    }
}