Magic Modallatest
Guides

UI recipes

Patterns for locked dialogs, custom motion, keyboard forms, and backdrop-free toasts.

Magic Modal owns orchestration and motion; the component you show owns the visual design. These recipes combine the small configuration API into common interaction patterns.

Require an explicit choice

Override both automatic close handlers and disable swipe. The modal content must still expose a button that calls useMagicModal().hide.

magicModal.show(() => <RequiredDecision />, {
  onBackButtonPress: () => {},
  onBackdropPress: () => {},
  swipeDirection: undefined,
});

Use this sparingly. A locked modal should explain the action required and remain accessible to screen-reader and keyboard users.

Custom entrance and exit

Pass Reanimated layout animations for motion that is not directional:

import { ZoomIn, ZoomOut } from "react-native-reanimated";

magicModal.show(() => <CelebrationModal />, {
  entering: ZoomIn.duration(280),
  exiting: ZoomOut.duration(220),
  swipeDirection: undefined,
});

Custom entering and exiting builders control the content animation. animationInTiming and animationOutTiming continue to control the backdrop and the default directional animations.

Bottom-aligned keyboard form

Put KeyboardAvoidingView inside the modal content and align the modal container to the bottom:

function RenameModal() {
  return (
    <KeyboardAvoidingView
      behavior={Platform.OS === "ios" ? "padding" : undefined}
    >
      <View style={styles.form}>
        <TextInput autoFocus />
      </View>
    </KeyboardAvoidingView>
  );
}

magicModal.show(() => <RenameModal />, {
  style: { justifyContent: "flex-end" },
});

Backdrop-free toast

hideBackdrop removes both the backdrop paint and its press target. Align the container and close from an effect:

function Toast() {
  const { hide } = useMagicModal();

  useEffect(() => {
    const timeout = setTimeout(() => hide(), 2_000);
    return () => clearTimeout(timeout);
  }, [hide]);

  return <ToastContent />;
}

magicModal.show(() => <Toast />, {
  dampingFactor: 0,
  hideBackdrop: true,
  style: { justifyContent: "flex-start" },
  swipeDirection: "up",
});

For a high-volume notification queue, use a dedicated toast library. This pattern is useful when the notification belongs to the same modal orchestration flow.

On this page