diff --git a/src/components/ModalSheetView/ModalSheetView.tsx b/src/components/ModalSheetView/ModalSheetView.tsx index 58f43e58..203abedf 100644 --- a/src/components/ModalSheetView/ModalSheetView.tsx +++ b/src/components/ModalSheetView/ModalSheetView.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import { StyleSheet } from 'react-native'; +import { Helpers } from 'react-native-ios-utilities'; import type { ModalSheetViewProps, ModalSheetViewRef } from './ModalSheetViewTypes'; import type { ModalSheetViewContentProps } from './ModalSheetViewContentTypes'; @@ -15,17 +16,51 @@ export const ModalSheetView = React.forwardRef< const nativeRef = React.useRef(); + const callbacksToInvokeOnNextRender = React.useRef void>>([]); + React.useEffect(() => { + const totalItems = callbacksToInvokeOnNextRender.current.length; + + for (let index = 0; index < totalItems; index++) { + const callback = callbacksToInvokeOnNextRender.current.pop(); + callback!(); + }; + }); + + const [ + shouldExplicitlyMountModalContents, + setShouldExplicitlyMountModalContents + ] = React.useState(false); + const [ modalSheetContentMap, setModalSheetContentMap ] = React.useState({}); + + const isModalContentLazy = props.isModalContentLazy ?? true; + + const shouldMountModalContents = + !isModalContentLazy + || shouldExplicitlyMountModalContents; + React.useImperativeHandle(ref, () => ({ presentModal: async (commandArgs) => { if(nativeRef.current == null) { throw Error("Unable to get ref to native sheet"); }; + const shouldWaitToMount = + !shouldExplicitlyMountModalContents + && isModalContentLazy; + + setShouldExplicitlyMountModalContents(true); + + if(shouldWaitToMount){ + await Helpers.promiseWithTimeout(300, new Promise(resolve => { + callbacksToInvokeOnNextRender.current.push(resolve); + })); + }; + await nativeRef.current.presentModal({ isAnimated: true, ...commandArgs, @@ -56,11 +91,14 @@ export const ModalSheetView = React.forwardRef< const shouldEnableDebugBackgroundColors = props.shouldEnableDebugBackgroundColors ?? false; + + const children = React.Children.map(props.children, (child) => { return React.cloneElement( child as React.ReactElement, { modalSheetContentMap, + shouldMountModalContent: shouldMountModalContents, } ); }); diff --git a/src/components/ModalSheetView/ModalSheetViewContent.tsx b/src/components/ModalSheetView/ModalSheetViewContent.tsx index 6fd17651..c26944e2 100644 --- a/src/components/ModalSheetView/ModalSheetViewContent.tsx +++ b/src/components/ModalSheetView/ModalSheetViewContent.tsx @@ -19,6 +19,8 @@ export function ModalSheetViewContent( props.contentContainerStyle, ]; + const shouldMountModalContent = props.shouldMountModalContent ?? false; + const detachedSubviewEntry = (viewID != null ? props.modalSheetContentMap?.[viewID] : undefined ) ?? DEFAULT_SHEET_CONTENT_ENTRY; @@ -50,13 +52,13 @@ export function ModalSheetViewContent( }} > {IS_USING_NEW_ARCH ? ( - props.children + shouldMountModalContent && props.children ) : ( - {props.children} + {shouldMountModalContent && props.children} )} diff --git a/src/components/ModalSheetView/ModalSheetViewContentTypes.tsx b/src/components/ModalSheetView/ModalSheetViewContentTypes.tsx index cf1ffbe5..dcaadf5d 100644 --- a/src/components/ModalSheetView/ModalSheetViewContentTypes.tsx +++ b/src/components/ModalSheetView/ModalSheetViewContentTypes.tsx @@ -16,6 +16,7 @@ export type ModalSheetViewContentBaseProps = { contentContainerStyle?: ViewStyle; isParentDetached?: boolean; modalSheetContentMap?: ModalSheetContentMap; + shouldMountModalContent?: boolean; }; export type ModalSheetViewContentProps = diff --git a/src/components/ModalSheetView/ModalSheetViewTypes.tsx b/src/components/ModalSheetView/ModalSheetViewTypes.tsx index 11df65e9..b8ba8406 100644 --- a/src/components/ModalSheetView/ModalSheetViewTypes.tsx +++ b/src/components/ModalSheetView/ModalSheetViewTypes.tsx @@ -31,11 +31,12 @@ export type ModalSheetViewRef = & ModalSheetViewRefInheritedRemapped; export type ModalSheetViewInheritedProps = Pick; -export type ModalSheetViewBaseProps = {}; +export type ModalSheetViewBaseProps = { + isModalContentLazy?: boolean; +}; export type ModalSheetViewProps = PropsWithChildren< ModalSheetViewInheritedProps