AlertDialog
HeroUIA dialog that asks before going on, HeroUI's on Kobalte's.
Solidtype_heroui.Alert_dialog is Kobalte’s Dialog as an alertdialog,
with the classes HeroUI’s own alertDialogVariants gives. It is a
Modal in all but these: only its own buttons close it, unless
its backdrop says a press outside or Escape may; its container takes no
scroll; and its icon draws HeroUI’s icon for its status.
module Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
let make () = <Alert_dialog> <Button variant=`danger>"Delete Project"</Button> <Alert_dialog.Backdrop> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon status=`danger /> <Alert_dialog.Heading> "Delete project permanently?" </Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p> "This will permanently delete " <strong>"My Awesome Project"</strong> " and all of its data. This action cannot be undone." </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Cancel"</Button> <Button slot=`close variant=`danger>"Delete Project"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog>Anatomy
Section titled “Anatomy”<Alert_dialog> <Button>"Open"</Button> <Alert_dialog.Backdrop> <Alert_dialog.Container> <Alert_dialog.Dialog> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon /> <Alert_dialog.Heading>...</Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body>...</Alert_dialog.Body> <Alert_dialog.Footer>...</Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop></Alert_dialog>Examples
Section titled “Examples”Statuses
Section titled “Statuses”module Jsx = Solidtype.Jsxmodule For = Solidtype.Formodule Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
type example = { cancel : string; confirm : string; body : string; classes : string; header : string; status : Solidtype_heroui.Status_icon.status; trigger : string;}
let examples = [| { cancel = "Stay Signed In"; confirm = "Sign Out"; body = "You'll need to sign in again to access your account. Any unsaved \ changes will be lost."; classes = "bg-accent-soft text-accent-soft-foreground"; header = "Sign out of your account?"; status = `accent; trigger = "Sign Out"; }; { cancel = "Not Yet"; confirm = "Mark Complete"; body = "This will mark the task as complete and notify all team members. The \ task will be moved to your completed list."; classes = "bg-success-soft text-success-soft-foreground"; header = "Complete this task?"; status = `success; trigger = "Complete Task"; }; { cancel = "Keep Editing"; confirm = "Discard"; body = "You have unsaved changes that will be permanently lost. Are you sure \ you want to discard them?"; classes = "bg-warning-soft text-warning-soft-foreground"; header = "Discard unsaved changes?"; status = `warning; trigger = "Discard Changes"; }; { cancel = "Cancel"; confirm = "Delete Account"; body = "This will permanently delete your account and remove all your data \ from our servers. This action is irreversible."; classes = "bg-danger-soft text-danger-soft-foreground"; header = "Delete your account?"; status = `danger; trigger = "Delete Account"; }; |]
let make () = <div class_="flex flex-wrap gap-4"> <For each=(fun () -> examples)> (fun (e : example) _ -> <Alert_dialog> <Button class_=(fun () -> e.classes)> (fun () -> Jsx.string e.trigger) </Button> <Alert_dialog.Backdrop> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon status=(fun () -> e.status) /> <Alert_dialog.Heading> (fun () -> Jsx.string e.header) </Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p>(fun () -> Jsx.string e.body)</p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary> (fun () -> Jsx.string e.cancel) </Button> <Button slot=`close variant=(fun () -> match e.status with | `danger -> `danger | `default | `accent | `success | `warning -> `primary)> (fun () -> Jsx.string e.confirm) </Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog>) </For> </div>Placements
Section titled “Placements”module Jsx = Solidtype.Jsxmodule For = Solidtype.Formodule Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
let placements = [| (`auto, "auto"); (`top, "top"); (`center, "center"); (`bottom, "bottom") |]
let make () = <div class_="flex flex-wrap gap-4"> <For each=(fun () -> placements)> (fun (placement, name) _ -> <Alert_dialog> <Button variant=`secondary> (fun () -> Jsx.string (String.capitalize_ascii name)) </Button> <Alert_dialog.Backdrop> <Alert_dialog.Container placement=(fun () -> placement)> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon status=`accent /> <Alert_dialog.Heading> (fun () -> Jsx.string (match placement with | `auto -> "Auto Placement" | `top | `center | `bottom -> String.capitalize_ascii name ^ " Position")) </Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p> (fun () -> Jsx.string (match placement with | `auto -> "Automatically positions at the bottom on mobile \ and center on desktop for optimal user \ experience." | `top | `center | `bottom -> "This dialog is positioned at the " ^ name ^ " of the viewport. Critical confirmations are \ typically centered for maximum attention.")) </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Cancel"</Button> <Button slot=`close>"Confirm"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog>) </For> </div>module Jsx = Solidtype.Jsxmodule For = Solidtype.Formodule Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
let sizes = [| (`xs, "xs"); (`sm, "sm"); (`md, "md"); (`lg, "lg"); (`cover, "cover") |]
let make () = <div class_="flex flex-wrap gap-4"> <For each=(fun () -> sizes)> (fun (size, name) _ -> <Alert_dialog> <Button variant=`secondary> (fun () -> Jsx.string (String.capitalize_ascii name)) </Button> <Alert_dialog.Backdrop> <Alert_dialog.Container size=(fun () -> size)> <Alert_dialog.Dialog> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon class_="bg-default text-foreground"> <Gravity.Rocket class_="size-5" /> </Alert_dialog.Icon> <Alert_dialog.Heading> "Size: " (fun () -> Jsx.string (String.capitalize_ascii name)) </Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p> "This alert dialog uses the " <code>(fun () -> Jsx.string name)</code> (fun () -> Jsx.string (match size with | `cover -> " size variant. It spans the full screen with \ margins: 16px on mobile and 40px on desktop. \ Maintains rounded corners and standard padding. \ Perfect for critical confirmations that need \ maximum width while preserving alert dialog \ aesthetics." | `xs | `sm | `md | `lg -> " size variant. On mobile devices, all sizes adapt \ to near full-width for optimal viewing. On \ desktop, each size provides a different maximum \ width to suit various content needs.")) </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Cancel"</Button> <Button slot=`close>"Confirm"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog>) </For> </div>Controlled State
Section titled “Controlled State”A signal is Solid’s state: each half keeps the dialog’s open state in one, where HeroUI’s uses React.useState and useOverlayState.
With a signal
Control the alert dialog using Solid's signal for simple state management. Perfect for basic use cases.
Status: closed
With a signal's setter
Use the signal's setter for a cleaner API with convenient calls like S.set set_open true, S.set set_open false, and S.update set_open not.
Status: closed
module S = Solidtype.Solidmodule Jsx = Solidtype.Jsxmodule Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
(* HeroUI shows React's useState and its own useOverlayState; a signal is Solid's state, so both halves keep the dialog's in one. *)let make () = let is_open, set_open = S.create_signal false in let state_open, set_state_open = S.create_signal false in <div class_="flex max-w-md flex-col gap-8"> <div class_="flex flex-col gap-3"> <h3 class_="text-lg font-semibold text-foreground">"With a signal"</h3> <p class_="text-sm leading-relaxed text-pretty text-muted"> "Control the alert dialog using Solid's " <code class_="text-foreground">"signal"</code> " for simple state management. Perfect for basic use cases." </p> <div class_="flex flex-col items-start gap-3 rounded-2xl bg-surface p-4 \ shadow-sm"> <div class_="flex w-full items-center justify-between"> <p class_="text-xs text-muted"> "Status: " <span class_="font-mono font-medium text-foreground"> (fun () -> Jsx.string (if S.get is_open then "open" else "closed")) </span> </p> </div> <div class_="flex gap-2"> <Button size=`sm variant=`secondary on_click=(fun _ -> S.set set_open true)> "Open Dialog" </Button> <Button size=`sm variant=`tertiary on_click=(fun _ -> S.update set_open not)> "Toggle" </Button> </div> </div> <Alert_dialog.Backdrop is_open=(fun () -> S.get is_open) on_open_change=(S.set set_open)> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon status=`accent /> <Alert_dialog.Heading> "Controlled with a signal" </Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p> "This alert dialog is controlled by Solid's " <code>"signal"</code> ". Pass " <code>"is_open"</code> " and " <code>"on_open_change"</code> " props to manage the dialog state externally." </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Cancel"</Button> <Button slot=`close>"Confirm"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </div> <div class_="flex flex-col gap-3"> <h3 class_="text-lg font-semibold text-foreground"> "With a signal's setter" </h3> <p class_="text-sm leading-relaxed text-pretty text-muted"> "Use the " <code class_="text-foreground">"signal"</code> "'s setter for a cleaner API with convenient calls like " <code>"S.set set_open true"</code> ", " <code>"S.set set_open false"</code> ", and " <code>"S.update set_open not"</code> "." </p> <div class_="flex flex-col items-start gap-3 rounded-2xl bg-surface p-4 \ shadow-sm"> <div class_="flex w-full items-center justify-between"> <p class_="text-xs text-muted"> "Status: " <span class_="font-mono font-medium text-foreground"> (fun () -> Jsx.string (if S.get state_open then "open" else "closed")) </span> </p> </div> <div class_="flex gap-2"> <Button size=`sm variant=`secondary on_click=(fun _ -> S.set set_state_open true)> "Open Dialog" </Button> <Button size=`sm variant=`tertiary on_click=(fun _ -> S.update set_state_open not)> "Toggle" </Button> </div> </div> <Alert_dialog.Backdrop is_open=(fun () -> S.get state_open) on_open_change=(S.set set_state_open)> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon status=`success /> <Alert_dialog.Heading> "Controlled with a signal's setter" </Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p> "The " <code>"signal"</code> {js|'s setter covers the common operations. No need to manually create callbacks—just use |js} <code>"S.set set_open true"</code> ", " <code>"S.set set_open false"</code> ", or " <code>"S.update set_open not"</code> "." </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Cancel"</Button> <Button slot=`close>"Confirm"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </div> </div>Custom Icon
Section titled “Custom Icon”module Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
let make () = <Alert_dialog> <Button variant=`secondary>"Reset Password"</Button> <Alert_dialog.Backdrop> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon status=`warning> <Gravity.Lock_open class_="size-5" /> </Alert_dialog.Icon> <Alert_dialog.Heading>"Reset your password?"</Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p> "We'll send a password reset link to your email address. You'll \ need to create a new password to regain access to your account." </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Cancel"</Button> <Button slot=`close>"Send Reset Link"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog>Custom Trigger
Section titled “Custom Trigger”Delete Item
Permanently remove this item
module Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
let make () = <Alert_dialog> <Alert_dialog.Trigger class_="group flex items-center gap-3 rounded-2xl bg-surface p-4 \ shadow-xs select-none hover:bg-surface-secondary"> <div class_="flex size-12 shrink-0 items-center justify-center rounded-xl \ bg-danger-soft text-danger-soft-foreground"> <Gravity.Trash_bin class_="size-6" /> </div> <div class_="flex flex-1 flex-col gap-0.5"> <p class_="text-sm font-semibold">"Delete Item"</p> <p class_="text-xs text-muted">"Permanently remove this item"</p> </div> </Alert_dialog.Trigger> <Alert_dialog.Backdrop> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon status=`danger> <Gravity.Trash_bin class_="size-5" /> </Alert_dialog.Icon> <Alert_dialog.Heading>"Delete this item?"</Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p> "Use " <code>"Alert_dialog.Trigger"</code> " to create custom trigger elements beyond standard buttons. \ This example shows a card-style trigger with icons and \ descriptive text." </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Cancel"</Button> <Button slot=`close variant=`danger>"Delete Item"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog>Backdrop Variants
Section titled “Backdrop Variants”module Jsx = Solidtype.Jsxmodule For = Solidtype.Formodule Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
let variants = [| (`opaque, "opaque"); (`blur, "blur"); (`transparent, "transparent") |]
let make () = <div class_="flex flex-wrap gap-4"> <For each=(fun () -> variants)> (fun (variant, name) _ -> <Alert_dialog> <Button variant=`secondary> (fun () -> Jsx.string (String.capitalize_ascii name)) </Button> <Alert_dialog.Backdrop variant=(fun () -> variant)> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon status=`accent /> <Alert_dialog.Heading> "Backdrop: " (fun () -> Jsx.string (String.capitalize_ascii name)) </Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p> (fun () -> Jsx.string (match variant with | `opaque -> "An opaque dark backdrop that completely obscures \ the background, providing maximum focus on the \ dialog." | `blur -> "A blurred backdrop that softly obscures the \ background while maintaining visual context." | `transparent -> "A transparent backdrop that keeps the background \ fully visible, useful for less critical \ confirmations.")) </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Cancel"</Button> <Button slot=`close>"Confirm"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog>) </For> </div>Custom Backdrop
Section titled “Custom Backdrop”module Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
let make () = <Alert_dialog> <Button variant=`danger>"Delete Account"</Button> <Alert_dialog.Backdrop class_="bg-linear-to-t from-red-950/90 via-red-950/50 to-transparent \ dark:from-red-950/95 dark:via-red-950/60" variant=`blur> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[420px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header class_="items-center text-center"> <Alert_dialog.Icon status=`danger> <Gravity.Triangle_exclamation class_="size-5" /> </Alert_dialog.Icon> <Alert_dialog.Heading> "Permanently delete your account?" </Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p> "This action cannot be undone. All your data, settings, and \ content will be permanently removed from our servers. The \ dramatic red backdrop emphasizes the severity and \ irreversibility of this decision." </p> </Alert_dialog.Body> <Alert_dialog.Footer class_="flex-col-reverse"> <Button class_="w-full" slot=`close>"Keep Account"</Button> <Button class_="w-full" slot=`close variant=`danger> "Delete Forever" </Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog>Dismiss Behavior
Section titled “Dismiss Behavior”is_dismissable
Controls whether the alert dialog can be dismissed by clicking the overlay backdrop. Alert dialogs typically require explicit action, so this defaults to false. Set to true for less critical confirmations.
is_keyboard_dismiss_disabled
Controls whether the ESC key can dismiss the alert dialog. Alert dialogs typically require explicit action, so this defaults to true. When set to false, the ESC key will be enabled.
module Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
let make () = <div class_="flex max-w-sm flex-col gap-6"> <div class_="flex flex-col gap-2"> <h3 class_="text-lg font-semibold">"is_dismissable"</h3> <p class_="text-sm text-muted"> "Controls whether the alert dialog can be dismissed by clicking the \ overlay backdrop. Alert dialogs typically require explicit action, so \ this defaults to " <code>"false"</code> ". Set to " <code>"true"</code> " for less critical confirmations." </p> <Alert_dialog> <Button variant=`secondary>"Open Alert Dialog"</Button> <Alert_dialog.Backdrop is_dismissable=false> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon status=`danger> <Gravity.Circle_info class_="size-5" /> </Alert_dialog.Icon> <Alert_dialog.Heading> "is_dismissable = false" </Alert_dialog.Heading> <p class_="text-sm leading-5 text-muted"> "Clicking the backdrop won't close this alert dialog" </p> </Alert_dialog.Header> <Alert_dialog.Body> <p> "Try clicking outside this alert dialog on the overlay - it \ won't close. You must use the action buttons to dismiss it." </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Cancel"</Button> <Button slot=`close>"Confirm"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog> </div> <div class_="flex flex-col gap-2"> <h3 class_="text-lg font-semibold">"is_keyboard_dismiss_disabled"</h3> <p class_="text-sm text-muted"> "Controls whether the ESC key can dismiss the alert dialog. Alert \ dialogs typically require explicit action, so this defaults to " <code>"true"</code> ". When set to " <code>"false"</code> ", the ESC key will be enabled." </p> <Alert_dialog> <Button variant=`secondary>"Open Alert Dialog"</Button> <Alert_dialog.Backdrop is_keyboard_dismiss_disabled=true> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon status=`accent> <Gravity.Circle_info class_="size-5" /> </Alert_dialog.Icon> <Alert_dialog.Heading> "is_keyboard_dismiss_disabled = true" </Alert_dialog.Heading> <p class_="text-sm leading-5 text-muted"> "ESC key is disabled" </p> </Alert_dialog.Header> <Alert_dialog.Body> <p> "Press ESC - nothing happens. You must use the action \ buttons to dismiss this alert dialog." </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Cancel"</Button> <Button slot=`close>"Confirm"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog> </div> </div>Close Methods
Section titled “Close Methods”The second half closes the dialog from its own state, where HeroUI’s reads close from the dialog’s render props: the page keeps the state, which the dialog follows.
Using slot=`close
The simplest way to close a dialog. Add slot=`close to any Button component within the dialog. When clicked, it will automatically close the dialog.
Using the dialog's state
Keep the dialog's state in a signal and set it to false. This gives you full control over when and how to close the dialog, allowing you to add custom logic before closing.
module S = Solidtype.Solidmodule Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
(* HeroUI's second dialog closes itself through its render prop's close; here the page keeps the dialog's state, which the buttons set. *)let make () = let is_open, set_open = S.create_signal false in <div class_="flex max-w-2xl flex-col gap-8"> <div class_="flex flex-col gap-2"> <h3 class_="text-lg font-semibold">"Using slot=`close"</h3> <p class_="text-sm text-muted"> "The simplest way to close a dialog. Add " <code>"slot=`close"</code> " to any Button component within the dialog. When clicked, it will \ automatically close the dialog." </p> <Alert_dialog> <Button variant=`secondary>"Open Dialog"</Button> <Alert_dialog.Backdrop> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Header> <Alert_dialog.Icon status=`accent /> <Alert_dialog.Heading>"Using slot=`close"</Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p> "Click either button below - both have " <code>"slot=`close"</code> " and will close the dialog automatically." </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Cancel"</Button> <Button slot=`close>"Confirm"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog> </div> <div class_="flex flex-col gap-2"> <h3 class_="text-lg font-semibold">"Using the dialog's state"</h3> <p class_="text-sm text-muted"> "Keep the dialog's state in a " <code>"signal"</code> " and set it to " <code>"false"</code> ". This gives you full control over when and how to close the dialog, \ allowing you to add custom logic before closing." </p> <Alert_dialog is_open=(fun () -> S.get is_open) on_open_change=(S.set set_open)> <Button variant=`secondary>"Open Dialog"</Button> <Alert_dialog.Backdrop> <Alert_dialog.Container> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Header> <Alert_dialog.Icon status=`success /> <Alert_dialog.Heading> "Using the dialog's state" </Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p> "The buttons below set the " <code>"signal"</code> " to " <code>"false"</code> ". You can add validation or other logic before calling " <code>"S.set set_open false"</code> "." </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button variant=`tertiary on_click=(fun _ -> S.set set_open false)> "Cancel" </Button> <Button on_click=(fun _ -> S.set set_open false)> "Confirm" </Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog> </div> </div>Custom Animations
Section titled “Custom Animations”module Jsx = Solidtype.Jsxmodule For = Solidtype.Formodule Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
type animation = { backdrop : string; container : string; description : string; icon : [ `sparkles | `arrow_up_from_line ]; name : string;}
let animations = [| { backdrop = String.concat " " [ "data-[entering]:duration-400"; "data-[entering]:ease-[cubic-bezier(0.16,1,0.3,1)]"; "data-[exiting]:duration-200"; "data-[exiting]:ease-[cubic-bezier(0.7,0,0.84,0)]"; ]; container = String.concat " " [ "data-[entering]:animate-in"; "data-[entering]:fade-in-0"; "data-[entering]:zoom-in-95"; "data-[entering]:duration-400"; "data-[entering]:ease-[cubic-bezier(0.16,1,0.3,1)]"; "data-[exiting]:animate-out"; "data-[exiting]:fade-out-0"; "data-[exiting]:zoom-out-95"; "data-[exiting]:duration-200"; "data-[exiting]:ease-[cubic-bezier(0.7,0,0.84,0)]"; ]; description = "Physics-based elastic scaling. Simulates a high-damping spring system \ with fast transient response and prolonged settling time. Ideal for \ Alert Dialogs and Modals."; icon = `sparkles; name = "Kinematic Scale"; }; { backdrop = String.concat " " [ "data-[entering]:duration-500"; "data-[entering]:ease-[cubic-bezier(0.25,1,0.5,1)]"; "data-[exiting]:duration-200"; "data-[exiting]:ease-[cubic-bezier(0.5,0,0.75,0)]"; ]; container = String.concat " " [ "data-[entering]:animate-in"; "data-[entering]:fade-in-0"; "data-[entering]:slide-in-from-bottom-4"; "data-[entering]:duration-500"; "data-[entering]:ease-[cubic-bezier(0.25,1,0.5,1)]"; "data-[exiting]:animate-out"; "data-[exiting]:fade-out-0"; "data-[exiting]:slide-out-to-bottom-2"; "data-[exiting]:duration-200"; "data-[exiting]:ease-[cubic-bezier(0.5,0,0.75,0)]"; ]; description = "Simulates movement through a medium with fluid resistance. Eliminates \ mechanical linearity for a natural, grounded feel. Perfect for Bottom \ Sheets or Toasts."; icon = `arrow_up_from_line; name = "Fluid Slide"; }; |]
let make () = <div class_="flex flex-wrap gap-4"> <For each=(fun () -> animations)> (fun (a : animation) _ -> <Alert_dialog> <Button variant=`secondary>(fun () -> Jsx.string a.name)</Button> <Alert_dialog.Backdrop class_=(fun () -> a.backdrop)> <Alert_dialog.Container class_=(fun () -> a.container)> <Alert_dialog.Dialog class_="sm:max-w-[400px]"> <Alert_dialog.Close_trigger /> <Alert_dialog.Header> <Alert_dialog.Icon status=`accent> (fun () -> match a.icon with | `sparkles -> Jsx.element <Gravity.Sparkles class_="size-5" /> | `arrow_up_from_line -> Jsx.element <Gravity.Arrow_up_from_line class_="size-5" />) </Alert_dialog.Icon> <Alert_dialog.Heading> (fun () -> Jsx.string a.name) " Animation" </Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body> <p class_="mt-1">(fun () -> Jsx.string a.description)</p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Close"</Button> <Button slot=`close>"Try Again"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog>) </For> </div>Custom Portal
Section titled “Custom Portal”HeroUI’s Custom Portal example gives the backdrop React Aria’s
UNSTABLE_portalContainer, which the port does not take yet: a dialog is
drawn at the end of the page.
Customization
Section titled “Customization”Tailwind CSS
Section titled “Tailwind CSS”class_ is added after HeroUI’s classes.
module Button = Solidtype_heroui.Buttonmodule Alert_dialog = Solidtype_heroui.Alert_dialog
let make () = <Alert_dialog> <Button variant=`secondary>"Sign out"</Button> <Alert_dialog.Backdrop class_="bg-overlay/50 dark:bg-overlay/60" variant=`blur> <Alert_dialog.Container> <Alert_dialog.Dialog class_="relative overflow-hidden border border-border/80 bg-surface \ shadow-2xl ring-1 ring-accent/10 sm:max-w-[400px] \ dark:border-border/90 dark:bg-surface dark:ring-accent/15"> <div aria_hidden=true class_="pointer-events-none absolute inset-x-0 top-0 h-24 \ bg-linear-to-b from-accent/6 to-transparent \ dark:from-accent/10" /> <div aria_hidden=true class_="pointer-events-none absolute inset-x-8 top-0 h-px \ bg-linear-to-r from-transparent via-accent/35 \ to-transparent dark:via-accent/45" /> <Alert_dialog.Header class_="relative"> <Alert_dialog.Icon status=`accent /> <Alert_dialog.Heading> "Sign out of your account?" </Alert_dialog.Heading> </Alert_dialog.Header> <Alert_dialog.Body class_="relative"> <p class_="text-muted"> "You will be signed out on this device. Unsaved work in " <strong class_="text-foreground">"Acme Workspace"</strong> " may be lost unless it was saved to the cloud." </p> </Alert_dialog.Body> <Alert_dialog.Footer> <Button slot=`close variant=`tertiary>"Stay signed in"</Button> <Button slot=`close>"Sign out"</Button> </Alert_dialog.Footer> </Alert_dialog.Dialog> </Alert_dialog.Container> </Alert_dialog.Backdrop> </Alert_dialog>Global CSS
Section titled “Global CSS”HeroUI’s classes are global, so a stylesheet restyles every one, as with HeroUI in React:
@layer components { .alert-dialog__dialog { @apply rounded-2xl; }
.alert-dialog__heading { @apply text-lg font-semibold; }}Styling Reference
Section titled “Styling Reference”CSS Classes
Section titled “CSS Classes”.alert-dialog__trigger,.alert-dialog__backdrop,.alert-dialog__container,.alert-dialog__dialog,.alert-dialog__header,.alert-dialog__heading,.alert-dialog__icon,.alert-dialog__body,.alert-dialog__footer,.alert-dialog__close-trigger.alert-dialog__backdrop--opaque,--blur,--transparent.alert-dialog__dialog--xs,--sm,--md,--lg,--cover.alert-dialog__icon--default,--accent,--success,--warning,--danger
Interactive States
Section titled “Interactive States”- Entering:
[data-entering="true"]on the backdrop and the container - Exiting:
[data-exiting="true"]on the backdrop and the container - Placement:
[data-placement="auto"], and the others, on the container and the dialog
How it is made
Section titled “How it is made”It shares Modal’s making, on Kobalte’s dialog: see Modal.
Its dialog’s role is alertdialog, as React Aria’s is, and a reader’s dismiss
button is in it only while its backdrop may be dismissed.
API Reference
Section titled “API Reference”Each prop beside the name HeroUI’s React component gives it.
AlertDialog
Section titled “AlertDialog”| React | solidtype | Type | Default | Description |
|---|---|---|---|---|
isOpen |
is_open |
bool |
Whether it is open, controlled | |
defaultOpen |
default_open |
bool |
false |
Whether it starts open |
onOpenChange |
on_open_change |
bool -> unit |
Told as it opens or closes |
AlertDialog.Backdrop
Section titled “AlertDialog.Backdrop”| React | solidtype | Type | Default | Description |
|---|---|---|---|---|
variant |
variant |
`opaque | `blur | `transparent |
`opaque |
Its look |
isDismissable |
is_dismissable |
bool |
false |
Whether a press on it closes the dialog |
isKeyboardDismissDisabled |
is_keyboard_dismiss_disabled |
bool |
true |
Whether Escape does not |
isOpen |
is_open |
bool |
With no Alert_dialog around it, whether it is open |
|
onOpenChange |
on_open_change |
bool -> unit |
With no Alert_dialog around it, told as it opens or closes |
|
className |
class_ |
string |
Added after HeroUI’s classes |
AlertDialog.Container
Section titled “AlertDialog.Container”| React | solidtype | Type | Default | Description |
|---|---|---|---|---|
placement |
placement |
`auto | `center | `top | `bottom |
`auto |
Where the dialog is |
size |
size |
`xs | `sm | `md | `lg | `cover |
`md |
Its width |
className |
class_ |
string |
Added after HeroUI’s classes |
AlertDialog.Icon
Section titled “AlertDialog.Icon”| React | solidtype | Type | Default | Description |
|---|---|---|---|---|
status |
status |
`default | `accent | `success | `warning | `danger |
`danger |
Its colour and icon |
className |
class_ |
string |
Added after HeroUI’s classes | |
children |
children |
elements | An icon of its own |
AlertDialog.Dialog, Header, Body, Footer, Heading, CloseTrigger, Trigger
Section titled “AlertDialog.Dialog, Header, Body, Footer, Heading, CloseTrigger, Trigger”As Modal’s.
Beside React
Section titled “Beside React”Original HeroUI documentation: AlertDialog.
The same HeroUI AlertDialog twice, under the same props: in solidtype on the left, in React on the right. Below them, every attribute of each trigger: a marked row is one they disagree on, and a dimmed row is a framework’s own, which no style reads.
| attribute | solidtype | React |
|---|
