Elements

Components / Base

Dialog

A window overlaid on the primary view, rendering content underneath inert. Based on shadcn/ui Dialog, built on Base UI with Instant Strata styling.

Installation

bash
npx shadcn add https://raw.githubusercontent.com/levi-putna/elements/main/registry/dialog/registry.json

Usage

tsx
import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"

export function Example() {
  return (
    <Dialog>
      <DialogTrigger render={<Button variant="outline" />}>
        Open dialog
      </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

text
Dialog
├── DialogTrigger
└── DialogContent
    ├── DialogHeader
    │   ├── DialogTitle
    │   └── DialogDescription
    └── DialogFooter

Examples

Default

Title, description, and a top-right close control.

Open dialog

No close button

Hide the icon close control and rely on footer actions instead.

No close button
tsx
<DialogContent showCloseButton={false}>
  <DialogHeader>
    <DialogTitle>No close button</DialogTitle>
    <DialogDescription>
      Use the footer actions or press Escape to dismiss.
    </DialogDescription>
  </DialogHeader>
  <DialogFooter showCloseButton>
    <Button variant="default">Confirm</Button>
  </DialogFooter>
</DialogContent>

Sticky footer

Keep actions visible while form fields scroll in the body.

Sticky footer
tsx
<DialogContent className="flex max-h-[min(520px,85vh)] min-h-0 flex-col gap-0 overflow-hidden p-0 sm:max-w-md">
  <DialogHeader className="shrink-0 px-4 pt-4">
    <DialogTitle>Sticky footer</DialogTitle>
    <DialogDescription>
      Actions stay visible while the body scrolls.
    </DialogDescription>
  </DialogHeader>
  <div className="min-h-0 flex-1 overflow-y-auto px-4 py-2">
    {/* long form fields */}
  </div>
  <DialogFooter bleed={false}>
    <DialogClose render={<Button variant="outline" />}>Cancel</DialogClose>
    <Button>Save changes</Button>
  </DialogFooter>
</DialogContent>

Scrollable content

Long copy scrolls inside the panel while the header remains fixed.

Scrollable content
tsx
<DialogContent className="flex max-h-[min(520px,85vh)] min-h-0 flex-col gap-0 overflow-hidden p-0 sm:max-w-md">
  <DialogHeader className="shrink-0 px-4 pt-4">
    <DialogTitle>Scrollable content</DialogTitle>
    <DialogDescription>
      The header stays in view while the body scrolls.
    </DialogDescription>
  </DialogHeader>
  <div className="min-h-0 flex-1 overflow-y-auto px-4 pb-4">
    {/* long content */}
  </div>
</DialogContent>

Props

DialogContent

PropTypeDefaultDescription
showCloseButtonbooleantrueWhen true, renders a ghost icon button in the top-right corner of the panel.
classNamestring-Additional classes on the popup. Use flex column layouts with max-height for scrollable bodies.

DialogFooter

PropTypeDefaultDescription
bleedbooleantrueWhen true, extends the footer to the dialog edges inside padded content. Set false for sticky p-0 layouts.
showCloseButtonbooleanfalseWhen true, appends an outline Close button after footer children.