Examples
Focused task
A named, described modal task returns focus to its trigger when closed.
Dialog preview with scrollable content and stable actions
"use client";
import { Button } from "@phuctech/ui/components/button";
import {
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@phuctech/ui/components/dialog";
export function Example() {
return (
<Dialog>
<DialogTrigger render={<Button>Review changes</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Review changes</DialogTitle>
<DialogDescription>Confirm the update before it is applied.</DialogDescription>
</DialogHeader>
<DialogBody>Long content belongs in this scrollable region.</DialogBody>
<DialogFooter>
<DialogClose render={<Button variant="outline">Cancel</Button>} />
<Button>Apply changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
Form in a Dialog
Small forms keep their validation and business state in the feature.
Dialog containing a small form
"use client";
import { Button } from "@phuctech/ui/components/button";
import {
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@phuctech/ui/components/dialog";
export function Example() {
return (
<Dialog>
<DialogTrigger render={<Button>Review changes</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Review changes</DialogTitle>
<DialogDescription>Confirm the update before it is applied.</DialogDescription>
</DialogHeader>
<DialogBody>Long content belongs in this scrollable region.</DialogBody>
<DialogFooter>
<DialogClose render={<Button variant="outline">Cancel</Button>} />
<Button>Apply changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}Delete confirmation
Destructive actions name the exact target and keep Cancel first.
Dialog confirmation for a destructive action
"use client";
import { Button } from "@phuctech/ui/components/button";
import {
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@phuctech/ui/components/dialog";
export function Example() {
return (
<Dialog>
<DialogTrigger render={<Button>Review changes</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Review changes</DialogTitle>
<DialogDescription>Confirm the update before it is applied.</DialogDescription>
</DialogHeader>
<DialogBody>Long content belongs in this scrollable region.</DialogBody>
<DialogFooter>
<DialogClose render={<Button variant="outline">Cancel</Button>} />
<Button>Apply changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}Processing and error
In-flight and failure feedback stay explicit before the modal closes.
Dialog with simulated processing and error feedback
"use client";
import { Button } from "@phuctech/ui/components/button";
import {
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@phuctech/ui/components/dialog";
export function Example() {
return (
<Dialog>
<DialogTrigger render={<Button>Review changes</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Review changes</DialogTitle>
<DialogDescription>Confirm the update before it is applied.</DialogDescription>
</DialogHeader>
<DialogBody>Long content belongs in this scrollable region.</DialogBody>
<DialogFooter>
<DialogClose render={<Button variant="outline">Cancel</Button>} />
<Button>Apply changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}Long content
DialogBody is the bounded scroll region; header and footer remain visible.
Dialog with long scrollable content
"use client";
import { Button } from "@phuctech/ui/components/button";
import {
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@phuctech/ui/components/dialog";
export function Example() {
return (
<Dialog>
<DialogTrigger render={<Button>Review changes</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Review changes</DialogTitle>
<DialogDescription>Confirm the update before it is applied.</DialogDescription>
</DialogHeader>
<DialogBody>Long content belongs in this scrollable region.</DialogBody>
<DialogFooter>
<DialogClose render={<Button variant="outline">Cancel</Button>} />
<Button>Apply changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}When to use
Use Dialog when the task needs attention before the person can continue. Use a page for a substantial workflow, and use Tooltip for short supplemental context.
Reviewing changes, editing a small record, or confirming a consequential action.
Do not put a multi-step workflow or a long required form into a small modal.
Usage
"use client";
import { Button } from "@phuctech/ui/components/button";
import {
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@phuctech/ui/components/dialog";
export function Example() {
return (
<Dialog>
<DialogTrigger render={<Button>Review changes</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Review changes</DialogTitle>
<DialogDescription>Confirm the update before it is applied.</DialogDescription>
</DialogHeader>
<DialogBody>Long content belongs in this scrollable region.</DialogBody>
<DialogFooter>
<DialogClose render={<Button variant="outline">Cancel</Button>} />
<Button>Apply changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
Composition
Give the Dialog a trigger, title, and description. Put long content in DialogBody so the body scrolls while DialogHeader and DialogFooter remain visible. Use DialogClose for cancel or explicit close actions.
- Use a real Button or IconButton as the trigger through
render. - Keep the primary action in the footer and disable it while an operation is in flight.
- Confirm destructive actions in a dedicated, clearly worded step.
API
Tokens
Accessibility
- Every dialog needs a title; add a description when the task needs context.
- Verify focus enters the popup, stays inside while modal, closes with Escape, and returns to the trigger.
- Keep the growing body scrollable; do not clip long content behind the footer.
Do and don’t
Use a specific title, stable actions, and a body region that can scroll on a small viewport.
Open a dialog for passive information, hide the only close action, or nest unrelated dialogs.