Shadcn Modal Manager
Radix UI

radixUiDialog

Adapter for Radix UI Dialog component

The radixUiDialog and radixUiDialogContent adapters work with @radix-ui/react-dialog.

Usage

import { Dialog, DialogContent, DialogTitle, DialogDescription } from "@radix-ui/react-dialog";
import { ModalManager, useModal, radixUiDialog, radixUiDialogContent } from "shadcn-modal-manager";

const MyModal = ModalManager.create(() => {
  const modal = useModal();

  return (
    <Dialog {...radixUiDialog(modal)}>
      <DialogContent {...radixUiDialogContent(modal)}>
        <DialogTitle>Edit Profile</DialogTitle>
        <DialogDescription>
          Make changes to your profile here.
        </DialogDescription>
        <button onClick={modal.dismiss}>Cancel</button>
        <button onClick={() => modal.close({ saved: true })}>Save</button>
      </DialogContent>
    </Dialog>
  );
});

API

radixUiDialog

Returns props for the Dialog root component.

const props = radixUiDialog(modal, options?);

Returns:

PropTypeDescription
openbooleanWhether the dialog is visible
onOpenChange(open: boolean) => voidCalled when open state should change

radixUiDialogContent

Returns props for the DialogContent component.

const props = radixUiDialogContent(modal, options?);

Returns:

PropTypeDescription
onAnimationEndCapture() => voidSignals animation completion
onEscapeKeyDown(e?: Event) => voidHandles escape key
onPointerDownOutside(e?: Event) => voidHandles outside click

Options

Both adapters accept AdapterOptions:

interface AdapterOptions {
  disableClose?: boolean;
}

When disableClose is true:

  • Escape key press is prevented
  • Clicking outside doesn't close the dialog
  • onOpenChange(false) is ignored

With Portal and Overlay

For proper layering, use Radix's Portal and Overlay:

import {
  Dialog,
  DialogPortal,
  DialogOverlay,
  DialogContent,
  DialogTitle,
} from "@radix-ui/react-dialog";

const MyModal = ModalManager.create(() => {
  const modal = useModal();

  return (
    <Dialog {...radixUiDialog(modal)}>
      <DialogPortal>
        <DialogOverlay className="fixed inset-0 bg-black/50" />
        <DialogContent
          {...radixUiDialogContent(modal)}
          className="fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-white p-6 rounded-lg"
        >
          <DialogTitle>Modal Title</DialogTitle>
          <button onClick={modal.dismiss}>Close</button>
        </DialogContent>
      </DialogPortal>
    </Dialog>
  );
});

Styling with CSS Animations

Radix Dialog supports CSS animations via data-state:

.dialog-overlay[data-state="open"] {
  animation: fadeIn 150ms ease-out;
}

.dialog-overlay[data-state="closed"] {
  animation: fadeOut 150ms ease-in;
}

.dialog-content[data-state="open"] {
  animation: slideIn 150ms ease-out;
}

.dialog-content[data-state="closed"] {
  animation: slideOut 150ms ease-in;
}

The onAnimationEndCapture prop automatically detects when these animations complete.

On this page