Dialog

Dialog allows you to create modal elements that overlay the main content.

Dependencies

Source Code

"use client";
 
import {
  Modal,
  ModalTrigger,
  ModalContent,
  ModalClose,
  ModalTitle,
  ModalDescription,
} from "@/components/modal";
import { cn } from "@/lib/utils";
 
type DialogProps = React.ComponentProps<typeof Modal>;
 
const Dialog = ({ ...props }: DialogProps) => {
  return <Modal {...props} />;
};
 
interface DialogContentProps extends React.ComponentProps<typeof ModalContent> {
  align?: "center" | "top";
}
 
const DialogContent = ({
  className,
  children,
  align = "center",
  ...props
}: DialogContentProps) => {
  return (
    <ModalContent
      className={cn(
        "bg-background border-border m-auto w-full max-w-md rounded-3xl border p-4 shadow-lg",
        "max-h-[calc(100svh-2rem)] overflow-y-auto backdrop:bg-black/20 backdrop:backdrop-blur-sm",
        "transition-all duration-300 backdrop:transition-all motion-reduce:transition-none motion-reduce:backdrop:transition-none",
        "not-data-[status=open]:translate-y-2 not-data-[status=open]:scale-95 not-data-[status=open]:opacity-0 not-data-[status=open]:duration-150 not-data-[status=open]:backdrop:opacity-0",
        align === "top" && "mt-4",
        className
      )}
      {...props}
    >
      {children}
    </ModalContent>
  );
};
 
const DialogTrigger = ModalTrigger;
 
const DialogClose = ModalClose;
 
const DialogTitle = ({
  children,
  className,
  ...props
}: React.ComponentProps<typeof ModalTitle>) => {
  return (
    <ModalTitle className={cn("pb-2 font-semibold", className)} {...props}>
      {children}
    </ModalTitle>
  );
};
 
const DialogDescription = ({
  children,
  className,
  ...props
}: React.ComponentProps<typeof ModalDescription>) => {
  return (
    <ModalDescription className={cn("pb-2", className)} {...props}>
      {children}
    </ModalDescription>
  );
};
 
const DialogActions = ({
  className,
  children,
  ...props
}: React.ComponentPropsWithRef<"div">) => (
  <div
    className={cn(
      "flex flex-col gap-2 pt-4 sm:flex-row sm:justify-start",
      className
    )}
    {...props}
  >
    {children}
  </div>
);
 
export {
  Dialog,
  DialogContent,
  DialogTrigger,
  DialogClose,
  DialogTitle,
  DialogDescription,
  DialogActions,
};

Features

  • Modal Overlay: Creates an accessible modal dialog with backdrop
  • Focus Management: Automatically traps focus within the dialog
  • Flexible Positioning: Center or top alignment options
  • Controlled & Uncontrolled: Supports both controlled and uncontrolled modes
  • Customizable Actions: Built-in support for common dialog actions

Anatomy

<Dialog>
  <DialogTrigger />
  <DialogContent>
    <DialogTitle />
    <DialogClose />
    <DialogDescription />
    <DialogActions />
  </Dialog.Content>
</Dialog>

API Reference

Dialog

Extends the Modal component.

DialogTrigger

Extends the ModalTrigger component.

DialogContent

Extends the ModalContent component.

PropDefaultTypeDescription

align

"center"

"center"

"top"

The vertical alignment of the dialog.

DialogTitle

Extends the ModalTitle component.

DialogDescription

Extends the ModalDescription component.

DialogActions

Extends the div element.

This component is designed to be placed at the bottom of the dialog content, providing a consistent layout for action buttons such as "Cancel" and "Confirm".

DialogClose

Extends the ModalClose component.

PropDefaultTypeDescription

asChild

-

boolean

Whether to merge props onto the child element.

Examples

Simple

A basic dialog with a title and actions.

Align to the top

Dialog aligned to the top of the screen.

Destructive

A dialog for destructive actions with appropriate styling.

Tall content

Dialog with scrollable content.

Arbitrary content

Dialog with custom content layout.

Best Practices

  1. Content Structure:

    • Always include a clear title that describes the purpose
    • Keep content concise and focused
    • Use appropriate action labels (avoid "OK/Cancel")
  2. Mobile Considerations:

    • Test on different screen sizes
    • Ensure touch targets are large enough
    • Consider native scroll behavior for tall content
  3. Performance:

    • Lazy load dialog content if needed
    • Consider using dynamic imports for heavy content
    • Clean up resources when dialog closes