diff --git a/src/components/Dialog/context.ts b/src/components/Dialog/context.ts index b28b9f5a25..f0c7c983a9 100644 --- a/src/components/Dialog/context.ts +++ b/src/components/Dialog/context.ts @@ -1,7 +1,11 @@ import React from 'react' import {useDialogStateContext} from '#/state/dialogs' -import {DialogContextProps, DialogControlProps} from '#/components/Dialog/types' +import { + DialogContextProps, + DialogControlProps, + DialogOuterProps, +} from '#/components/Dialog/types' export const Context = React.createContext({ close: () => {}, @@ -11,7 +15,7 @@ export function useDialogContext() { return React.useContext(Context) } -export function useDialogControl() { +export function useDialogControl(): DialogOuterProps['control'] { const id = React.useId() const control = React.useRef({ open: () => {}, @@ -30,6 +34,6 @@ export function useDialogControl() { return { ref: control, open: () => control.current.open(), - close: () => control.current.close(), + close: cb => control.current.close(cb), } } diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx index 5295350512..9feb080dec 100644 --- a/src/components/Dialog/index.tsx +++ b/src/components/Dialog/index.tsx @@ -7,6 +7,7 @@ import BottomSheet, { BottomSheetView, } from '@gorhom/bottom-sheet' import {useSafeAreaInsets} from 'react-native-safe-area-context' +import EventEmitter from 'eventemitter3' import {useTheme, atoms as a, flatten} from '#/alf' import {Portal} from '#/components/Portal' @@ -35,6 +36,7 @@ export function Outer({ const sheetOptions = nativeOptions?.sheet || {} const hasSnapPoints = !!sheetOptions.snapPoints const insets = useSafeAreaInsets() + const events = React.useRef(new EventEmitter<'close'>()).current /* * Used to manage open/closed, but index is otherwise handled internally by `BottomSheet` @@ -54,9 +56,15 @@ export function Outer({ [setOpenIndex], ) - const close = React.useCallback(() => { - sheet.current?.close() - }, []) + const close = React.useCallback( + cb => { + if (cb) { + events.on('close', cb) + } + sheet.current?.close() + }, + [events], + ) useImperativeHandle( control.ref, @@ -70,11 +78,13 @@ export function Outer({ const onChange = React.useCallback( (index: number) => { if (index === -1) { + events.emit('close') + events.removeAllListeners('close') onClose?.() setOpenIndex(-1) } }, - [onClose, setOpenIndex], + [onClose, setOpenIndex, events], ) const context = React.useMemo(() => ({close}), [close]) diff --git a/src/components/Dialog/types.ts b/src/components/Dialog/types.ts index 00178926a0..75ba825ac9 100644 --- a/src/components/Dialog/types.ts +++ b/src/components/Dialog/types.ts @@ -22,15 +22,13 @@ export type DialogControlOpenOptions = { export type DialogControlProps = { open: (options?: DialogControlOpenOptions) => void - close: () => void + close: (callback?: () => void) => void } export type DialogOuterProps = { control: { ref: React.RefObject - open: (index?: number) => void - close: () => void - } + } & DialogControlProps onClose?: () => void nativeOptions?: { sheet?: Omit diff --git a/src/view/screens/Storybook/Dialogs.tsx b/src/view/screens/Storybook/Dialogs.tsx index 821ac3c886..09be124db5 100644 --- a/src/view/screens/Storybook/Dialogs.tsx +++ b/src/view/screens/Storybook/Dialogs.tsx @@ -110,7 +110,11 @@ export function Dialogs() { variant="outline" color="primary" size="small" - onPress={() => scrollable.close()} + onPress={() => + scrollable.close(() => { + console.log('CLOSED') + }) + } label="Open basic dialog"> Close dialog