Dialog
dialogPresents modal content in a portal with focus trapping.
Usage
Basic usage
Trigger, Portal + focus trap: Esc close, focus return trigger button.
<Dialog>
<DialogTrigger render={<Button variant="outline">Open dialog box</Button>} />
<DialogContent title="Hulian Dialog Box" description="Auxiliary explanation copy under the title.">
<div className="flex justify-end gap-2">
<DialogClose render={<Button variant="ghost">Cancel</Button>} />
<DialogClose render={<Button>OK</Button>} />
</div>
</DialogContent>
</Dialog>footer operating area
Use footer slot to place the bottom operation button, automatically with top divider and right alignment.
<Dialog>
<DialogTrigger render={<Button>Delete item</Button>} />
<DialogContent
title="Confirm deletion"
description="This operation is irreversible. Are you sure you want to delete this item?"
footer={
<>
<DialogClose render={<Button variant="ghost">Cancel</Button>} />
<DialogClose render={<Button tone="danger">Delete</Button>} />
</>
}
/>
</Dialog>Open by default
Uncontrolled use defaultOpen to make the dialog box expand initially.
<Dialog defaultOpen>
<DialogTrigger render={<Button variant="outline">Open dialog box</Button>} />
<DialogContent title="Welcome" description="The dialog box is initially open.">
<div className="flex justify-end">
<DialogClose render={<Button>Got it</Button>} />
</div>
</DialogContent>
</Dialog>When to use
Use Dialog to interrupt the current flow with a form, details, or confirmation above an overlay. It includes a Portal, focus containment, and Escape dismissal. Use Modal for one-line imperative confirm or status calls, AlertDialog when the user must explicitly decide, or Drawer for a sliding panel.
Import
import { Dialog, DialogTrigger, DialogClose, DialogContent } from "@hulianui/ui"Props
Dialog, DialogTrigger, and DialogClose are thin wrappers around the matching Base UI primitives. Dialog forwards Root props such as open, defaultOpen, and onOpenChange; Trigger and Close support render to supply the rendered element. DialogContent adds HulianUI styling:
| Name | Type | Default | Description |
|---|---|---|---|
DialogContent.title * | string | — | Visible title and accessible label. |
DialogContent.description | string | — | Supporting copy. |
DialogContent.className | string | — | Content-container class name. |
Events
| Event | Type | Description |
|---|---|---|
Dialog.onOpenChange | (open: boolean) => void | Called when the open state changes; forwarded to Base UI Dialog Root. |
Slots
| Slot | Type | Description |
|---|---|---|
DialogContent.footer | ReactNode | Action area below the body with a top divider and right alignment, matching DrawerContent. |
DialogContent.children | ReactNode | Main body content. |
Example
<Dialog>
<DialogTrigger render={<Button variant="outline">Open dialog</Button>} />
<DialogContent title="Hulian dialog" description="Focus stays inside, Escape closes, and focus returns to the trigger.">
<div className="flex justify-end gap-2">
<DialogClose render={<Button variant="ghost">Cancel</Button>} />
<DialogClose render={<Button>Confirm</Button>} />
</div>
</DialogContent>
</Dialog>Usage guidelines
- Use
render={<Button … />}on DialogTrigger and DialogClose to merge behavior into the target element. Do not wrap another button around them; that creates nested interactive elements and duplicate click handling. - Prefer the
footerslot for actions so it receives the divider and alignment, leavingchildrenfor primary content.
Related
Modal · AlertDialog · Drawer · Popover · Tooltip · HoverCard