Magic Modallatest
API reference

magicModal

Show, hide, and configure stack entries from application code.

magicModal is the global imperative API. Its methods target the MagicModalPortal mounted in the active React tree.

show

show<T>(
  component: React.FC,
  config?: Partial<ModalProps>,
): ModalHandle<T>

type ModalHandle<T> = Promise<HideReturn<T>> & {
  modalID: string;
  update: (next: React.FC) => void;
  hide: (data?: T) => void;
  /** @deprecated await the handle directly */
  promise: Promise<HideReturn<T>>;
};

Pushes a modal to the top of the stack. The returned handle is the promise, so await it:

const result = await magicModal.show<Profile>(() => <ProfilePicker />, {
  accessibilityLabel: "Choose a profile",
  backdropColor: "rgba(7, 6, 18, 0.72)",
  swipeDirection: "down",
});

Keep the handle instead when the caller needs to drive the modal while it is open:

const handle = magicModal.show<Profile>(() => <ProfilePicker />);

handle.update(() => <ProfilePicker step={2} />);
handle.hide({ id: "cached" });
MemberPurpose
awaitedResolves once when this modal closes.
modalIDAddresses this exact entry from outside its component.
updateAdvanced API that replaces and remounts its content.
hideCloses this entry with an intentional result.
promiseDeprecated alias of the handle. Kept so old destructuring works.

const { promise, modalID, update } = magicModal.show(...) still works exactly as before, and promise is the same object as the handle.

The controls hang off the promise, so anything that adopts the handle hands back a plain promise without them. Returning it straight from an async function is the case that bites: const open = async () => magicModal.show(Modal) gives the caller a promise with no modalID, update, or hide. Return it from a non-async function, or await it where you open it.

See hide results for promise narrowing. Read replace open content before using update(), since it remounts the rendered component.

hide

hide<T>(data: T, options?: { modalID?: string }): void

Closes one modal imperatively and resolves its promise with an intentional result.

const { modalID } = magicModal.show(() => <UploadModal />);

magicModal.hide({ uploaded: true }, { modalID });

Prefer useMagicModal inside modal content. Calling hide without a modalID falls back to the top entry for compatibility and is deprecated.

hideAll

hideAll(): void

Closes every entry with MagicModalHideReason.GLOBAL_HIDE_ALL. Useful for logout boundaries and test cleanup; individual hides are clearer during normal interaction flows.

enableFullWindowOverlay

enableFullWindowOverlay(): void

Enables rendering above native iOS modal screens. This is the default and is a no-op outside iOS.

disableFullWindowOverlay

disableFullWindowOverlay(): void

Disables rendering above native iOS modal screens. See native iOS overlays for a safe try/finally pattern.

On this page