Components
Loading preview...
HeroUI AlertDialog for critical confirmations, with status icons, placements, backdrop variants, sizes, custom icons, dismiss behavior, controlled state and custom trigger examples. Uses the real @heroui/react component with bundled @heroui/styles CSS.
npx shadcn@latest add https://21st.dev/r/hero_ui/heroui-alert-dialog"use client"
import { AlertDialog } from "@/components/ui/heroui-alert-dialog"
import { Button, useOverlayState } from "@heroui/react"
import React from "react"
export default function Controlled() {
const [isOpen, setIsOpen] = React.useState(false)
const state = useOverlayState()
return (
<div className="flex max-w-md flex-col gap-8">
<div className="flex flex-col gap-3">
<h3 className="text-lg font-semibold text-foreground">With React.useState()</h3>
<p className="text-sm leading-relaxed text-muted">Control the alert dialog using React's useState hook for simple state management.</p>
<div className="flex flex-col items-start gap-3 rounded-2xl bg-surface p-4 shadow-sm">
<p className="text-xs text-muted">Status: <span className="font-mono font-medium text-foreground">{isOpen ? "open" : "closed"}</span></p>
<div className="flex gap-2">
<Button size="sm" variant="secondary" onPress={() => setIsOpen(true)}>Open Dialog</Button>
<Button size="sm" variant="tertiary" onPress={() => setIsOpen(!isOpen)}>Toggle</Button>
</div>
</div>
<AlertDialog.Backdrop isOpen={isOpen} onOpenChange={setIsOpen}>
<AlertDialog.Container>
<AlertDialog.Dialog className="sm:max-w-[400px]">
<AlertDialog.CloseTrigger />
<AlertDialog.Header>
<AlertDialog.Icon status="accent" />
<AlertDialog.Heading>Controlled with useState()</AlertDialog.Heading>
</AlertDialog.Header>
<AlertDialog.Body><p>This alert dialog is controlled by React's useState hook. Pass isOpen and onOpenChange props to manage the dialog state externally.</p></AlertDialog.Body>
<AlertDialog.Footer>
<Button slot="close" variant="tertiary">Cancel</Button>
<Button slot="close">Confirm</Button>
</AlertDialog.Footer>
</AlertDialog.Dialog>
</AlertDialog.Container>
</AlertDialog.Backdrop>
</div>
<div className="flex flex-col gap-3">
<h3 className="text-lg font-semibold text-foreground">With useOverlayState()</h3>
<p className="text-sm leading-relaxed text-muted">Use the useOverlayState hook for a cleaner API with open(), close(), and toggle().</p>
<div className="flex flex-col items-start gap-3 rounded-2xl bg-surface p-4 shadow-sm">
<p className="text-xs text-muted">Status: <span className="font-mono font-medium text-foreground">{state.isOpen ? "open" : "closed"}</span></p>
<div className="flex gap-2">
<Button size="sm" variant="secondary" onPress={state.open}>Open Dialog</Button>
<Button size="sm" variant="tertiary" onPress={state.toggle}>Toggle</Button>
</div>
</div>
<AlertDialog.Backdrop isOpen={state.isOpen} onOpenChange={state.setOpen}>
<AlertDialog.Container>
<AlertDialog.Dialog className="sm:max-w-[400px]">
<AlertDialog.CloseTrigger />
<AlertDialog.Header>
<AlertDialog.Icon status="success" />
<AlertDialog.Heading>Controlled with useOverlayState()</AlertDialog.Heading>
</AlertDialog.Header>
<AlertDialog.Body><p>The useOverlayState hook provides dedicated methods for common operations.</p></AlertDialog.Body>
<AlertDialog.Footer>
<Button slot="close" variant="tertiary">Cancel</Button>
<Button slot="close">Confirm</Button>
</AlertDialog.Footer>
</AlertDialog.Dialog>
</AlertDialog.Container>
</AlertDialog.Backdrop>
</div>
</div>
)
}