Dialog
A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
Installation
Install the following dependencies:
pnpm add @radix-ui/react-dialog
Copy and paste the following code into your project.
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { XIcon } from "lucide-react";
import { Button } from "~/components/ui/Button";
import {
dialogContentVariants,
dialogDescriptionVariants,
dialogFooterVariants,
dialogHeaderVariants,
dialogOverlayVariants,
dialogTitleVariants,
} from "~/components/ui/_Dialog";
const Dialog = DialogPrimitive.Root;
const DialogTrigger = DialogPrimitive.Trigger;
const DialogPortal = DialogPrimitive.Portal;
const DialogClose = DialogPrimitive.Close;
function DialogOverlay({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
return (
<DialogPrimitive.Overlay
className={dialogOverlayVariants({ className })}
{...props}
/>
);
}
function DialogContent({
className,
children,
showCloseButton = true,
...props
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
showCloseButton?: boolean;
}) {
return (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content
className={dialogContentVariants({ className })}
{...props}
>
{children}
{showCloseButton && (
<DialogPrimitive.Close asChild>
<Button variant="ghost" size="sm" subject="icon">
<XIcon />
<span className="sr-only">Close</span>
</Button>
</DialogPrimitive.Close>
)}
</DialogPrimitive.Content>
</DialogPortal>
);
}
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
return <div className={dialogHeaderVariants({ className })} {...props} />;
}
function DialogBody({ className, ...props }: React.ComponentProps<"div">) {
return <div className={className} {...props} />;
}
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
return <div className={dialogFooterVariants({ className })} {...props} />;
}
function DialogTitle({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
return (
<DialogPrimitive.Title
className={dialogTitleVariants({ className })}
{...props}
/>
);
}
function DialogDescription({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
return (
<DialogPrimitive.Description
className={dialogDescriptionVariants({ className })}
{...props}
/>
);
}
export {
Dialog,
DialogPortal,
DialogOverlay,
DialogTrigger,
DialogClose,
DialogContent,
DialogHeader,
DialogBody,
DialogFooter,
DialogTitle,
DialogDescription,
};
Update the import paths to match your project setup.
Usage
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "~/components/ui/Dialog";
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">Edit Profile</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Edit Profile</DialogTitle>
<DialogDescription>
Make changes to your profile here. Click save afterwards.
</DialogDescription>
</DialogHeader>
<div className="grid grid-cols-4 items-center gap-x-4 gap-y-3">
<Label htmlFor="name" className="text-right">
Name
</Label>
<Input id="name" value="Pedro Duarte" className="col-span-3" />
</div>
<DialogFooter>
<Button type="submit">Save Changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>