Dialog

A modal window layered above the page, with focus trapped inside.

import {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogHeader,
  DialogFooter,
  DialogTitle,
  DialogDescription,
  DialogClose,
} from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'

export default function DialogDemo() {
  return (
    <Dialog>
      <DialogTrigger render={<Button variant="outline">Edit profile</Button>} />
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Edit profile</DialogTitle>
          <DialogDescription>Make changes to your profile here. Click save when you&apos;re done.</DialogDescription>
        </DialogHeader>
        <div className="grid gap-3">
          <div className="grid gap-1.5">
            <Label htmlFor="dialog-name">Name</Label>
            <Input id="dialog-name" defaultValue="Ada Lovelace" />
          </div>
          <div className="grid gap-1.5">
            <Label htmlFor="dialog-username">Username</Label>
            <Input id="dialog-username" defaultValue="@ada" />
          </div>
        </div>
        <DialogFooter>
          <DialogClose render={<Button variant="outline">Cancel</Button>} />
          <DialogClose render={<Button>Save changes</Button>} />
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

Built on Base UI

Installation

pnpm dlx shadcn@latest add https://kagadmodyaa.vercel.app/r/dialog.json

Needs a React + Tailwind project set up with shadcn. Copies the component source straight into your project, so you can edit it.

Dialog imports cn() from lib/utils.ts — add it too if you don't have it yet:

import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

Usage

import {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogHeader,
  DialogFooter,
  DialogTitle,
  DialogDescription,
  DialogClose,
} from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'

<Dialog>
  <DialogTrigger render={<Button variant="outline">Edit profile</Button>} />
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Edit profile</DialogTitle>
      <DialogDescription>Make changes to your profile here.</DialogDescription>
    </DialogHeader>
    <DialogFooter>
      <DialogClose render={<Button>Save changes</Button>} />
    </DialogFooter>
  </DialogContent>
</Dialog>

API Reference

NameTypeDefaultDescription
open / onOpenChangeboolean / (open: boolean) => void—Control the open state from outside (set on Dialog).
defaultOpenbooleanfalseInitial open state (uncontrolled).
modalboolean | 'trap-focus'trueTraps focus and locks page scroll while open.
DialogTrigger renderReactElement—Renders the trigger as a different element, e.g. a Button.
DialogContent showCloseButtonbooleantrueShows the corner close button. Turn it off when the content has its own dismiss control.
DialogClose renderReactElement—Renders a close control as a different element.