Shadcn Modal Manager
Base UI

baseUiDialog

Adapter for Base UI Dialog component

The baseUiDialog, baseUiDialogPortal, and baseUiDialogPopup adapters work with Base UI (formerly MUI Base).

Base UI provides unstyled, accessible components with CSS data attributes for animations.

Usage

import { Dialog } from "@base-ui-components/react/dialog";
import {
  ModalManager,
  useModal,
  baseUiDialog,
  baseUiDialogPortal,
  baseUiDialogPopup,
} from "shadcn-modal-manager";

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

  return (
    <Dialog.Root {...baseUiDialog(modal)}>
      <Dialog.Portal {...baseUiDialogPortal(modal)}>
        <Dialog.Backdrop className="fixed inset-0 bg-black/50 data-[closed]:opacity-0 transition-opacity" />
        <Dialog.Popup
          {...baseUiDialogPopup(modal)}
          className="fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-white p-6 rounded-lg shadow-xl"
        >
          <Dialog.Title className="text-lg font-semibold">
            Modal Title
          </Dialog.Title>
          <Dialog.Description className="text-gray-600 mt-2">
            Modal description goes here.
          </Dialog.Description>
          <div className="mt-6 flex gap-2 justify-end">
            <button onClick={modal.dismiss} className="px-4 py-2 border rounded">
              Cancel
            </button>
            <button onClick={() => modal.close(true)} className="px-4 py-2 bg-blue-500 text-white rounded">
              Confirm
            </button>
          </div>
        </Dialog.Popup>
      </Dialog.Portal>
    </Dialog.Root>
  );
});

API

baseUiDialog

Returns props for the Dialog.Root component.

const props = baseUiDialog(modal, options?);

Returns:

PropTypeDescription
openbooleanWhether the dialog is visible
onOpenChange(open: boolean) => voidCalled when open state changes
dismissiblebooleanWhether clicking outside/escape closes

baseUiDialogPortal

Returns props for the Dialog.Portal component.

const props = baseUiDialogPortal(modal);

Returns:

PropTypeDescription
keepMountedbooleanKeep portal mounted when closed

baseUiDialogPopup

Returns props for the Dialog.Popup component.

const props = baseUiDialogPopup(modal);

Returns:

PropTypeDescription
onAnimationEnd() => voidSignals animation completion

CSS Data Attributes

Base UI uses data attributes for styling states:

AttributeDescription
data-openPresent when dialog is open
data-closedPresent when dialog is closed
data-enteringPresent during enter animation
data-exitingPresent during exit animation
/* Backdrop animations */
.backdrop {
  transition: opacity 200ms;
}

.backdrop[data-closed] {
  opacity: 0;
}

/* Popup animations */
.popup {
  transition: opacity 200ms, transform 200ms;
}

.popup[data-entering] {
  animation: fadeIn 200ms ease-out;
}

.popup[data-exiting] {
  animation: fadeOut 200ms ease-in;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
}

@keyframes fadeOut {
  from {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
  to {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.95);
  }
}

With Tailwind CSS

Using Tailwind's arbitrary variants:

<Dialog.Backdrop
  className="
    fixed inset-0 bg-black/50
    transition-opacity duration-200
    data-[closed]:opacity-0
  "
/>
<Dialog.Popup
  {...baseUiDialogPopup(modal)}
  className="
    fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2
    bg-white p-6 rounded-lg shadow-xl
    data-[entering]:animate-in data-[entering]:fade-in-0 data-[entering]:zoom-in-95
    data-[exiting]:animate-out data-[exiting]:fade-out-0 data-[exiting]:zoom-out-95
  "
/>

Keep Mounted

The baseUiDialogPortal adapter respects keepMounted from the modal:

// Open with keepMounted
ModalManager.open(MyModal, { keepMounted: true });

// The portal will stay in the DOM after closing
// Useful for preserving form state or heavy components

Compared to Radix

FeatureRadix UIBase UI
StylingCSS/classNameData attributes
Animation detectiononAnimationEndCaptureonAnimationEnd
PortalAutomaticExplicit Dialog.Portal
Keep mountedVia adapterVia Dialog.Portal prop

On this page