Getting started
Your first modal
Show a component, close it from inside, and await typed data.
Define the data returned by the interaction. Pass that type to both show and useMagicModal.
import { Pressable, Text, View } from "react-native";
import { MagicModalHideReason, magicModal, useMagicModal } from "magic-modal";
type Confirmation = {
confirmed: boolean;
};
function ConfirmationModal() {
const { hide } = useMagicModal<Confirmation>();
return (
<View>
<Text accessibilityRole="header">Delete this project?</Text>
<Pressable
accessibilityRole="button"
onPress={() => hide({ confirmed: true })}
>
<Text>Delete</Text>
</Pressable>
<Pressable
accessibilityRole="button"
onPress={() => hide({ confirmed: false })}
>
<Text>Keep it</Text>
</Pressable>
</View>
);
}
export async function confirmDeletion() {
const result = await magicModal.show<Confirmation>(ConfirmationModal, {
accessibilityLabel: "Confirm project deletion",
});
if (result.reason !== MagicModalHideReason.INTENTIONAL_HIDE) {
return false;
}
return result.data.confirmed;
}show() hands back a handle that is itself the promise, so awaiting it gives the result directly.
The older const { promise } = magicModal.show(...) form still works; promise is an alias of the
handle. Keep the handle when the calling code needs modalID, update, or hide while the modal
stays open.
The promise also resolves when the backdrop, swipe gesture, system-dismiss action, or hideAll
closes the modal. System dismissal includes Android back, web Escape, and the native accessibility
escape action. Checking reason narrows the union, so data only exists after an intentional hide.