Biji UI

Alert Dialog

A modal dialog that interrupts the user with important content and requires a deliberate response.

Installation

biji-ui = { version = "0.5.0", features = ["alert_dialog"] }

Usage

use std::time::Duration;
use leptos::prelude::*;
use biji_ui::components::alert_dialog;

#[component]
pub fn MyAlertDialog() -> impl IntoView {
    view! {
        // No Portal needed — Overlay and Content use `fixed` positioning with
        // a high z-index, so they layer correctly over the page without
        // teleportation. Root takes Children (FnOnce), so owned values like
        // Strings can be moved in freely without StoredValue wrappers.
        <alert_dialog::Root hide_delay={Duration::from_millis(200)}>
            <alert_dialog::Trigger class="rounded bg-red-600 px-4 py-2 text-white hover:bg-red-500">
                "Delete account"
            </alert_dialog::Trigger>
            <alert_dialog::Overlay
                class="fixed inset-0 z-[80] bg-black/40"
                show_class="opacity-100 duration-300 ease-out"
                hide_class="opacity-0 duration-200 ease-in"
            />
            <alert_dialog::Content
                class="fixed left-1/2 top-1/2 z-[90] -translate-x-1/2 -translate-y-1/2 w-full max-w-md rounded-lg bg-background p-6 shadow-xl"
                show_class="opacity-100 scale-100 duration-300 ease-out"
                hide_class="opacity-0 scale-95 duration-200 ease-in"
            >
                <alert_dialog::Title class="text-lg font-semibold">
                    "Are you absolutely sure?"
                </alert_dialog::Title>
                <alert_dialog::Description class="mt-2 text-sm text-muted-foreground">
                    "This action cannot be undone. This will permanently delete your account."
                </alert_dialog::Description>
                <div class="mt-6 flex justify-end gap-3">
                    <alert_dialog::Cancel class="rounded-md border px-4 py-2 text-sm font-medium hover:bg-accent">
                        "Cancel"
                    </alert_dialog::Cancel>
                    <alert_dialog::Action
                        class="rounded-md bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-500"
                        on_click={Callback::new(|_| { /* your action here */ })}
                    >
                        "Continue"
                    </alert_dialog::Action>
                </div>
            </alert_dialog::Content>
        </alert_dialog::Root>
    }
}

RootWith

Use RootWith to access AlertDialogState inline via the let: binding. The state is Copy and safe to pass as a prop.

Alert is closed

use std::time::Duration;
use leptos::prelude::*;
use biji_ui::components::alert_dialog;

#[component]
pub fn MyAlertDialog() -> impl IntoView {
    view! {
        <alert_dialog::RootWith hide_delay={Duration::from_millis(200)} let:d>
            <p class="mb-2 text-sm text-muted-foreground">
                {move || if d.open.get() { "Alert is open" } else { "Alert is closed" }}
            </p>
            <alert_dialog::Trigger class="rounded bg-red-600 px-4 py-2 text-white hover:bg-red-500">
                "Delete account"
            </alert_dialog::Trigger>
            <alert_dialog::Overlay
                class="fixed inset-0 z-[80] bg-black/40"
                show_class="opacity-100 duration-300 ease-out"
                hide_class="opacity-0 duration-200 ease-in"
            />
            <alert_dialog::Content
                class="fixed left-1/2 top-1/2 z-[90] w-full max-w-md rounded-lg bg-background p-6 shadow-xl"
                show_class="opacity-100 scale-100 duration-300 ease-out translate-x-[-50%] translate-y-[-50%]"
                hide_class="opacity-0 scale-95 duration-200 ease-in translate-x-[-50%] translate-y-[-50%]"
            >
                <alert_dialog::Title class="text-lg font-semibold">
                    "Are you absolutely sure?"
                </alert_dialog::Title>
                <alert_dialog::Description class="mt-2 text-sm text-muted-foreground">
                    "This action cannot be undone."
                </alert_dialog::Description>
                <div class="mt-6 flex justify-end gap-3">
                    <alert_dialog::Cancel class="rounded-md border px-4 py-2 text-sm font-medium">
                        "Cancel"
                    </alert_dialog::Cancel>
                    <alert_dialog::Action class="rounded-md bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-500">
                        "Confirm"
                    </alert_dialog::Action>
                </div>
            </alert_dialog::Content>
        </alert_dialog::RootWith>
    }
}

API Reference

Root / RootWith

NameTypeDefaultDescription
classString""CSS class applied to the root wrapper element.
hide_delayDuration200msHow long to wait before unmounting content after closing begins. Should match your CSS transition duration.
prevent_scrollbooltrueWhen true, prevents the page from scrolling while the dialog is open.
openboolfalseInitial open state.
on_open_changeOption<Callback<bool>>NoneCallback fired when the open state changes.

Trigger

NameTypeDefaultDescription
classString""CSS class applied to the trigger button.

Overlay

NameTypeDefaultDescription
classString""CSS class applied in both open and closed states.
show_classString""CSS class applied when the overlay is visible.
hide_classString""CSS class applied while the overlay is hiding.

Content

NameTypeDefaultDescription
classString""CSS class applied in both open and closed states.
show_classString""CSS class applied when the dialog is open.
hide_classString""CSS class applied while the dialog is closing.

Title

NameTypeDefaultDescription
classString""CSS class applied to the title heading.

Description

NameTypeDefaultDescription
classString""CSS class applied to the description paragraph.

Cancel

NameTypeDefaultDescription
classString""CSS class applied to the cancel button. Clicking closes the dialog.

Action

NameTypeDefaultDescription
classString""CSS class applied to the action button. Does not auto-close; wire your own handler.

Data Attributes

AttributeDescription
data-state"open" when the dialog is visible; "closed" when hidden. Present on Trigger.

Keyboard Navigation

KeyDescription
TabMoves focus to the next focusable element inside the dialog. Focus is trapped.
Shift + TabMoves focus to the previous focusable element inside the dialog.
EscapeCloses the dialog and returns focus to the trigger.