diff --git a/src/components/ModalSheetView/ModalSheetView.tsx b/src/components/ModalSheetView/ModalSheetView.tsx index 2969f4f1..70dd1d3d 100644 --- a/src/components/ModalSheetView/ModalSheetView.tsx +++ b/src/components/ModalSheetView/ModalSheetView.tsx @@ -85,6 +85,9 @@ export const ModalSheetView = React.forwardRef< return await nativeRef.current.getModalMetrics(); }, + getEventEmitter: () => { + return nativeRef.current!.getEventEmitter(); + }, })); const shouldEnableDebugBackgroundColors = diff --git a/src/functions/ModalSheetViewEventEmitter.ts b/src/functions/ModalSheetViewEventEmitter.ts new file mode 100644 index 00000000..621f610a --- /dev/null +++ b/src/functions/ModalSheetViewEventEmitter.ts @@ -0,0 +1,29 @@ +import type { TSEventEmitter } from '@dominicstop/ts-event-emitter'; +import type { RemapObject } from 'react-native-ios-utilities'; +import type { OnModalDidHideEventPayload, OnModalDidPresentEventPayload, OnModalDidShowEventPayload, OnModalWillHideEventPayload, OnModalWillPresentEventPayload, OnModalWillShowEventPayload } from '../types/CommonModalEvents'; + + +export enum ModalSheetViewEvents { + onModalWillPresent = "onModalWillPresent", + onModalDidPresent = "onModalDidPresent", + onModalWillShow = "onModalWillShow", + onModalDidShow = "onModalDidShow", + onModalWillHide = "onModalWillHide", + onModalDidHide = "onModalDidHide", +}; + +export type ModalSheetViewEventKeys = keyof typeof ModalSheetViewEvents; + +export type ModalSheetViewEventEmitterMap = RemapObject; + +export type ModalSheetViewEventEmitter = TSEventEmitter< + ModalSheetViewEvents, + ModalSheetViewEventEmitterMap +>; diff --git a/src/hooks/useLazyRef.ts b/src/hooks/useLazyRef.ts new file mode 100644 index 00000000..cac8eb2a --- /dev/null +++ b/src/hooks/useLazyRef.ts @@ -0,0 +1,13 @@ +import React from "react"; + +export function useLazyRef( + providerCallback: () => T +) { + const ref = React.useRef(); + + if (ref.current === undefined) { + ref.current = providerCallback(); + }; + + return ref; +}; \ No newline at end of file diff --git a/src/native_components/RNIModalSheetVIew/RNIModalSheetView.tsx b/src/native_components/RNIModalSheetVIew/RNIModalSheetView.tsx index a45b383d..29e2a2cc 100644 --- a/src/native_components/RNIModalSheetVIew/RNIModalSheetView.tsx +++ b/src/native_components/RNIModalSheetVIew/RNIModalSheetView.tsx @@ -1,10 +1,15 @@ import * as React from 'react'; import { StyleSheet } from 'react-native'; + import { Helpers, type StateViewID, type StateReactTag } from 'react-native-ios-utilities'; +import { TSEventEmitter } from '@dominicstop/ts-event-emitter'; import { RNIModalSheetNativeView } from './RNIModalSheetNativeView'; +import { useLazyRef } from '../../hooks/useLazyRef'; + import type { RNIModalSheetViewProps, RNIModalSheetViewRef, } from './RNIModalSheetViewTypes'; import type { ModalMetrics } from '../../types/ModalMetrics'; +import type { ModalSheetViewEventEmitter } from '../../functions/ModalSheetViewEventEmitter'; export const RNIModalSheetView = React.forwardRef< @@ -13,6 +18,9 @@ export const RNIModalSheetView = React.forwardRef< >((props, ref) => { const [viewID, setViewID] = React.useState(); const [reactTag, setReactTag] = React.useState(); + + const modalEventEmitterRef = + useLazyRef(() => new TSEventEmitter()); const [ cachedModalMetrics, @@ -26,6 +34,9 @@ export const RNIModalSheetView = React.forwardRef< getViewID: () => { return viewID; }, + getEventEmitter: () => { + return modalEventEmitterRef.current!; + }, presentModal: async (commandArgs) => { if(viewID == null) return; const module = Helpers.getRNIUtilitiesModule(); @@ -82,6 +93,60 @@ export const RNIModalSheetView = React.forwardRef< props.onDidSetViewID?.(event); event.stopPropagation(); }} + onModalWillPresent={(event) => { + props.onModalWillPresent?.(event); + event.stopPropagation(); + + modalEventEmitterRef.current!.emit( + 'onModalWillPresent', + event.nativeEvent + ); + }} + onModalDidPresent={(event) => { + props.onModalDidPresent?.(event); + event.stopPropagation(); + + modalEventEmitterRef.current!.emit( + 'onModalDidPresent', + event.nativeEvent + ); + }} + onModalWillShow={(event) => { + props.onModalWillShow?.(event); + event.stopPropagation(); + + modalEventEmitterRef.current!.emit( + 'onModalWillShow', + event.nativeEvent + ); + }} + onModalDidShow={(event) => { + props.onModalDidShow?.(event); + event.stopPropagation(); + + modalEventEmitterRef.current!.emit( + 'onModalDidShow', + event.nativeEvent + ); + }} + onModalWillHide={(event) => { + props.onModalWillHide?.(event); + event.stopPropagation(); + + modalEventEmitterRef.current!.emit( + 'onModalWillHide', + event.nativeEvent + ); + }} + onModalDidHide={(event) => { + props.onModalDidHide?.(event); + event.stopPropagation(); + + modalEventEmitterRef.current!.emit( + 'onModalDidHide', + event.nativeEvent + ); + }} > {props.children} diff --git a/src/native_components/RNIModalSheetVIew/RNIModalSheetViewTypes.ts b/src/native_components/RNIModalSheetVIew/RNIModalSheetViewTypes.ts index d6b21750..09001300 100644 --- a/src/native_components/RNIModalSheetVIew/RNIModalSheetViewTypes.ts +++ b/src/native_components/RNIModalSheetVIew/RNIModalSheetViewTypes.ts @@ -1,3 +1,5 @@ +import type React from "react"; + import type { PropsWithChildren } from "react"; import type { ViewProps } from "react-native"; import type { StateReactTag, StateViewID } from "react-native-ios-utilities"; @@ -5,12 +7,15 @@ import type { StateReactTag, StateViewID } from "react-native-ios-utilities"; import type { RNIModalSheetNativeViewProps } from "./RNIModalSheetNativeView"; import type { ModalMetrics } from "../../types/ModalMetrics"; +import type { ModalSheetViewEventEmitter } from "../../functions/ModalSheetViewEventEmitter"; export type RNIModalSheetViewRef = { getViewID: () => StateViewID; getReactTag: () => StateReactTag; + getEventEmitter: () => ModalSheetViewEventEmitter; + presentModal: (commandArgs: { isAnimated: boolean; }) => Promise;