expo-router 5.2.0-canary-20250713-8f814f8 → 5.2.0-canary-20250729-d8899ae
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/modal.module.css +5 -4
- package/build/getRoutes.d.ts.map +1 -1
- package/build/getRoutes.js +5 -2
- package/build/getRoutes.js.map +1 -1
- package/build/getRoutesCore.d.ts.map +1 -1
- package/build/getRoutesCore.js +6 -1
- package/build/getRoutesCore.js.map +1 -1
- package/build/getRoutesSSR.d.ts.map +1 -1
- package/build/getRoutesSSR.js +14 -4
- package/build/getRoutesSSR.js.map +1 -1
- package/build/getServerManifest.d.ts.map +1 -1
- package/build/getServerManifest.js +11 -3
- package/build/getServerManifest.js.map +1 -1
- package/build/link/preview/native.d.ts +1 -0
- package/build/link/preview/native.d.ts.map +1 -1
- package/build/link/preview/native.js +5 -4
- package/build/link/preview/native.js.map +1 -1
- package/build/modal/Modal.d.ts +12 -1
- package/build/modal/Modal.d.ts.map +1 -1
- package/build/modal/Modal.js +37 -12
- package/build/modal/Modal.js.map +1 -1
- package/build/modal/ModalContext.d.ts +6 -13
- package/build/modal/ModalContext.d.ts.map +1 -1
- package/build/modal/ModalContext.js +34 -94
- package/build/modal/ModalContext.js.map +1 -1
- package/build/modal/ModalsRenderer.d.ts +3 -0
- package/build/modal/ModalsRenderer.d.ts.map +1 -0
- package/build/modal/ModalsRenderer.js +47 -0
- package/build/modal/ModalsRenderer.js.map +1 -0
- package/build/modal/ModalsRenderer.web.d.ts +3 -0
- package/build/modal/ModalsRenderer.web.d.ts.map +1 -0
- package/build/modal/ModalsRenderer.web.js +37 -0
- package/build/modal/ModalsRenderer.web.js.map +1 -0
- package/build/modal/types.d.ts +19 -0
- package/build/modal/types.d.ts.map +1 -0
- package/build/modal/types.js +3 -0
- package/build/modal/types.js.map +1 -0
- package/build/modal/utils.d.ts +4 -0
- package/build/modal/utils.d.ts.map +1 -1
- package/build/modal/utils.js +46 -0
- package/build/modal/utils.js.map +1 -1
- package/build/modal/web/ModalStack.web.d.ts.map +1 -1
- package/build/modal/web/ModalStack.web.js +4 -4
- package/build/modal/web/ModalStack.web.js.map +1 -1
- package/build/modal/web/ModalStackRouteDrawer.web.d.ts.map +1 -1
- package/build/modal/web/ModalStackRouteDrawer.web.js +6 -3
- package/build/modal/web/ModalStackRouteDrawer.web.js.map +1 -1
- package/build/utils/splash.d.ts.map +1 -1
- package/build/utils/splash.js +4 -2
- package/build/utils/splash.js.map +1 -1
- package/build/views/Sitemap.js +1 -8
- package/build/views/Sitemap.js.map +1 -1
- package/ios/LinkPreview/LinkPreviewNativeActionView.swift +2 -0
- package/ios/LinkPreview/LinkPreviewNativeModule.swift +1 -0
- package/ios/LinkPreview/LinkPreviewNativeNavigation.h +6 -0
- package/ios/LinkPreview/LinkPreviewNativeNavigation.mm +38 -5
- package/ios/LinkPreview/LinkPreviewNativePreviewView.swift +2 -0
- package/ios/LinkPreview/LinkPreviewNativeView.swift +13 -4
- package/package.json +6 -6
|
@@ -7,7 +7,8 @@ exports.NativeLinkPreview = NativeLinkPreview;
|
|
|
7
7
|
exports.NativeLinkPreviewContent = NativeLinkPreviewContent;
|
|
8
8
|
const expo_1 = require("expo");
|
|
9
9
|
const react_native_1 = require("react-native");
|
|
10
|
-
const
|
|
10
|
+
const areNativeViewsAvailable = process.env.EXPO_OS === 'ios' && global.RN$Bridgeless === true;
|
|
11
|
+
const LinkPreviewNativeActionView = areNativeViewsAvailable
|
|
11
12
|
? (0, expo_1.requireNativeView)('ExpoRouterNativeLinkPreview', 'LinkPreviewNativeActionView')
|
|
12
13
|
: null;
|
|
13
14
|
function NativeLinkPreviewAction(props) {
|
|
@@ -16,7 +17,7 @@ function NativeLinkPreviewAction(props) {
|
|
|
16
17
|
}
|
|
17
18
|
return <LinkPreviewNativeActionView {...props}/>;
|
|
18
19
|
}
|
|
19
|
-
const NativeLinkPreviewTriggerView =
|
|
20
|
+
const NativeLinkPreviewTriggerView = areNativeViewsAvailable
|
|
20
21
|
? (0, expo_1.requireNativeView)('ExpoRouterNativeLinkPreview', 'NativeLinkPreviewTrigger')
|
|
21
22
|
: null;
|
|
22
23
|
function NativeLinkPreviewTrigger(props) {
|
|
@@ -25,7 +26,7 @@ function NativeLinkPreviewTrigger(props) {
|
|
|
25
26
|
}
|
|
26
27
|
return <NativeLinkPreviewTriggerView {...props}/>;
|
|
27
28
|
}
|
|
28
|
-
const NativeLinkPreviewView =
|
|
29
|
+
const NativeLinkPreviewView = areNativeViewsAvailable
|
|
29
30
|
? (0, expo_1.requireNativeView)('ExpoRouterNativeLinkPreview', 'NativeLinkPreviewView')
|
|
30
31
|
: null;
|
|
31
32
|
function NativeLinkPreview(props) {
|
|
@@ -34,7 +35,7 @@ function NativeLinkPreview(props) {
|
|
|
34
35
|
}
|
|
35
36
|
return <NativeLinkPreviewView {...props}/>;
|
|
36
37
|
}
|
|
37
|
-
const NativeLinkPreviewContentView =
|
|
38
|
+
const NativeLinkPreviewContentView = areNativeViewsAvailable
|
|
38
39
|
? (0, expo_1.requireNativeView)('ExpoRouterNativeLinkPreview', 'NativeLinkPreviewContentView')
|
|
39
40
|
: null;
|
|
40
41
|
function NativeLinkPreviewContent(props) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.js","sourceRoot":"","sources":["../../../src/link/preview/native.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;
|
|
1
|
+
{"version":3,"file":"native.js","sourceRoot":"","sources":["../../../src/link/preview/native.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAkBb,0DAKC;AASD,4DAKC;AAmBD,8CAKC;AAYD,4DAWC;AAlFD,+BAAyC;AACzC,+CAA0D;AAE1D,MAAM,uBAAuB,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,KAAK,IAAI,MAAM,CAAC,aAAa,KAAK,IAAI,CAAC;AAS/F,MAAM,2BAA2B,GAC/B,uBAAuB;IACrB,CAAC,CAAC,IAAA,wBAAiB,EAAC,6BAA6B,EAAE,6BAA6B,CAAC;IACjF,CAAC,CAAC,IAAI,CAAC;AACX,SAAgB,uBAAuB,CAAC,KAAmC;IACzE,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CAAC,2BAA2B,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AACpD,CAAC;AAKD,MAAM,4BAA4B,GAChC,uBAAuB;IACrB,CAAC,CAAC,IAAA,wBAAiB,EAAC,6BAA6B,EAAE,0BAA0B,CAAC;IAC9E,CAAC,CAAC,IAAI,CAAC;AACX,SAAgB,wBAAwB,CAAC,KAAoC;IAC3E,IAAI,CAAC,4BAA4B,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CAAC,4BAA4B,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AACrD,CAAC;AAeD,MAAM,qBAAqB,GACzB,uBAAuB;IACrB,CAAC,CAAC,IAAA,wBAAiB,EAAC,6BAA6B,EAAE,uBAAuB,CAAC;IAC3E,CAAC,CAAC,IAAI,CAAC;AACX,SAAgB,iBAAiB,CAAC,KAA6B;IAC7D,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CAAC,qBAAqB,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AAC9C,CAAC;AAOD,MAAM,4BAA4B,GAChC,uBAAuB;IACrB,CAAC,CAAC,IAAA,wBAAiB,EAAC,6BAA6B,EAAE,8BAA8B,CAAC;IAClF,CAAC,CAAC,IAAI,CAAC;AAEX,SAAgB,wBAAwB,CAAC,KAAoC;IAC3E,IAAI,CAAC,4BAA4B,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,yBAAU,CAAC,OAAO,CAAC;QAC/B,KAAK,CAAC,KAAK;QACX;YACE,QAAQ,EAAE,UAAU;SACZ;KACX,CAAC,CAAC;IACH,OAAO,CAAC,4BAA4B,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAG,CAAC;AACnE,CAAC;AACD,aAAa","sourcesContent":["'use client';\n\nimport { requireNativeView } from 'expo';\nimport { StyleSheet, type ViewProps } from 'react-native';\n\nconst areNativeViewsAvailable = process.env.EXPO_OS === 'ios' && global.RN$Bridgeless === true;\n\n// #region Action View\nexport interface NativeLinkPreviewActionProps {\n title: string;\n icon?: string;\n id: string;\n children?: React.ReactNode;\n}\nconst LinkPreviewNativeActionView: React.ComponentType<NativeLinkPreviewActionProps> | null =\n areNativeViewsAvailable\n ? requireNativeView('ExpoRouterNativeLinkPreview', 'LinkPreviewNativeActionView')\n : null;\nexport function NativeLinkPreviewAction(props: NativeLinkPreviewActionProps) {\n if (!LinkPreviewNativeActionView) {\n return null;\n }\n return <LinkPreviewNativeActionView {...props} />;\n}\n// #endregion\n\n// #region Trigger View\nexport type NativeLinkPreviewTriggerProps = ViewProps;\nconst NativeLinkPreviewTriggerView: React.ComponentType<NativeLinkPreviewTriggerProps> | null =\n areNativeViewsAvailable\n ? requireNativeView('ExpoRouterNativeLinkPreview', 'NativeLinkPreviewTrigger')\n : null;\nexport function NativeLinkPreviewTrigger(props: NativeLinkPreviewTriggerProps) {\n if (!NativeLinkPreviewTriggerView) {\n return null;\n }\n return <NativeLinkPreviewTriggerView {...props} />;\n}\n// #endregion\n\n// #region Preview View\nexport interface NativeLinkPreviewProps extends ViewProps {\n nextScreenId: string | undefined;\n onActionSelected?: (event: { nativeEvent: { id: string } }) => void;\n onWillPreviewOpen?: () => void;\n onDidPreviewOpen?: () => void;\n onPreviewWillClose?: () => void;\n onPreviewDidClose?: () => void;\n onPreviewTapped?: () => void;\n onPreviewTappedAnimationCompleted?: () => void;\n children: React.ReactNode;\n}\nconst NativeLinkPreviewView: React.ComponentType<NativeLinkPreviewProps> | null =\n areNativeViewsAvailable\n ? requireNativeView('ExpoRouterNativeLinkPreview', 'NativeLinkPreviewView')\n : null;\nexport function NativeLinkPreview(props: NativeLinkPreviewProps) {\n if (!NativeLinkPreviewView) {\n return null;\n }\n return <NativeLinkPreviewView {...props} />;\n}\n// #endregion\n\n// #region Preview Content View\nexport interface NativeLinkPreviewContentProps extends ViewProps {\n preferredContentSize?: { width: number; height: number };\n}\nconst NativeLinkPreviewContentView: React.ComponentType<NativeLinkPreviewContentProps> | null =\n areNativeViewsAvailable\n ? requireNativeView('ExpoRouterNativeLinkPreview', 'NativeLinkPreviewContentView')\n : null;\n\nexport function NativeLinkPreviewContent(props: NativeLinkPreviewContentProps) {\n if (!NativeLinkPreviewContentView) {\n return null;\n }\n const style = StyleSheet.flatten([\n props.style,\n {\n position: 'absolute',\n } as const,\n ]);\n return <NativeLinkPreviewContentView {...props} style={style} />;\n}\n// #endregion\n"]}
|
package/build/modal/Modal.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export interface ModalProps extends ViewProps {
|
|
|
13
13
|
visible: boolean;
|
|
14
14
|
/**
|
|
15
15
|
* Callback that is called after modal is closed.
|
|
16
|
-
* This is called when the modal is
|
|
16
|
+
* This is called when the modal is closed programmatically or when the user dismisses it.
|
|
17
17
|
*/
|
|
18
18
|
onClose?: () => void;
|
|
19
19
|
/**
|
|
@@ -52,8 +52,19 @@ export interface ModalProps extends ViewProps {
|
|
|
52
52
|
* Heights should be described as fraction (a number from `[0, 1]` interval) of screen height / maximum detent height.
|
|
53
53
|
* You can pass an array of ascending values each defining allowed sheet detent. iOS accepts any number of detents,
|
|
54
54
|
* while **Android is limited to three**.
|
|
55
|
+
*
|
|
56
|
+
* @default 'fitToContents'
|
|
55
57
|
*/
|
|
56
58
|
detents?: ModalConfig['detents'];
|
|
59
|
+
/**
|
|
60
|
+
* Determines whether the modal should close when navigating away from the screen that opened it.
|
|
61
|
+
*
|
|
62
|
+
* If set to `true`, the modal will close when the user navigates to a different screen.
|
|
63
|
+
*
|
|
64
|
+
* If set to `false`, the modal will remain open when pushing a new screen.
|
|
65
|
+
* However, it will still close when navigating back or replacing the current screen.
|
|
66
|
+
*/
|
|
67
|
+
closeOnNavigation?: boolean;
|
|
57
68
|
}
|
|
58
69
|
/**
|
|
59
70
|
* A standalone modal component that can be used in Expo Router apps.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../src/modal/Modal.tsx"],"names":[],"mappings":"AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../src/modal/Modal.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAc,SAAS,EAAE,MAAM,cAAc,CAAC;AAGrD,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAInE,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;OAGG;IACH,aAAa,CAAC,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC;IAC7C;;;;;;;;;OASG;IACH,iBAAiB,CAAC,EAAE,WAAW,CAAC,mBAAmB,CAAC,CAAC;IACrD;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjC;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,QAgGtC"}
|
package/build/modal/Modal.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.Modal = Modal;
|
|
5
5
|
const non_secure_1 = require("nanoid/non-secure");
|
|
6
6
|
const react_1 = require("react");
|
|
7
|
+
const react_native_1 = require("react-native");
|
|
7
8
|
const ModalContext_1 = require("./ModalContext");
|
|
8
9
|
const useNavigation_1 = require("../useNavigation");
|
|
9
10
|
const utils_1 = require("./utils");
|
|
@@ -33,17 +34,28 @@ const utils_1 = require("./utils");
|
|
|
33
34
|
* }
|
|
34
35
|
*/
|
|
35
36
|
function Modal(props) {
|
|
36
|
-
const { children, visible, onClose, onShow, animationType, presentationStyle, transparent, ...viewProps } = props;
|
|
37
|
-
const { openModal, closeModal, addEventListener } = (0, ModalContext_1.useModalContext)();
|
|
37
|
+
const { children, visible, onClose, onShow, animationType, presentationStyle, transparent, detents, closeOnNavigation, ...viewProps } = props;
|
|
38
|
+
const { openModal, updateModal, closeModal, addEventListener } = (0, ModalContext_1.useModalContext)();
|
|
38
39
|
const [currentModalId, setCurrentModalId] = (0, react_1.useState)();
|
|
39
40
|
const navigation = (0, useNavigation_1.useNavigation)();
|
|
40
41
|
(0, react_1.useEffect)(() => {
|
|
41
|
-
if (!(0, utils_1.areDetentsValid)(
|
|
42
|
-
throw new Error(`Invalid detents provided to Modal: ${JSON.stringify(
|
|
42
|
+
if (!(0, utils_1.areDetentsValid)(detents)) {
|
|
43
|
+
throw new Error(`Invalid detents provided to Modal: ${JSON.stringify(detents)}`);
|
|
43
44
|
}
|
|
44
|
-
}, [
|
|
45
|
+
}, [detents]);
|
|
45
46
|
(0, react_1.useEffect)(() => {
|
|
46
|
-
if (
|
|
47
|
+
if (__DEV__ &&
|
|
48
|
+
presentationStyle === 'formSheet' &&
|
|
49
|
+
detents !== 'fitToContents' &&
|
|
50
|
+
process.env.EXPO_OS === 'ios' &&
|
|
51
|
+
react_native_1.StyleSheet.flatten(props.style)?.flex) {
|
|
52
|
+
console.warn(
|
|
53
|
+
// TODO: ENG-16230: Add warning link to documentation
|
|
54
|
+
'The `formSheet` presentation style does not support flex styles on iOS. Consider using a fixed height view or scroll view with `fitToContents` detent instead. See ');
|
|
55
|
+
}
|
|
56
|
+
}, [props.style, presentationStyle, detents]);
|
|
57
|
+
(0, react_1.useEffect)(() => {
|
|
58
|
+
if (visible) {
|
|
47
59
|
const newId = (0, non_secure_1.nanoid)();
|
|
48
60
|
openModal({
|
|
49
61
|
animationType,
|
|
@@ -51,21 +63,34 @@ function Modal(props) {
|
|
|
51
63
|
transparent,
|
|
52
64
|
viewProps,
|
|
53
65
|
component: children,
|
|
54
|
-
detents: props.detents,
|
|
55
66
|
uniqueId: newId,
|
|
56
67
|
parentNavigationProp: navigation,
|
|
68
|
+
detents: detents ?? 'fitToContents',
|
|
57
69
|
});
|
|
58
70
|
setCurrentModalId(newId);
|
|
59
71
|
return () => {
|
|
60
72
|
closeModal(newId);
|
|
61
73
|
};
|
|
62
74
|
}
|
|
63
|
-
else if (currentModalId && !visible) {
|
|
64
|
-
closeModal(currentModalId);
|
|
65
|
-
setCurrentModalId(undefined);
|
|
66
|
-
}
|
|
67
75
|
return () => { };
|
|
68
76
|
}, [visible]);
|
|
77
|
+
(0, react_1.useEffect)(() => {
|
|
78
|
+
if (navigation.isFocused()) {
|
|
79
|
+
return navigation.addListener('blur', () => {
|
|
80
|
+
if (currentModalId && closeOnNavigation) {
|
|
81
|
+
closeModal(currentModalId);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return () => { };
|
|
86
|
+
}, [navigation, closeModal, currentModalId, closeOnNavigation]);
|
|
87
|
+
(0, react_1.useEffect)(() => {
|
|
88
|
+
if (currentModalId && visible) {
|
|
89
|
+
updateModal(currentModalId, {
|
|
90
|
+
component: children,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}, [children]);
|
|
69
94
|
(0, react_1.useEffect)(() => {
|
|
70
95
|
if (currentModalId) {
|
|
71
96
|
const unsubscribeShow = addEventListener('show', (id) => {
|
|
@@ -85,7 +110,7 @@ function Modal(props) {
|
|
|
85
110
|
};
|
|
86
111
|
}
|
|
87
112
|
return () => { };
|
|
88
|
-
}, [currentModalId, addEventListener, onClose]);
|
|
113
|
+
}, [currentModalId, addEventListener, onClose, onShow]);
|
|
89
114
|
return null;
|
|
90
115
|
}
|
|
91
116
|
//# sourceMappingURL=Modal.js.map
|
package/build/modal/Modal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../src/modal/Modal.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;
|
|
1
|
+
{"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../src/modal/Modal.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { type NavigationProp, type ParamListBase } from '@react-navigation/native';\nimport { nanoid } from 'nanoid/non-secure';\nimport { useEffect, useState } from 'react';\nimport { StyleSheet, ViewProps } from 'react-native';\nimport { type ScreenProps } from 'react-native-screens';\n\nimport { useModalContext, type ModalConfig } from './ModalContext';\nimport { useNavigation } from '../useNavigation';\nimport { areDetentsValid } from './utils';\n\nexport interface ModalProps extends ViewProps {\n /**\n * The content of the modal.\n */\n children?: React.ReactNode;\n /**\n * Whether the modal is visible or not.\n * When set to `true`, the modal will be opened.\n * When set to `false`, the modal will be closed.\n */\n visible: boolean;\n /**\n * Callback that is called after modal is closed.\n * This is called when the modal is closed programmatically or when the user dismisses it.\n */\n onClose?: () => void;\n /**\n * Callback that is called after modal is shown.\n */\n onShow?: () => void;\n /**\n * The animation type for the modal.\n * This can be one of 'none', 'slide', or 'fade'.\n */\n animationType?: ModalConfig['animationType'];\n /**\n * The presentation style for the modal.\n * This can be one of 'fullScreen', 'pageSheet', 'formSheet', or 'overFullScreen'.\n * - `fullScreen`: The modal covers the entire screen. When `transparent` is set to `true`, it will fallback to `overFullScreen`.\n * - `pageSheet`: The modal is presented as a page sheet on iOS. Defaults to `fullScreen` on Android.\n * - `formSheet`: The modal is presented as a form sheet.\n * - `overFullScreen`: The modal is presented over the full screen, allowing interaction with the underlying content.\n *\n * @default 'fullScreen'\n */\n presentationStyle?: ModalConfig['presentationStyle'];\n /**\n * Whether the modal should be rendered as a transparent overlay.\n * This will render the modal without a background, allowing the content behind it to be visible.\n *\n * On Android, this will fallback to `overFullScreen` presentation style.\n */\n transparent?: boolean;\n /**\n * See {@link ScreenProps[\"sheetAllowedDetents\"]}.\n *\n * Describes heights where a sheet can rest.\n * Works only when `presentation` is set to `formSheet`.\n *\n * Heights should be described as fraction (a number from `[0, 1]` interval) of screen height / maximum detent height.\n * You can pass an array of ascending values each defining allowed sheet detent. iOS accepts any number of detents,\n * while **Android is limited to three**.\n *\n * @default 'fitToContents'\n */\n detents?: ModalConfig['detents'];\n /**\n * Determines whether the modal should close when navigating away from the screen that opened it.\n *\n * If set to `true`, the modal will close when the user navigates to a different screen.\n *\n * If set to `false`, the modal will remain open when pushing a new screen.\n * However, it will still close when navigating back or replacing the current screen.\n */\n closeOnNavigation?: boolean;\n}\n\n/**\n * A standalone modal component that can be used in Expo Router apps.\n * It always renders on top of the application's content.\n * Internally, the modal is rendered as a `Stack.Screen`, with the presentation style determined by the `presentationStyle` prop.\n *\n * **Props should be set before the modal is opened. Changes to the props will take effect after the modal is reopened.**\n *\n * This component is not linkable. If you need to link to a modal, use `<Stack.Screen options={{ presentationStyle: \"modal\" }} />` instead.\n *\n * @example\n * ```tsx\n * import { Modal } from 'expo-router';\n *\n * function Page() {\n * const [modalVisible, setModalVisible] = useState(false);\n * return (\n * <Modal\n * visible={modalVisible}\n * onClose={() => setModalVisible(false)}\n * >\n * <Text>Hello World</Text>\n * </Modal>\n * );\n * }\n */\nexport function Modal(props: ModalProps) {\n const {\n children,\n visible,\n onClose,\n onShow,\n animationType,\n presentationStyle,\n transparent,\n detents,\n closeOnNavigation,\n ...viewProps\n } = props;\n const { openModal, updateModal, closeModal, addEventListener } = useModalContext();\n const [currentModalId, setCurrentModalId] = useState<string | undefined>();\n const navigation = useNavigation<NavigationProp<ParamListBase>>();\n useEffect(() => {\n if (!areDetentsValid(detents)) {\n throw new Error(`Invalid detents provided to Modal: ${JSON.stringify(detents)}`);\n }\n }, [detents]);\n useEffect(() => {\n if (\n __DEV__ &&\n presentationStyle === 'formSheet' &&\n detents !== 'fitToContents' &&\n process.env.EXPO_OS === 'ios' &&\n StyleSheet.flatten(props.style)?.flex\n ) {\n console.warn(\n // TODO: ENG-16230: Add warning link to documentation\n 'The `formSheet` presentation style does not support flex styles on iOS. Consider using a fixed height view or scroll view with `fitToContents` detent instead. See '\n );\n }\n }, [props.style, presentationStyle, detents]);\n useEffect(() => {\n if (visible) {\n const newId = nanoid();\n openModal({\n animationType,\n presentationStyle,\n transparent,\n viewProps,\n component: children,\n uniqueId: newId,\n parentNavigationProp: navigation,\n detents: detents ?? 'fitToContents',\n });\n setCurrentModalId(newId);\n return () => {\n closeModal(newId);\n };\n }\n return () => {};\n }, [visible]);\n\n useEffect(() => {\n if (navigation.isFocused()) {\n return navigation.addListener('blur', () => {\n if (currentModalId && closeOnNavigation) {\n closeModal(currentModalId);\n }\n });\n }\n return () => {};\n }, [navigation, closeModal, currentModalId, closeOnNavigation]);\n\n useEffect(() => {\n if (currentModalId && visible) {\n updateModal(currentModalId, {\n component: children,\n });\n }\n }, [children]);\n\n useEffect(() => {\n if (currentModalId) {\n const unsubscribeShow = addEventListener('show', (id) => {\n if (id === currentModalId) {\n onShow?.();\n }\n });\n const unsubscribeClose = addEventListener('close', (id) => {\n if (id === currentModalId) {\n onClose?.();\n setCurrentModalId(undefined);\n }\n });\n return () => {\n unsubscribeShow();\n unsubscribeClose();\n };\n }\n return () => {};\n }, [currentModalId, addEventListener, onClose, onShow]);\n return null;\n}\n"]}
|
|
@@ -1,21 +1,14 @@
|
|
|
1
|
-
import type { NavigationProp, ParamListBase } from '@react-navigation/native';
|
|
2
1
|
import { type PropsWithChildren } from 'react';
|
|
3
|
-
import { type
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
uniqueId: string;
|
|
8
|
-
animationType?: 'slide' | 'fade' | 'none';
|
|
9
|
-
presentationStyle?: 'fullScreen' | 'overFullScreen' | 'pageSheet' | 'formSheet';
|
|
10
|
-
transparent?: boolean;
|
|
11
|
-
viewProps?: ViewProps;
|
|
12
|
-
detents?: number[] | 'fitToContents';
|
|
13
|
-
}
|
|
2
|
+
import { type ModalConfig } from './types';
|
|
3
|
+
export { type ModalConfig };
|
|
4
|
+
declare const ALLOWED_EVENT_TYPE_LISTENERS: readonly ["close", "show"];
|
|
5
|
+
type AllowedEventTypeListeners = (typeof ALLOWED_EVENT_TYPE_LISTENERS)[number];
|
|
14
6
|
export interface ModalContextType {
|
|
15
7
|
modalConfigs: ModalConfig[];
|
|
16
8
|
openModal: (config: ModalConfig) => void;
|
|
9
|
+
updateModal: (id: string, config: Omit<Partial<ModalConfig>, 'uniqueId'>) => void;
|
|
17
10
|
closeModal: (id: string) => void;
|
|
18
|
-
addEventListener: (type:
|
|
11
|
+
addEventListener: (type: AllowedEventTypeListeners, callback: (id: string) => void) => () => void;
|
|
19
12
|
}
|
|
20
13
|
export declare const ModalContextProvider: ({ children }: PropsWithChildren) => import("react").JSX.Element;
|
|
21
14
|
export declare const useModalContext: () => ModalContextType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalContext.d.ts","sourceRoot":"","sources":["../../src/modal/ModalContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"ModalContext.d.ts","sourceRoot":"","sources":["../../src/modal/ModalContext.tsx"],"names":[],"mappings":"AAEA,OAAO,EAOL,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,EAAE,KAAK,WAAW,EAAE,CAAC;AAE5B,QAAA,MAAM,4BAA4B,4BAA6B,CAAC;AAChE,KAAK,yBAAyB,GAAG,CAAC,OAAO,4BAA4B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/E,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,SAAS,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,KAAK,IAAI,CAAC;IAClF,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,gBAAgB,EAAE,CAAC,IAAI,EAAE,yBAAyB,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;CACnG;AAID,eAAO,MAAM,oBAAoB,GAAI,cAAc,iBAAiB,gCA0FnE,CAAC;AAEF,eAAO,MAAM,eAAe,wBAM3B,CAAC"}
|
|
@@ -2,33 +2,46 @@
|
|
|
2
2
|
'use client';
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.useModalContext = exports.ModalContextProvider = void 0;
|
|
5
|
-
const non_secure_1 = require("nanoid/non-secure");
|
|
6
5
|
const react_1 = require("react");
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const ModalComponent_1 = require("./ModalComponent");
|
|
6
|
+
const ModalsRenderer_1 = require("./ModalsRenderer");
|
|
7
|
+
const ALLOWED_EVENT_TYPE_LISTENERS = ['close', 'show'];
|
|
10
8
|
const ModalContext = (0, react_1.createContext)(undefined);
|
|
11
9
|
const ModalContextProvider = ({ children }) => {
|
|
12
10
|
const [modalConfigs, setModalConfigs] = (0, react_1.useState)([]);
|
|
13
|
-
const
|
|
14
|
-
|
|
11
|
+
const eventListeners = (0, react_1.useRef)({
|
|
12
|
+
close: new Set(),
|
|
13
|
+
show: new Set(),
|
|
14
|
+
});
|
|
15
15
|
const prevModalConfigs = (0, react_1.useRef)([]);
|
|
16
16
|
(0, react_1.useEffect)(() => {
|
|
17
17
|
if (prevModalConfigs.current !== modalConfigs) {
|
|
18
18
|
prevModalConfigs.current.forEach((config) => {
|
|
19
19
|
if (!modalConfigs.find((c) => c.uniqueId === config.uniqueId)) {
|
|
20
|
-
|
|
20
|
+
emitCloseEvent(config.uniqueId);
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
prevModalConfigs.current = modalConfigs;
|
|
24
24
|
}
|
|
25
25
|
}, [modalConfigs]);
|
|
26
|
-
const openModal = (0, react_1.useCallback)((config) =>
|
|
26
|
+
const openModal = (0, react_1.useCallback)((config) => {
|
|
27
|
+
setModalConfigs((prev) => [...prev, config]);
|
|
28
|
+
}, []);
|
|
29
|
+
const updateModal = (0, react_1.useCallback)((id, config) => {
|
|
30
|
+
setModalConfigs((prev) => {
|
|
31
|
+
const index = prev.findIndex((c) => c.uniqueId === id);
|
|
32
|
+
if (index >= 0) {
|
|
33
|
+
const updatedConfigs = [...prev];
|
|
34
|
+
updatedConfigs[index] = { ...updatedConfigs[index], ...config };
|
|
35
|
+
return updatedConfigs;
|
|
36
|
+
}
|
|
37
|
+
return prev;
|
|
38
|
+
});
|
|
39
|
+
}, []);
|
|
27
40
|
const emitCloseEvent = (0, react_1.useCallback)((id) => {
|
|
28
|
-
|
|
41
|
+
eventListeners.current.close.forEach((callback) => callback(id));
|
|
29
42
|
}, []);
|
|
30
43
|
const emitShowEvent = (0, react_1.useCallback)((id) => {
|
|
31
|
-
|
|
44
|
+
eventListeners.current.show.forEach((callback) => callback(id));
|
|
32
45
|
}, []);
|
|
33
46
|
const closeModal = (0, react_1.useCallback)((id) => {
|
|
34
47
|
setModalConfigs((prev) => {
|
|
@@ -40,54 +53,30 @@ const ModalContextProvider = ({ children }) => {
|
|
|
40
53
|
});
|
|
41
54
|
}, []);
|
|
42
55
|
const addEventListener = (0, react_1.useCallback)((type, callback) => {
|
|
43
|
-
if (type
|
|
56
|
+
if (!ALLOWED_EVENT_TYPE_LISTENERS.includes(type))
|
|
44
57
|
return () => { };
|
|
45
58
|
if (!callback) {
|
|
46
59
|
console.warn('Passing undefined as a callback to addEventListener is forbidden');
|
|
47
60
|
return () => { };
|
|
48
61
|
}
|
|
49
|
-
|
|
50
|
-
eventListeners.current.add(callback);
|
|
62
|
+
eventListeners.current[type].add(callback);
|
|
51
63
|
return () => {
|
|
52
|
-
eventListeners.current.delete(callback);
|
|
64
|
+
eventListeners.current[type].delete(callback);
|
|
53
65
|
};
|
|
54
66
|
}, []);
|
|
55
|
-
|
|
56
|
-
return (<react_native_screens_1.ScreenStack style={styles.stackContainer}>
|
|
57
|
-
<react_native_screens_1.ScreenStackItem screenId={rootId} activityState={2} style={react_native_1.StyleSheet.absoluteFill} headerConfig={{
|
|
58
|
-
hidden: true,
|
|
59
|
-
}}>
|
|
60
|
-
<ModalContext.Provider value={{
|
|
67
|
+
return (<ModalContext.Provider value={{
|
|
61
68
|
modalConfigs,
|
|
62
69
|
openModal,
|
|
63
70
|
closeModal,
|
|
71
|
+
updateModal,
|
|
64
72
|
addEventListener,
|
|
65
73
|
}}>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
{
|
|
73
|
-
flex: 1,
|
|
74
|
-
backgroundColor: config.transparent ? 'transparent' : 'white',
|
|
75
|
-
},
|
|
76
|
-
config.viewProps?.style,
|
|
77
|
-
]} sheetAllowedDetents={config.detents} style={[
|
|
78
|
-
react_native_1.StyleSheet.absoluteFill,
|
|
79
|
-
{
|
|
80
|
-
backgroundColor: config.transparent ? 'transparent' : 'white',
|
|
81
|
-
},
|
|
82
|
-
]} onDismissed={() => {
|
|
83
|
-
closeModal(config.uniqueId);
|
|
84
|
-
emitCloseEvent(config.uniqueId);
|
|
85
|
-
}} onAppear={() => {
|
|
86
|
-
emitShowEvent(config.uniqueId);
|
|
87
|
-
}}>
|
|
88
|
-
<ModalComponent_1.ModalComponent modalConfig={config}/>
|
|
89
|
-
</react_native_screens_1.ScreenStackItem>))}
|
|
90
|
-
</react_native_screens_1.ScreenStack>);
|
|
74
|
+
<ModalsRenderer_1.ModalsRenderer modalConfigs={modalConfigs} onDismissed={(id) => {
|
|
75
|
+
closeModal(id);
|
|
76
|
+
}} onShow={emitShowEvent}>
|
|
77
|
+
{children}
|
|
78
|
+
</ModalsRenderer_1.ModalsRenderer>
|
|
79
|
+
</ModalContext.Provider>);
|
|
91
80
|
};
|
|
92
81
|
exports.ModalContextProvider = ModalContextProvider;
|
|
93
82
|
const useModalContext = () => {
|
|
@@ -98,53 +87,4 @@ const useModalContext = () => {
|
|
|
98
87
|
return context;
|
|
99
88
|
};
|
|
100
89
|
exports.useModalContext = useModalContext;
|
|
101
|
-
function getStackAnimationType(config) {
|
|
102
|
-
switch (config.animationType) {
|
|
103
|
-
case 'fade':
|
|
104
|
-
return 'fade';
|
|
105
|
-
case 'none':
|
|
106
|
-
return 'none';
|
|
107
|
-
case 'slide':
|
|
108
|
-
default:
|
|
109
|
-
return 'slide_from_bottom';
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
function getStackPresentationType(config) {
|
|
113
|
-
if (process.env.EXPO_OS === 'android') {
|
|
114
|
-
if (config.transparent) {
|
|
115
|
-
return 'transparentModal';
|
|
116
|
-
}
|
|
117
|
-
switch (config.presentationStyle) {
|
|
118
|
-
case 'fullScreen':
|
|
119
|
-
return 'fullScreenModal';
|
|
120
|
-
case 'overFullScreen':
|
|
121
|
-
return 'transparentModal';
|
|
122
|
-
case 'pageSheet':
|
|
123
|
-
return 'pageSheet';
|
|
124
|
-
case 'formSheet':
|
|
125
|
-
return 'formSheet';
|
|
126
|
-
default:
|
|
127
|
-
return 'fullScreenModal';
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
switch (config.presentationStyle) {
|
|
131
|
-
case 'overFullScreen':
|
|
132
|
-
return 'transparentModal';
|
|
133
|
-
case 'pageSheet':
|
|
134
|
-
return 'pageSheet';
|
|
135
|
-
case 'formSheet':
|
|
136
|
-
return 'formSheet';
|
|
137
|
-
case 'fullScreen':
|
|
138
|
-
default:
|
|
139
|
-
if (config.transparent) {
|
|
140
|
-
return 'transparentModal';
|
|
141
|
-
}
|
|
142
|
-
return 'fullScreenModal';
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
const styles = react_native_1.StyleSheet.create({
|
|
146
|
-
stackContainer: {
|
|
147
|
-
flex: 1,
|
|
148
|
-
},
|
|
149
|
-
});
|
|
150
90
|
//# sourceMappingURL=ModalContext.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalContext.js","sourceRoot":"","sources":["../../src/modal/ModalContext.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport type { NavigationProp, ParamListBase } from '@react-navigation/native';\nimport { nanoid } from 'nanoid/non-secure';\nimport {\n createContext,\n use,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type PropsWithChildren,\n} from 'react';\nimport { StyleSheet, type ViewProps } from 'react-native';\nimport {\n ScreenStack,\n ScreenStackItem,\n type StackAnimationTypes,\n type StackPresentationTypes,\n} from 'react-native-screens';\n\nimport { ModalComponent } from './ModalComponent';\n\nexport interface ModalConfig {\n component: React.ReactNode;\n parentNavigationProp: NavigationProp<ParamListBase>;\n uniqueId: string;\n animationType?: 'slide' | 'fade' | 'none';\n presentationStyle?: 'fullScreen' | 'overFullScreen' | 'pageSheet' | 'formSheet';\n transparent?: boolean;\n viewProps?: ViewProps;\n detents?: number[] | 'fitToContents';\n}\n\nexport interface ModalContextType {\n modalConfigs: ModalConfig[];\n openModal: (config: ModalConfig) => void;\n closeModal: (id: string) => void;\n addEventListener: (type: 'close' | 'show', callback: (id: string) => void) => () => void;\n}\n\nconst ModalContext = createContext<ModalContextType | undefined>(undefined);\n\nexport const ModalContextProvider = ({ children }: PropsWithChildren) => {\n const [modalConfigs, setModalConfigs] = useState<ModalConfig[]>([]);\n const closeEventListeners = useRef<Set<(id: string) => void>>(new Set());\n const showEventListeners = useRef<Set<(id: string) => void>>(new Set());\n const prevModalConfigs = useRef<ModalConfig[]>([]);\n\n useEffect(() => {\n if (prevModalConfigs.current !== modalConfigs) {\n prevModalConfigs.current.forEach((config) => {\n if (!modalConfigs.find((c) => c.uniqueId === config.uniqueId)) {\n closeEventListeners.current.forEach((callback) => callback(config.uniqueId));\n }\n });\n prevModalConfigs.current = modalConfigs;\n }\n }, [modalConfigs]);\n\n const openModal = useCallback(\n (config: ModalConfig) => setModalConfigs((prev) => [...prev, config]),\n []\n );\n\n const emitCloseEvent = useCallback((id: string) => {\n closeEventListeners.current.forEach((callback) => callback(id));\n }, []);\n\n const emitShowEvent = useCallback((id: string) => {\n showEventListeners.current.forEach((callback) => callback(id));\n }, []);\n\n const closeModal = useCallback((id: string) => {\n setModalConfigs((prev) => {\n const modalIndex = prev.findIndex((config) => config.uniqueId === id);\n if (modalIndex >= 0) {\n return prev.filter((_, index) => index < modalIndex);\n }\n return prev;\n });\n }, []);\n\n const addEventListener = useCallback((type: 'close' | 'show', callback: (id: string) => void) => {\n if (type !== 'close' && type !== 'show') return () => {};\n\n if (!callback) {\n console.warn('Passing undefined as a callback to addEventListener is forbidden');\n return () => {};\n }\n\n const eventListeners = type === 'close' ? closeEventListeners : showEventListeners;\n eventListeners.current.add(callback);\n\n return () => {\n eventListeners.current.delete(callback);\n };\n }, []);\n\n const rootId = useMemo(() => nanoid(), []);\n\n return (\n <ScreenStack style={styles.stackContainer}>\n <ScreenStackItem\n screenId={rootId}\n activityState={2}\n style={StyleSheet.absoluteFill}\n headerConfig={{\n hidden: true,\n }}>\n <ModalContext.Provider\n value={{\n modalConfigs,\n openModal,\n closeModal,\n addEventListener,\n }}>\n {children}\n </ModalContext.Provider>\n </ScreenStackItem>\n {modalConfigs.map((config) => (\n <ScreenStackItem\n key={config.uniqueId}\n {...config.viewProps}\n screenId={`${rootId}${config.uniqueId}`}\n activityState={2}\n stackPresentation={getStackPresentationType(config)}\n stackAnimation={getStackAnimationType(config)}\n nativeBackButtonDismissalEnabled\n headerConfig={{\n hidden: true,\n }}\n contentStyle={[\n {\n flex: 1,\n backgroundColor: config.transparent ? 'transparent' : 'white',\n },\n config.viewProps?.style,\n ]}\n sheetAllowedDetents={config.detents}\n style={[\n StyleSheet.absoluteFill,\n {\n backgroundColor: config.transparent ? 'transparent' : 'white',\n },\n ]}\n onDismissed={() => {\n closeModal(config.uniqueId);\n emitCloseEvent(config.uniqueId);\n }}\n onAppear={() => {\n emitShowEvent(config.uniqueId);\n }}>\n <ModalComponent modalConfig={config} />\n </ScreenStackItem>\n ))}\n </ScreenStack>\n );\n};\n\nexport const useModalContext = () => {\n const context = use(ModalContext);\n if (!context) {\n throw new Error('useModalContext must be used within a ModalContextProvider');\n }\n return context;\n};\n\nfunction getStackAnimationType(config: ModalConfig): StackAnimationTypes | undefined {\n switch (config.animationType) {\n case 'fade':\n return 'fade';\n case 'none':\n return 'none';\n case 'slide':\n default:\n return 'slide_from_bottom';\n }\n}\n\nfunction getStackPresentationType(config: ModalConfig): StackPresentationTypes {\n if (process.env.EXPO_OS === 'android') {\n if (config.transparent) {\n return 'transparentModal';\n }\n switch (config.presentationStyle) {\n case 'fullScreen':\n return 'fullScreenModal';\n case 'overFullScreen':\n return 'transparentModal';\n case 'pageSheet':\n return 'pageSheet';\n case 'formSheet':\n return 'formSheet';\n default:\n return 'fullScreenModal';\n }\n }\n switch (config.presentationStyle) {\n case 'overFullScreen':\n return 'transparentModal';\n case 'pageSheet':\n return 'pageSheet';\n case 'formSheet':\n return 'formSheet';\n case 'fullScreen':\n default:\n if (config.transparent) {\n return 'transparentModal';\n }\n return 'fullScreenModal';\n }\n}\n\nconst styles = StyleSheet.create({\n stackContainer: {\n flex: 1,\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"ModalContext.js","sourceRoot":"","sources":["../../src/modal/ModalContext.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport {\n createContext,\n use,\n useCallback,\n useEffect,\n useRef,\n useState,\n type PropsWithChildren,\n} from 'react';\n\nimport { ModalsRenderer } from './ModalsRenderer';\nimport { type ModalConfig } from './types';\n\nexport { type ModalConfig };\n\nconst ALLOWED_EVENT_TYPE_LISTENERS = ['close', 'show'] as const;\ntype AllowedEventTypeListeners = (typeof ALLOWED_EVENT_TYPE_LISTENERS)[number];\n\nexport interface ModalContextType {\n modalConfigs: ModalConfig[];\n openModal: (config: ModalConfig) => void;\n updateModal: (id: string, config: Omit<Partial<ModalConfig>, 'uniqueId'>) => void;\n closeModal: (id: string) => void;\n addEventListener: (type: AllowedEventTypeListeners, callback: (id: string) => void) => () => void;\n}\n\nconst ModalContext = createContext<ModalContextType | undefined>(undefined);\n\nexport const ModalContextProvider = ({ children }: PropsWithChildren) => {\n const [modalConfigs, setModalConfigs] = useState<ModalConfig[]>([]);\n const eventListeners = useRef<Record<AllowedEventTypeListeners, Set<(id: string) => void>>>({\n close: new Set(),\n show: new Set(),\n });\n const prevModalConfigs = useRef<ModalConfig[]>([]);\n\n useEffect(() => {\n if (prevModalConfigs.current !== modalConfigs) {\n prevModalConfigs.current.forEach((config) => {\n if (!modalConfigs.find((c) => c.uniqueId === config.uniqueId)) {\n emitCloseEvent(config.uniqueId);\n }\n });\n prevModalConfigs.current = modalConfigs;\n }\n }, [modalConfigs]);\n\n const openModal = useCallback((config: ModalConfig) => {\n setModalConfigs((prev) => [...prev, config]);\n }, []);\n\n const updateModal = useCallback((id: string, config: Omit<Partial<ModalConfig>, 'uniqueId'>) => {\n setModalConfigs((prev) => {\n const index = prev.findIndex((c) => c.uniqueId === id);\n if (index >= 0) {\n const updatedConfigs = [...prev];\n updatedConfigs[index] = { ...updatedConfigs[index], ...config };\n return updatedConfigs;\n }\n return prev;\n });\n }, []);\n\n const emitCloseEvent = useCallback((id: string) => {\n eventListeners.current.close.forEach((callback) => callback(id));\n }, []);\n\n const emitShowEvent = useCallback((id: string) => {\n eventListeners.current.show.forEach((callback) => callback(id));\n }, []);\n\n const closeModal = useCallback((id: string) => {\n setModalConfigs((prev) => {\n const modalIndex = prev.findIndex((config) => config.uniqueId === id);\n if (modalIndex >= 0) {\n return prev.filter((_, index) => index < modalIndex);\n }\n return prev;\n });\n }, []);\n\n const addEventListener = useCallback(\n (type: AllowedEventTypeListeners, callback: (id: string) => void) => {\n if (!ALLOWED_EVENT_TYPE_LISTENERS.includes(type)) return () => {};\n\n if (!callback) {\n console.warn('Passing undefined as a callback to addEventListener is forbidden');\n return () => {};\n }\n\n eventListeners.current[type].add(callback);\n\n return () => {\n eventListeners.current[type].delete(callback);\n };\n },\n []\n );\n\n return (\n <ModalContext.Provider\n value={{\n modalConfigs,\n openModal,\n closeModal,\n updateModal,\n addEventListener,\n }}>\n <ModalsRenderer\n modalConfigs={modalConfigs}\n onDismissed={(id) => {\n closeModal(id);\n }}\n onShow={emitShowEvent}>\n {children}\n </ModalsRenderer>\n </ModalContext.Provider>\n );\n};\n\nexport const useModalContext = () => {\n const context = use(ModalContext);\n if (!context) {\n throw new Error('useModalContext must be used within a ModalContextProvider');\n }\n return context;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalsRenderer.d.ts","sourceRoot":"","sources":["../../src/modal/ModalsRenderer.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAGnD,eAAO,MAAM,cAAc,GAAI,kDAK5B,mBAAmB,gCAmDrB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ModalsRenderer = void 0;
|
|
5
|
+
const non_secure_1 = require("nanoid/non-secure");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const react_native_1 = require("react-native");
|
|
8
|
+
const react_native_screens_1 = require("react-native-screens");
|
|
9
|
+
const ModalComponent_1 = require("./ModalComponent");
|
|
10
|
+
const utils_1 = require("./utils");
|
|
11
|
+
const ModalsRenderer = ({ children, modalConfigs, onDismissed, onShow, }) => {
|
|
12
|
+
const rootId = (0, react_1.useRef)((0, non_secure_1.nanoid)());
|
|
13
|
+
return (<react_native_screens_1.ScreenStack style={styles.stackContainer}>
|
|
14
|
+
<react_native_screens_1.ScreenStackItem screenId={rootId.current} activityState={2} style={react_native_1.StyleSheet.absoluteFill} headerConfig={{
|
|
15
|
+
hidden: true,
|
|
16
|
+
}}>
|
|
17
|
+
{children}
|
|
18
|
+
</react_native_screens_1.ScreenStackItem>
|
|
19
|
+
{modalConfigs.map((config) => (<react_native_screens_1.ScreenStackItem key={config.uniqueId} {...config.viewProps} screenId={`${rootId.current}${config.uniqueId}`} activityState={2} stackPresentation={(0, utils_1.getStackPresentationType)(config)} stackAnimation={(0, utils_1.getStackAnimationType)(config)} nativeBackButtonDismissalEnabled headerConfig={{
|
|
20
|
+
hidden: true,
|
|
21
|
+
}} contentStyle={[
|
|
22
|
+
{
|
|
23
|
+
flex: 1,
|
|
24
|
+
backgroundColor: config.transparent ? 'transparent' : 'white',
|
|
25
|
+
},
|
|
26
|
+
config.viewProps?.style,
|
|
27
|
+
]} sheetAllowedDetents={config.detents} style={[
|
|
28
|
+
react_native_1.StyleSheet.absoluteFill,
|
|
29
|
+
{
|
|
30
|
+
backgroundColor: config.transparent ? 'transparent' : 'white',
|
|
31
|
+
},
|
|
32
|
+
]} onDismissed={() => {
|
|
33
|
+
onDismissed?.(config.uniqueId);
|
|
34
|
+
}} onAppear={() => {
|
|
35
|
+
onShow?.(config.uniqueId);
|
|
36
|
+
}}>
|
|
37
|
+
<ModalComponent_1.ModalComponent modalConfig={config}/>
|
|
38
|
+
</react_native_screens_1.ScreenStackItem>))}
|
|
39
|
+
</react_native_screens_1.ScreenStack>);
|
|
40
|
+
};
|
|
41
|
+
exports.ModalsRenderer = ModalsRenderer;
|
|
42
|
+
const styles = react_native_1.StyleSheet.create({
|
|
43
|
+
stackContainer: {
|
|
44
|
+
flex: 1,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=ModalsRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalsRenderer.js","sourceRoot":"","sources":["../../src/modal/ModalsRenderer.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;AAEb,kDAA2C;AAC3C,iCAA+B;AAC/B,+CAA0C;AAC1C,+DAAoE;AAEpE,qDAAkD;AAElD,mCAA0E;AAEnE,MAAM,cAAc,GAAG,CAAC,EAC7B,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,MAAM,GACc,EAAE,EAAE;IACxB,MAAM,MAAM,GAAG,IAAA,cAAM,EAAC,IAAA,mBAAM,GAAE,CAAC,CAAC;IAEhC,OAAO,CACL,CAAC,kCAAW,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CACxC;MAAA,CAAC,sCAAe,CACd,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CACzB,aAAa,CAAC,CAAC,CAAC,CAAC,CACjB,KAAK,CAAC,CAAC,yBAAU,CAAC,YAAY,CAAC,CAC/B,YAAY,CAAC,CAAC;YACZ,MAAM,EAAE,IAAI;SACb,CAAC,CACF;QAAA,CAAC,QAAQ,CACX;MAAA,EAAE,sCAAe,CACjB;MAAA,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC5B,CAAC,sCAAe,CACd,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CACrB,IAAI,MAAM,CAAC,SAAS,CAAC,CACrB,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,CAChD,aAAa,CAAC,CAAC,CAAC,CAAC,CACjB,iBAAiB,CAAC,CAAC,IAAA,gCAAwB,EAAC,MAAM,CAAC,CAAC,CACpD,cAAc,CAAC,CAAC,IAAA,6BAAqB,EAAC,MAAM,CAAC,CAAC,CAC9C,gCAAgC,CAChC,YAAY,CAAC,CAAC;gBACZ,MAAM,EAAE,IAAI;aACb,CAAC,CACF,YAAY,CAAC,CAAC;gBACZ;oBACE,IAAI,EAAE,CAAC;oBACP,eAAe,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO;iBAC9D;gBACD,MAAM,CAAC,SAAS,EAAE,KAAK;aACxB,CAAC,CACF,mBAAmB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CACpC,KAAK,CAAC,CAAC;gBACL,yBAAU,CAAC,YAAY;gBACvB;oBACE,eAAe,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO;iBAC9D;aACF,CAAC,CACF,WAAW,CAAC,CAAC,GAAG,EAAE;gBAChB,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjC,CAAC,CAAC,CACF,QAAQ,CAAC,CAAC,GAAG,EAAE;gBACb,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC,CAAC,CACF;UAAA,CAAC,+BAAc,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EACtC;QAAA,EAAE,sCAAe,CAAC,CACnB,CAAC,CACJ;IAAA,EAAE,kCAAW,CAAC,CACf,CAAC;AACJ,CAAC,CAAC;AAxDW,QAAA,cAAc,kBAwDzB;AAEF,MAAM,MAAM,GAAG,yBAAU,CAAC,MAAM,CAAC;IAC/B,cAAc,EAAE;QACd,IAAI,EAAE,CAAC;KACR;CACF,CAAC,CAAC","sourcesContent":["'use client';\n\nimport { nanoid } from 'nanoid/non-secure';\nimport { useRef } from 'react';\nimport { StyleSheet } from 'react-native';\nimport { ScreenStack, ScreenStackItem } from 'react-native-screens';\n\nimport { ModalComponent } from './ModalComponent';\nimport type { ModalsRendererProps } from './types';\nimport { getStackAnimationType, getStackPresentationType } from './utils';\n\nexport const ModalsRenderer = ({\n children,\n modalConfigs,\n onDismissed,\n onShow,\n}: ModalsRendererProps) => {\n const rootId = useRef(nanoid());\n\n return (\n <ScreenStack style={styles.stackContainer}>\n <ScreenStackItem\n screenId={rootId.current}\n activityState={2}\n style={StyleSheet.absoluteFill}\n headerConfig={{\n hidden: true,\n }}>\n {children}\n </ScreenStackItem>\n {modalConfigs.map((config) => (\n <ScreenStackItem\n key={config.uniqueId}\n {...config.viewProps}\n screenId={`${rootId.current}${config.uniqueId}`}\n activityState={2}\n stackPresentation={getStackPresentationType(config)}\n stackAnimation={getStackAnimationType(config)}\n nativeBackButtonDismissalEnabled\n headerConfig={{\n hidden: true,\n }}\n contentStyle={[\n {\n flex: 1,\n backgroundColor: config.transparent ? 'transparent' : 'white',\n },\n config.viewProps?.style,\n ]}\n sheetAllowedDetents={config.detents}\n style={[\n StyleSheet.absoluteFill,\n {\n backgroundColor: config.transparent ? 'transparent' : 'white',\n },\n ]}\n onDismissed={() => {\n onDismissed?.(config.uniqueId);\n }}\n onAppear={() => {\n onShow?.(config.uniqueId);\n }}>\n <ModalComponent modalConfig={config} />\n </ScreenStackItem>\n ))}\n </ScreenStack>\n );\n};\n\nconst styles = StyleSheet.create({\n stackContainer: {\n flex: 1,\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalsRenderer.web.d.ts","sourceRoot":"","sources":["../../src/modal/ModalsRenderer.web.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAe,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAMhE,eAAO,MAAM,cAAc,GAAI,kDAK5B,mBAAmB,gCAarB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ModalsRenderer = void 0;
|
|
5
|
+
const native_1 = require("@react-navigation/native");
|
|
6
|
+
const react_native_1 = require("react-native");
|
|
7
|
+
const ModalComponent_1 = require("./ModalComponent");
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
const ModalStackRouteDrawer_web_1 = require("./web/ModalStackRouteDrawer.web");
|
|
10
|
+
const TransparentModalStackRouteDrawer_web_1 = require("./web/TransparentModalStackRouteDrawer.web");
|
|
11
|
+
const utils_2 = require("./web/utils");
|
|
12
|
+
const ModalsRenderer = ({ children, modalConfigs, onDismissed, onShow, }) => {
|
|
13
|
+
return (<div style={{ flex: 1, display: 'flex' }}>
|
|
14
|
+
{children}
|
|
15
|
+
{modalConfigs.map((config) => (<Modal key={config.uniqueId} config={config} onDismissed={() => onDismissed?.(config.uniqueId)}/>))}
|
|
16
|
+
</div>);
|
|
17
|
+
};
|
|
18
|
+
exports.ModalsRenderer = ModalsRenderer;
|
|
19
|
+
function Modal({ config, onDismissed }) {
|
|
20
|
+
const { colors } = (0, native_1.useTheme)();
|
|
21
|
+
const presentation = (0, utils_1.getStackPresentationType)(config);
|
|
22
|
+
const isTransparentModal = (0, utils_2.isTransparentModalPresentation)({ presentation });
|
|
23
|
+
const SelectedModalComponent = isTransparentModal
|
|
24
|
+
? TransparentModalStackRouteDrawer_web_1.TransparentModalStackRouteDrawer
|
|
25
|
+
: ModalStackRouteDrawer_web_1.ModalStackRouteDrawer;
|
|
26
|
+
return (<SelectedModalComponent routeKey={config.uniqueId} onDismiss={onDismissed} themeColors={colors} key={config.uniqueId} options={{
|
|
27
|
+
presentation,
|
|
28
|
+
animation: (0, utils_1.getStackAnimationType)(config),
|
|
29
|
+
headerShown: false,
|
|
30
|
+
sheetAllowedDetents: config.detents,
|
|
31
|
+
}} renderScreen={() => (<react_native_1.View style={{ flex: 1 }}>
|
|
32
|
+
<react_native_1.View {...config.viewProps} style={[{ flex: 1 }, config.viewProps?.style]}>
|
|
33
|
+
<ModalComponent_1.ModalComponent modalConfig={config}/>
|
|
34
|
+
</react_native_1.View>
|
|
35
|
+
</react_native_1.View>)}/>);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=ModalsRenderer.web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModalsRenderer.web.js","sourceRoot":"","sources":["../../src/modal/ModalsRenderer.web.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;AAEb,qDAAoD;AACpD,+CAAoC;AAEpC,qDAAkD;AAElD,mCAA0E;AAC1E,+EAAwE;AACxE,qGAA8F;AAC9F,uCAA6D;AAEtD,MAAM,cAAc,GAAG,CAAC,EAC7B,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,MAAM,GACc,EAAE,EAAE;IACxB,OAAO,CACL,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CACvC;MAAA,CAAC,QAAQ,CACT;MAAA,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC5B,CAAC,KAAK,CACJ,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CACrB,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAClD,CACH,CAAC,CACJ;IAAA,EAAE,GAAG,CAAC,CACP,CAAC;AACJ,CAAC,CAAC;AAlBW,QAAA,cAAc,kBAkBzB;AAOF,SAAS,KAAK,CAAC,EAAE,MAAM,EAAE,WAAW,EAAc;IAChD,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,iBAAQ,GAAE,CAAC;IAE9B,MAAM,YAAY,GAAG,IAAA,gCAAwB,EAAC,MAAM,CAAC,CAAC;IACtD,MAAM,kBAAkB,GAAG,IAAA,sCAA8B,EAAC,EAAE,YAAY,EAAE,CAAC,CAAC;IAE5E,MAAM,sBAAsB,GAAG,kBAAkB;QAC/C,CAAC,CAAC,uEAAgC;QAClC,CAAC,CAAC,iDAAqB,CAAC;IAE1B,OAAO,CACL,CAAC,sBAAsB,CACrB,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAC1B,SAAS,CAAC,CAAC,WAAW,CAAC,CACvB,WAAW,CAAC,CAAC,MAAM,CAAC,CACpB,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CACrB,OAAO,CAAC,CAAC;YACP,YAAY;YACZ,SAAS,EAAE,IAAA,6BAAqB,EAAC,MAAM,CAAC;YACxC,WAAW,EAAE,KAAK;YAClB,mBAAmB,EAAE,MAAM,CAAC,OAAO;SACpC,CAAC,CACF,YAAY,CAAC,CAAC,GAAG,EAAE,CAAC,CAClB,CAAC,mBAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CACvB;UAAA,CAAC,mBAAI,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CACxE;YAAA,CAAC,+BAAc,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EACtC;UAAA,EAAE,mBAAI,CACR;QAAA,EAAE,mBAAI,CAAC,CACR,CAAC,EACF,CACH,CAAC;AACJ,CAAC","sourcesContent":["'use client';\n\nimport { useTheme } from '@react-navigation/native';\nimport { View } from 'react-native';\n\nimport { ModalComponent } from './ModalComponent';\nimport type { ModalConfig, ModalsRendererProps } from './types';\nimport { getStackAnimationType, getStackPresentationType } from './utils';\nimport { ModalStackRouteDrawer } from './web/ModalStackRouteDrawer.web';\nimport { TransparentModalStackRouteDrawer } from './web/TransparentModalStackRouteDrawer.web';\nimport { isTransparentModalPresentation } from './web/utils';\n\nexport const ModalsRenderer = ({\n children,\n modalConfigs,\n onDismissed,\n onShow,\n}: ModalsRendererProps) => {\n return (\n <div style={{ flex: 1, display: 'flex' }}>\n {children}\n {modalConfigs.map((config) => (\n <Modal\n key={config.uniqueId}\n config={config}\n onDismissed={() => onDismissed?.(config.uniqueId)}\n />\n ))}\n </div>\n );\n};\n\ninterface ModalProps {\n config: ModalConfig;\n onDismissed: () => void;\n}\n\nfunction Modal({ config, onDismissed }: ModalProps) {\n const { colors } = useTheme();\n\n const presentation = getStackPresentationType(config);\n const isTransparentModal = isTransparentModalPresentation({ presentation });\n\n const SelectedModalComponent = isTransparentModal\n ? TransparentModalStackRouteDrawer\n : ModalStackRouteDrawer;\n\n return (\n <SelectedModalComponent\n routeKey={config.uniqueId}\n onDismiss={onDismissed}\n themeColors={colors}\n key={config.uniqueId}\n options={{\n presentation,\n animation: getStackAnimationType(config),\n headerShown: false,\n sheetAllowedDetents: config.detents,\n }}\n renderScreen={() => (\n <View style={{ flex: 1 }}>\n <View {...config.viewProps} style={[{ flex: 1 }, config.viewProps?.style]}>\n <ModalComponent modalConfig={config} />\n </View>\n </View>\n )}\n />\n );\n}\n"]}
|