react-native-multiple-modals
Version:
Native implementation with the ability to display multiple Modals
100 lines (99 loc) • 2.91 kB
JavaScript
"use strict";
import { useMemo } from 'react';
import { createPortal } from 'react-dom';
import { StyleSheet, View, Pressable } from 'react-native';
import { useID } from './hooks/useID';
import { useModalRegistry } from './hooks/useModalRegistry';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const backdropAccessibilityLabel = 'Backdrop';
const backdropAccessibilityHint = 'Double-tap to close the modal';
const defaultBackdropColor = 'rgba(0, 0, 0, 0.3)';
export let DismissalSource = /*#__PURE__*/function (DismissalSource) {
DismissalSource["BackButton"] = "BackButton";
DismissalSource["Backdrop"] = "Backdrop";
return DismissalSource;
}({});
export const ModalView = ({
modalId,
children,
renderBackdrop,
onRequestDismiss,
contentContainerStyle,
showBackdrop = true,
BackdropPressableComponent = Pressable,
backdropColor = defaultBackdropColor,
animationType = 'none'
}) => {
const currentModalId = useID(modalId);
const {
modals,
isBackdropVisible
} = useModalRegistry(currentModalId);
const modalIsOpen = modals.has(currentModalId);
const animatedStyle = useMemo(() => {
if (animationType === 'fade') {
return {
opacity: modalIsOpen ? 1 : 0,
transition: 'opacity 0.3s'
};
}
if (animationType === 'slide') {
return {
transform: modalIsOpen ? 'translateY(0)' : 'translateY(100%)',
opacity: modalIsOpen ? 1 : 0,
transition: 'transform 0.3s, opacity 0.3s'
};
}
return {};
}, [animationType, modalIsOpen]);
return /*#__PURE__*/createPortal(/*#__PURE__*/_jsxs(View, {
style: [showBackdrop && styles.backdropContainer],
children: [showBackdrop && /*#__PURE__*/_jsx(BackdropPressableComponent, {
accessibilityLabel: backdropAccessibilityLabel,
accessibilityHint: backdropAccessibilityHint,
style: [styles.backdropPressable, !isBackdropVisible && styles.backdropHidden],
onPress: () => onRequestDismiss?.(DismissalSource.Backdrop),
children: renderBackdrop ? renderBackdrop() : /*#__PURE__*/_jsx(View, {
style: [styles.flex, {
backgroundColor: backdropColor
}]
})
}), /*#__PURE__*/_jsx(View, {
role: "dialog",
pointerEvents: "box-none",
style: [styles.content, animatedStyle, contentContainerStyle],
children: children
})]
}), document.body);
};
const styles = StyleSheet.create({
backdropPressable: {
flex: 1,
opacity: 1,
alignSelf: 'stretch'
},
backdropHidden: {
opacity: 0
},
flex: {
flex: 1
},
content: {
alignSelf: 'center',
flex: 1,
height: '100%',
position: 'absolute',
zIndex: 1
},
backdropContainer: {
bottom: 0,
display: 'flex',
flexDirection: 'column',
left: 0,
position: 'fixed',
right: 0,
top: 0,
zIndex: 0
}
});
//# sourceMappingURL=ModalView.web.js.map