logoPressFast

Dialog

Modal dialog component

Dialog

A modal dialog component for important interactions.

Usage

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

export function Example() {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button>Open Dialog</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Dialog Title</DialogTitle>
          <DialogDescription>
            This is a description of the dialog.
          </DialogDescription>
        </DialogHeader>
        <div className="py-4">
          Dialog content goes here
        </div>
      </DialogContent>
    </Dialog>
  );
}

Controlled Dialog

'use client';

import { useState } from 'react';

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

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button>Open</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Controlled Dialog</DialogTitle>
        </DialogHeader>
        <div className="py-4">
          <p>This dialog is controlled</p>
          <Button onClick={() => setOpen(false)} className="mt-4">
            Close
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
}

Confirmation Dialog

export function ConfirmDialog({ onConfirm }) {
  const [open, setOpen] = useState(false);

  const handleConfirm = () => {
    onConfirm();
    setOpen(false);
  };

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button variant="destructive">Delete</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Are you sure?</DialogTitle>
          <DialogDescription>
            This action cannot be undone. This will permanently delete your data.
          </DialogDescription>
        </DialogHeader>
        <div className="flex justify-end gap-2 mt-4">
          <Button variant="outline" onClick={() => setOpen(false)}>
            Cancel
          </Button>
          <Button variant="destructive" onClick={handleConfirm}>
            Delete
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
}

Form Dialog

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

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    // Handle form submission
    setOpen(false);
  };

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button>Create New</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Create Item</DialogTitle>
          <DialogDescription>
            Fill in the details below
          </DialogDescription>
        </DialogHeader>
        <form onSubmit={handleSubmit} className="space-y-4">
          <div>
            <label htmlFor="name" className="block text-sm font-medium mb-2">
              Name
            </label>
            <Input id="name" required />
          </div>
          <div>
            <label htmlFor="description" className="block text-sm font-medium mb-2">
              Description
            </label>
            <Textarea id="description" />
          </div>
          <div className="flex justify-end gap-2">
            <Button type="button" variant="outline" onClick={() => setOpen(false)}>
              Cancel
            </Button>
            <Button type="submit">Create</Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
}

Scrollable Dialog

<Dialog>
  <DialogTrigger asChild>
    <Button>Open Long Content</Button>
  </DialogTrigger>
  <DialogContent className="max-h-[80vh] overflow-y-auto">
    <DialogHeader>
      <DialogTitle>Long Content</DialogTitle>
    </DialogHeader>
    <div className="py-4">
      {/* Long scrollable content */}
      <p>Lorem ipsum dolor sit amet...</p>
    </div>
  </DialogContent>
</Dialog>

Custom Width

<DialogContent className="max-w-2xl">
  {/* Wider dialog content */}
</DialogContent>

Props

Dialog

PropTypeDescription
openbooleanControlled open state
onOpenChange(open: boolean) => voidCallback when open state changes
defaultOpenbooleanDefault open state
modalbooleanWhether dialog is modal (default: true)

DialogContent

PropTypeDescription
classNamestringAdditional CSS classes
childrenReactNodeDialog content

Best Practices

  1. Use for important actions: Don't overuse dialogs
  2. Keep content focused: One clear purpose per dialog
  3. Provide clear actions: Make it obvious what users should do
  4. Handle escape key: Allow users to dismiss easily
  5. Mobile responsive: Test on different screen sizes

Accessibility

The dialog component is built with accessibility in mind:

  • Focus trap keeps focus within dialog
  • Escape key closes dialog
  • Click outside closes dialog
  • Proper ARIA attributes
  • Screen reader support

Next Steps

Dialog