diff --git a/modules/bottom-sheet/index.ts b/modules/bottom-sheet/index.ts index ea0c87b83e..2eae5bfc2f 100644 --- a/modules/bottom-sheet/index.ts +++ b/modules/bottom-sheet/index.ts @@ -1,4 +1,13 @@ -import {BottomSheetState, BottomSheetViewProps} from './src/BottomSheet.types' +import { + BottomSheetSnapPoint, + BottomSheetState, + BottomSheetViewProps, +} from './src/BottomSheet.types' import {BottomSheetView} from './src/BottomSheetView' -export {type BottomSheetState, BottomSheetView, type BottomSheetViewProps} +export { + BottomSheetSnapPoint, + type BottomSheetState, + BottomSheetView, + type BottomSheetViewProps, +} diff --git a/modules/bottom-sheet/ios/SheetView.swift b/modules/bottom-sheet/ios/SheetView.swift index 2146f1bc03..c4db60994c 100644 --- a/modules/bottom-sheet/ios/SheetView.swift +++ b/modules/bottom-sheet/ios/SheetView.swift @@ -52,6 +52,22 @@ class SheetView: ExpoView, UISheetPresentationControllerDelegate { } } } + private var selectedDetentIdentifier: UISheetPresentationController.Detent.Identifier? { + didSet { + guard let selectedDetentIdentifier else { + return + } + if selectedDetentIdentifier == .large { + onSnapPointChange([ + "snapPoint": 2 + ]) + } else { + onSnapPointChange([ + "snapPoint": 1 + ]) + } + } + } // MARK: - Lifecycle @@ -104,11 +120,12 @@ class SheetView: ExpoView, UISheetPresentationControllerDelegate { } let sheetVc = SheetViewController() + sheetVc.setDetents(contentHeight: self.clampHeight(contentHeight), preventExpansion: self.preventExpansion) if let sheet = sheetVc.sheetPresentationController { sheet.delegate = self sheet.preferredCornerRadius = self.cornerRadius + self.selectedDetentIdentifier = sheet.selectedDetentIdentifier } - sheetVc.setDetents(contentHeight: self.clampHeight(contentHeight), preventExpansion: self.preventExpansion) sheetVc.view.addSubview(innerView) self.sheetVc = sheetVc @@ -161,16 +178,6 @@ class SheetView: ExpoView, UISheetPresentationControllerDelegate { } func sheetPresentationControllerDidChangeSelectedDetentIdentifier(_ sheetPresentationController: UISheetPresentationController) { - let identifier = sheetPresentationController.selectedDetentIdentifier - - if identifier == .large { - onSnapPointChange([ - "snapPoint": 2, - ]) - } else { - onSnapPointChange([ - "snapPoint": 1, - ]) - } + self.selectedDetentIdentifier = sheetPresentationController.selectedDetentIdentifier } } diff --git a/modules/bottom-sheet/src/BottomSheet.types.ts b/modules/bottom-sheet/src/BottomSheet.types.ts index 8177df5787..d08e985fa7 100644 --- a/modules/bottom-sheet/src/BottomSheet.types.ts +++ b/modules/bottom-sheet/src/BottomSheet.types.ts @@ -3,6 +3,12 @@ import {ColorValue, NativeSyntheticEvent} from 'react-native' export type BottomSheetState = 'closed' | 'closing' | 'open' | 'opening' +export enum BottomSheetSnapPoint { + Hidden, + Partial, + Full, +} + export interface BottomSheetViewProps { children: React.ReactNode cornerRadius?: number @@ -15,8 +21,11 @@ export interface BottomSheetViewProps { minHeight?: number maxHeight?: number + onAttemptDismiss?: (event: NativeSyntheticEvent) => void + onSnapPointChange?: ( + event: NativeSyntheticEvent<{snapPoint: BottomSheetSnapPoint}>, + ) => void onStateChange?: ( event: NativeSyntheticEvent<{state: BottomSheetState}>, ) => void - onAttemptDismiss?: (event: NativeSyntheticEvent) => void } diff --git a/src/components/Dialog/context.ts b/src/components/Dialog/context.ts index 27b8a56375..058d09b25d 100644 --- a/src/components/Dialog/context.ts +++ b/src/components/Dialog/context.ts @@ -6,10 +6,12 @@ import { DialogControlRefProps, DialogOuterProps, } from '#/components/Dialog/types' +import {BottomSheetSnapPoint} from '../../../modules/bottom-sheet/src/BottomSheet.types' export const Context = React.createContext({ close: () => {}, insideDialog: false, + snapPoint: BottomSheetSnapPoint.Hidden, }) export function useDialogContext() { diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx index 0695c11ebf..54d303396b 100644 --- a/src/components/Dialog/index.tsx +++ b/src/components/Dialog/index.tsx @@ -8,7 +8,7 @@ import {isIOS} from '#/platform/detection' import {useDialogStateControlContext} from '#/state/dialogs' import {List, ListMethods, ListProps} from '#/view/com/util/List' import {atoms as a, flatten, useTheme} from '#/alf' -import {Context} from '#/components/Dialog/context' +import {Context, useDialogContext} from '#/components/Dialog/context' import { DialogControlProps, DialogInnerProps, @@ -16,7 +16,10 @@ import { } from '#/components/Dialog/types' import {createInput} from '#/components/forms/TextField' import {Portal} from '#/components/Portal' -import {BottomSheetView} from '../../../modules/bottom-sheet' +import { + BottomSheetSnapPoint, + BottomSheetView, +} from '../../../modules/bottom-sheet' export {useDialogContext, useDialogControl} from '#/components/Dialog/context' export * from '#/components/Dialog/types' @@ -57,6 +60,10 @@ export function OuterWithoutPortal({ const closeCallbacks = React.useRef<(() => void)[]>([]) const {setDialogIsOpen} = useDialogStateControlContext() + const [snapPoint, setSnapPoint] = React.useState( + BottomSheetSnapPoint.Partial, + ) + const callQueuedCallbacks = React.useCallback(() => { for (const cb of closeCallbacks.current) { try { @@ -103,7 +110,10 @@ export function OuterWithoutPortal({ [open, close], ) - const context = React.useMemo(() => ({close, insideDialog: true}), [close]) + const context = React.useMemo( + () => ({close, insideDialog: true, snapPoint}), + [close, snapPoint], + ) const Wrapper = isIOS ? View : GestureHandlerRootView @@ -113,6 +123,10 @@ export function OuterWithoutPortal({ ref={ref} topInset={30} bottomInset={insets.bottom} + onSnapPointChange={e => { + console.log(e.nativeEvent) + setSnapPoint(e.nativeEvent.snapPoint) + }} onStateChange={e => { if (e.nativeEvent.state === 'closed') { onCloseAnimationComplete() @@ -147,8 +161,12 @@ export function Inner({children, style}: DialogInnerProps) { export const ScrollableInner = React.forwardRef( function ScrollableInner({children, style}, ref) { const insets = useSafeAreaInsets() + const {snapPoint} = useDialogContext() return ( - + {children} diff --git a/src/components/Dialog/types.ts b/src/components/Dialog/types.ts index c5219e5eab..a964f29c89 100644 --- a/src/components/Dialog/types.ts +++ b/src/components/Dialog/types.ts @@ -7,6 +7,7 @@ import type { import {ViewStyleProp} from '#/alf' import {BottomSheetViewProps} from '../../../modules/bottom-sheet' +import {BottomSheetSnapPoint} from '../../../modules/bottom-sheet/src/BottomSheet.types' type A11yProps = Required @@ -38,6 +39,7 @@ export type DialogControlProps = DialogControlRefProps & { export type DialogContextProps = { close: DialogControlProps['close'] insideDialog: boolean + snapPoint: BottomSheetSnapPoint } export type DialogControlOpenOptions = {