Dialog
A modal window over a blurred backdrop that springs up into place.
pnpm exec shadcn add @intelligo/dialogInside an app made by intelligo create, or any shadcn project that names the registry.
used by these pages
Team Settings, Workspace Settings, Feature Gating, QR Payment (poll), Profile Settings, Artifacts, Chat
more in primitives
Alert dialog, Button, Dropdown menu, Input, Popover, Progress, Select, Sheet, Sidebar, Tabs, Textarea, Tooltip, Checkbox, Radio group, Switch, Collapsible, Command
Source
What shadcn add writes to components/ui/dialog.tsx. It is yours from then on.
"use client";
/*
* The dialog: a blurred backdrop and a panel that springs up from slightly
* smaller. Backdrop and panel animate with motion; the root is kept
* controlled so the exit plays.
*/
import * as React from "react";
import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
import { XIcon } from "lucide-react";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
import {
backdropMotion,
popupMotion,
useOpenState,
} from "@showcase/components/ui/ai-motion";
import { Button } from "@showcase/components/ui/button";
import { cn } from "@showcase/lib/utils";
const DialogOpenContext = React.createContext<boolean | null>(null);
const OVERLAY =
"fixed inset-0 isolate z-overlay bg-background/60 supports-backdrop-filter:backdrop-blur-sm";
function Dialog({
open: openProp,
defaultOpen,
onOpenChange,
...props
}: DialogPrimitive.Root.Props) {
const [open, setOpen] = useOpenState(openProp, defaultOpen, onOpenChange);
return (
<DialogOpenContext.Provider value={open}>
<DialogPrimitive.Root
data-slot="dialog"
open={open}
onOpenChange={setOpen}
{...props}
/>
</DialogOpenContext.Provider>
);
}
function DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
}
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(
OVERLAY,
"transition-[opacity,backdrop-filter] duration-normal ease-standard data-starting-style:opacity-0 data-ending-style:opacity-0 data-ending-style:duration-fast",
className
)}
{...props}
/>
);
}
function DialogContent({
className,
children,
showCloseButton = true,
...props
}: DialogPrimitive.Popup.Props & {
showCloseButton?: boolean;
}) {
const open = React.useContext(DialogOpenContext) ?? true;
const reduced = useReducedMotion() ?? false;
return (
<AnimatePresence>
{open && (
<DialogPrimitive.Portal data-slot="dialog-portal" keepMounted>
<DialogPrimitive.Backdrop
data-slot="dialog-overlay"
render={<motion.div {...backdropMotion(reduced)} />}
className={OVERLAY}
/>
<DialogPrimitive.Popup
data-slot="dialog-content"
render={<motion.div {...popupMotion(reduced, 0.94)} />}
className={cn(
"fixed top-1/2 left-1/2 z-modal grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl border border-border bg-popover p-5 text-sm text-popover-foreground shadow-2xl outline-none sm:max-w-sm",
className
)}
{...props}
>
{children}
{showCloseButton && (
<DialogPrimitive.Close
data-slot="dialog-close"
render={
<Button
variant="ghost"
className="absolute top-3 right-3"
size="icon-sm"
/>
}
>
<XIcon />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
)}
</DialogPrimitive.Popup>
</DialogPrimitive.Portal>
)}
</AnimatePresence>
);
}
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="dialog-header"
className={cn("flex flex-col gap-2", className)}
{...props}
/>
);
}
function DialogFooter({
className,
showCloseButton = false,
children,
...props
}: React.ComponentProps<"div"> & {
showCloseButton?: boolean;
}) {
return (
<div
data-slot="dialog-footer"
className={cn(
"-mx-5 -mb-5 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/60 px-5 py-4 sm:flex-row sm:justify-end",
className
)}
{...props}
>
{children}
{showCloseButton && (
<DialogPrimitive.Close render={<Button variant="outline" />}>
Close
</DialogPrimitive.Close>
)}
</div>
);
}
function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
return (
<DialogPrimitive.Title
data-slot="dialog-title"
className={cn(
"font-heading text-base leading-none font-medium",
className
)}
{...props}
/>
);
}
function DialogDescription({
className,
...props
}: DialogPrimitive.Description.Props) {
return (
<DialogPrimitive.Description
data-slot="dialog-description"
className={cn(
"text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
className
)}
{...props}
/>
);
}
export {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogOverlay,
DialogPortal,
DialogTitle,
DialogTrigger,
};Ready to try it? Three commands and the app runs against a stub model.