Get Started
Input
Feedback
Display
Installation
i18n
A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
import { Button } from "@/components/ui/button"
import {
Dialog,Installation#
pnpm dlx shadcn@latest add https://ui.tyap.me/r/styles/base/dialog.jsonnpx shadcn@latest add https://ui.tyap.me/r/styles/base/dialog.jsonyarn dlx shadcn@latest add https://ui.tyap.me/r/styles/base/dialog.jsonbunx --bun shadcn@latest add https://ui.tyap.me/r/styles/base/dialog.json
Install the following dependencies:
pnpm add @base-ui/reactnpm install @base-ui/reactyarn add @base-ui/reactbun add @base-ui/react
Copy and paste the following code into your project.
"use client"
import * as React from "react"
import { Dialog as DialogPrimitive } from "@base-ui/react/dialog"
import { cn } from "@/lib/utils"
import {
DIALOG_CONTENT_BASE_CLASSES,
DIALOG_OVERLAY_CLASSES,
DialogDragHandle,
} from "@/components/ui/_dialog-shared"
import { Button } from "@/components/ui/button"
function Dialog({ ...props }: DialogPrimitive.Root.Props) {
return <DialogPrimitive.Root data-slot="dialog" {...props} />
}
function DialogTrigger({
asChild,
children,
render,
...props
}: DialogPrimitive.Trigger.Props & {
asChild?: boolean
children?: React.ReactNode
}) {
let resolvedRender =
asChild && React.isValidElement(children) ? children : render
if (React.isValidElement(resolvedRender)) {
resolvedRender = React.cloneElement(
resolvedRender as React.ReactElement<{ "data-slot"?: string }>,
{ "data-slot": "dialog-trigger" }
)
}
return (
<DialogPrimitive.Trigger
data-slot="dialog-trigger"
render={resolvedRender}
{...props}
>
{asChild ? undefined : children}
</DialogPrimitive.Trigger>
)
}
function DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
}
function DialogClose({ ...props }: DialogPrimitive.Close.Props) {
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
}
function DialogOverlay({
className,
...props
}: DialogPrimitive.Backdrop.Props) {
return (
<DialogPrimitive.Backdrop
data-slot="dialog-overlay"
className={cn(DIALOG_OVERLAY_CLASSES, className)}
{...props}
/>
)
}
function DialogContent({
className,
children,
...props
}: DialogPrimitive.Popup.Props) {
return (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Popup
data-slot="dialog-content"
className={cn(DIALOG_CONTENT_BASE_CLASSES, "sm:max-w-md", className)}
{...props}
>
<DialogDragHandle />
{children}
</DialogPrimitive.Popup>
</DialogPortal>
)
}
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="dialog-header"
className={cn("flex flex-col", className)}
{...props}
/>
)
}
function DialogFooter({
className,
showCloseButton = false,
children,
...props
}: React.ComponentProps<"div"> & {
showCloseButton?: boolean
}) {
return (
<div
data-slot="dialog-footer"
className={cn(
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
className
)}
{...props}
>
{children}
{showCloseButton && (
<DialogPrimitive.Close nativeButton render={<Button variant="outline">Close</Button>} />
)}
</div>
)
}
function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
return (
<DialogPrimitive.Title
data-slot="dialog-title"
className={cn("cn-font-heading", className)}
{...props}
/>
)
}
function DialogDescription({
className,
...props
}: DialogPrimitive.Description.Props) {
return (
<DialogPrimitive.Description
data-slot="dialog-description"
className={cn(className)}
{...props}
/>
)
}
export {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogOverlay,
DialogPortal,
DialogTitle,
DialogTrigger,
}
Update the import paths to match your project setup.
Usage#
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"<Dialog>
<DialogTrigger>Open</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>
</DialogContent>
</Dialog>Composition#
Use the following composition to build a Dialog:
Dialog
├── DialogTrigger
└── DialogContent
├── DialogHeader
│ ├── DialogTitle
│ └── DialogDescription
└── DialogFooterExamples#
Custom Close Button#
Replace the default close control with your own button.
import { Button } from "@/components/ui/button"
import {
Dialog,No Close Button#
Use showCloseButton={false} to hide the close button.
import { Button } from "@/components/ui/button"
import {
Dialog,Sticky Footer#
Keep actions visible while the content scrolls.
import { Button } from "@/components/ui/button"
import {
Dialog,Scrollable Content#
Long content can scroll while the header stays in view.
import { Button } from "@/components/ui/button"
import {
Dialog,RTL#
To enable RTL support in shadcn/ui, see the RTL configuration guide.
"use client"
import {API Reference#
See the Base UI documentation for more information.