Overlay
Dialog
A modal dialog with backdrop, keyboard navigation (Esc to close), focus trap, and full WAI-ARIA compliance.
Installation
bash
pnpm dlx shadcn@latest add dialog -c packages/reactBasic Usage
tsx
import {
Dialog, DialogContent, DialogHeader,
DialogTitle, DialogDescription, DialogFooter
} from "@polyui/react/dialog"
import { Button } from "@polyui/react/button"
export function DeleteConfirm() {
return (
<Dialog>
<Button>Open Dialog</Button>
<DialogContent>
<DialogHeader>
<DialogTitle>Confirm Delete</DialogTitle>
<DialogDescription>
This action cannot be undone. Data will be permanently deleted.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button variant="outline">Cancel</Button>
<Button variant="destructive">Delete</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}Controlled
Use open and onOpenChange to fully control the dialog state.
tsx
const [open, setOpen] = useState(false)
<Dialog open={open} onOpenChange={setOpen}>
<Button onClick={() => setOpen(true)}>
Open
</Button>
<DialogContent>
{/* ... */}
</DialogContent>
</Dialog>Basic
Basic Dialogs
vue
import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose } from "@polyui/vue/dialog"
import { Button } from "@polyui/vue/button"
export function DialogBasicDemos() {
return (
<div class="flex flex-wrap gap-3">
<Dialog>
<DialogTrigger as-child>
<Button variant="outline">Basic Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you absolutely sure?</DialogTitle>
<DialogDescription>
This action cannot be undone. This will permanently delete your account and remove your data from our
servers.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose as-child>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button>Continue</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<Dialog>
<DialogTrigger as-child>
<Button variant="outline">Destructive</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader class="items-center">
<DialogTitle>Are you absolutely sure?</DialogTitle>
<DialogDescription class="text-center">
This action cannot be undone. This will permanently delete your account and remove your data from our
servers.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose as-child>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button variant="destructive">Delete</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<Dialog>
<DialogTrigger as-child>
<Button variant="outline">Edit Profile</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Edit profile</DialogTitle>
<DialogDescription>Make changes to your profile here. Click save when you're done.</DialogDescription>
</DialogHeader>
<div class="grid gap-4">
<div class="grid gap-2">
<label for="dlg-name-vue">Name</label>
<input id="dlg-name-vue" value="Pedro Duarte" class="border rounded px-3 py-2 text-sm" />
</div>
<div class="grid gap-2">
<label for="dlg-username-vue">Username</label>
<input id="dlg-username-vue" value="@peduarte" class="border rounded px-3 py-2 text-sm" />
</div>
</div>
<DialogFooter>
<DialogClose as-child>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button type="submit">Save changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<Dialog>
<DialogTrigger as-child>
<Button variant="outline">Terms & Conditions</Button>
</DialogTrigger>
<DialogContent class="sm:max-w-md">
<DialogHeader>
<DialogTitle class="border-b pb-3">Terms and Conditions</DialogTitle>
</DialogHeader>
<div class="text-muted-foreground py-2 text-sm">
<ol class="flex list-decimal flex-col gap-2 pl-4">
<li>
<strong class="text-foreground">Eligibility:</strong> You must be at least 18 years old to use this
service.
</li>
<li>
<strong class="text-foreground">Account Responsibility:</strong> You are responsible for maintaining the
confidentiality of your account and password.
</li>
<li>
<strong class="text-foreground">Usage:</strong> Do not misuse or attempt to disrupt the service.
</li>
<li>
<strong class="text-foreground">Data Collection:</strong> We collect and use your data as described in
our Privacy Policy.
</li>
<li>
<strong class="text-foreground">Modifications:</strong> We reserve the right to update or modify these
terms at any time.
</li>
</ol>
</div>
<DialogFooter>
<DialogClose as-child>
<Button variant="outline">Cancel</Button>
</DialogClose>
<DialogClose as-child>
<Button>I Agree</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
)
}Rich Content
Rich Content
tsx
export function DialogRichContent() {
return (
<div className="flex flex-col gap-3">
<p className="text-xs font-mono text-muted-foreground tracking-widest uppercase">Rich Content</p>
<div className="flex flex-wrap gap-3">
<DialogReferAndEarn />
<DialogRating />
<DialogSignInV2 />
<DialogSignUpV2 />
<DialogInviteV2 />
</div>
</div>
)
}Positioning
Positioning
tsx
export function DialogPositioning() {
return (
<div className="flex flex-col gap-3">
<p className="text-xs font-mono text-muted-foreground tracking-widest uppercase">Positioning</p>
<div className="flex flex-wrap gap-3">
<DialogTopLeft />
<DialogTop />
<DialogTopRight />
<DialogMiddleLeft />
<DialogMiddleRight />
<DialogBottomLeft />
<DialogBottom />
<DialogBottomRight />
</div>
</div>
)
}Animations
Animations
tsx
export function DialogAnimations() {
return (
<div className="flex flex-col gap-3">
<p className="text-xs font-mono text-muted-foreground tracking-widest uppercase">Animations</p>
<div className="flex flex-wrap gap-3">
<DialogSlideToTop />
<DialogSlideToRight />
<DialogZoomIn />
</div>
</div>
)
}Props
Dialog
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
open | boolean | — | Controlled open state |
onOpenChange | (open: boolean) => void | — | State change callback |
defaultOpen | boolean | false | Uncontrolled initial state |
modal | boolean | true | Whether modal (blocks background interaction) |
DialogContent
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
className | string | — | Custom class |
showCloseButton | boolean | true | Show close button |
onEscapeKeyDown | (e: KeyboardEvent) => void | — | Escape key handler |
onPointerDownOutside | (e: PointerEvent) => void | — | Click outside handler |