Magic Modallatest
API reference

Modal configuration

Configure animation, backdrop, swipe behavior, callbacks, and container style.

Pass a partial configuration as the second argument to magicModal.show:

magicModal.show(() => <SettingsModal />, {
  accessibilityLabel: "Application settings",
  animationInTiming: 220,
  backdropColor: "rgba(8, 7, 20, 0.72)",
  swipeDirection: "down",
});

Prop

Type

NewConfigProps is the partial override accepted by show. The exported ModalProps type is the fully resolved internal shape after defaults are applied.

Container style

style is the one option whose type is not the same on every platform, because a React Native style and a CSS declaration are not the same thing.

style: StyleProp<ViewStyle>;
magicModal.show(() => <SheetModal />, {
  style: { justifyContent: "flex-end", paddingHorizontal: 16 },
});

Breaking change in v10.1 (web only)

The web entry used to type style as StyleProp<ViewStyle> and let React Native Web translate it at runtime. It is React.CSSProperties now, because there is no React Native Web in the browser bundle to translate anything.

Most modals need no change: justifyContent, margin, padding, backgroundColor and unitless numbers all mean the same thing in both. Four things do change on web:

WasNow
style: [base, override]style: { ...base, ...override }
paddingHorizontal, marginVertical, ...paddingInline, marginBlock, ...
shadowColor / shadowOffset / elevationboxShadow
transform: [{ translateY: 8 }]transform: "translateY(8px)"

entering and exiting are gone from the web type as well. They take Reanimated builders, the browser bundle has no Reanimated, and they were already documented as ignored there.

A React Native style that slips past TypeScript is not applied on web, and logs one migration warning in development.

The React Native entry is unchanged, so a shared config object typed against it needs splitting before a web build can use it.

Direction

type Direction = "up" | "down" | "left" | "right";

Set swipeDirection to undefined to disable the dismiss gesture. This is recommended for scrollable content.

Callback overrides

Providing onBackdropPress or onBackButtonPress replaces the default close behavior. Call the supplied hide function yourself when the override should close:

magicModal.show(() => <DraftModal />, {
  onBackdropPress: ({ hide }) => {
    saveDraft();
    hide({ reason: MagicModalHideReason.BACKDROP_PRESS });
  },
});

onBackButtonPress handles the shared system-dismiss path: Android back, web Escape, and the native accessibility escape action.

On this page