Back to Design System

Dialog

Modal overlay built on Radix Dialog primitives. Handles focus trapping, escape key, and overlays that respect Pixexid’s motion tokens.

Overview

Use for

  • Blocking confirmations, forms, or creation flows.
  • Previewing larger assets without leaving the page.
  • Communicating critical system feedback (errors, required upgrades).

Avoid for

  • Passive notifications—use `Toast` or `Sonner` integration.
  • Lightweight tooltips or menus; they should not block background interaction.
  • Mobile full-screen flows; consider dedicated routes.

Examples

Invite flow

<Dialog>
  <DialogTrigger asChild>
    <Button>Invite teammate</Button>
  </DialogTrigger>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Invite teammate</DialogTitle>
      <DialogDescription>
        Send a one-time invite link to join your workspace.
      </DialogDescription>
    </DialogHeader>
    <form className="space-y-4">
      <div className="space-y-2">
        <Label htmlFor="email">Email</Label>
        <Input id="email" type="email" placeholder="teammate@pixexid.com" />
      </div>
      <DialogFooter>
        <DialogClose asChild>
          <Button type="button" variant="ghost">Cancel</Button>
        </DialogClose>
        <Button type="submit">Send invite</Button>
      </DialogFooter>
    </form>
  </DialogContent>
</Dialog>

Controlled dialog

import { useState } from "react"
import { Dialog, DialogTrigger, DialogContent } from "@/components/ui/dialog"

export function ControlledDialog() {
  const [open, setOpen] = useState(false)

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button variant="outline">Open dialog</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Dialog title</DialogTitle>
          <DialogDescription>Controlled with React state.</DialogDescription>
        </DialogHeader>
        <DialogFooter>
          <DialogClose asChild>
            <Button variant="ghost">Close</Button>
          </DialogClose>
          <Button onClick={() => setOpen(false)}>Confirm</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

Props

PropTypeDefaultDescription
openbooleanControls the dialog in a controlled pattern. Pair with `onOpenChange`.
defaultOpenbooleanfalseInitial open state for uncontrolled usage.
onOpenChange(open: boolean) => voidCallback invoked when the dialog requests to open or close.
modalbooleantrueRadix option to trap focus; leave true for Pixexid modals.

Accessibility

Keyboard

  • Tab stays trapped inside the dialog while open.
  • Esc closes the dialog.
  • `DialogClose` ensures buttons and links dismiss the overlay and return focus to the trigger.

Best practices

  • Always provide `DialogTitle` and `DialogDescription` to communicate context quickly.
  • Keep content concise—move multi-step flows to dedicated pages.
  • Use `aria-describedby` via `DialogDescription` for screen-reader hints.