@hanzogui/sheet 2.0.0
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/LICENSE +21 -0
- package/controller/index.cjs +2 -0
- package/controller/index.d.ts +5 -0
- package/controller/index.js +2 -0
- package/controller/index.native.cjs +2 -0
- package/controller/index.native.js +2 -0
- package/dist/cjs/GestureDetectorWrapper.cjs +48 -0
- package/dist/cjs/GestureDetectorWrapper.native.js +53 -0
- package/dist/cjs/GestureDetectorWrapper.native.js.map +1 -0
- package/dist/cjs/GestureSheetContext.cjs +52 -0
- package/dist/cjs/GestureSheetContext.native.js +56 -0
- package/dist/cjs/GestureSheetContext.native.js.map +1 -0
- package/dist/cjs/Sheet.cjs +117 -0
- package/dist/cjs/Sheet.native.js +120 -0
- package/dist/cjs/Sheet.native.js.map +1 -0
- package/dist/cjs/SheetContext.cjs +32 -0
- package/dist/cjs/SheetContext.native.js +35 -0
- package/dist/cjs/SheetContext.native.js.map +1 -0
- package/dist/cjs/SheetController.cjs +65 -0
- package/dist/cjs/SheetController.native.js +71 -0
- package/dist/cjs/SheetController.native.js.map +1 -0
- package/dist/cjs/SheetImplementationCustom.cjs +472 -0
- package/dist/cjs/SheetImplementationCustom.native.js +524 -0
- package/dist/cjs/SheetImplementationCustom.native.js.map +1 -0
- package/dist/cjs/SheetScrollView.cjs +180 -0
- package/dist/cjs/SheetScrollView.native.js +197 -0
- package/dist/cjs/SheetScrollView.native.js.map +1 -0
- package/dist/cjs/constants.cjs +32 -0
- package/dist/cjs/constants.native.js +35 -0
- package/dist/cjs/constants.native.js.map +1 -0
- package/dist/cjs/contexts.cjs +42 -0
- package/dist/cjs/contexts.native.js +45 -0
- package/dist/cjs/contexts.native.js.map +1 -0
- package/dist/cjs/controller.cjs +29 -0
- package/dist/cjs/controller.native.js +32 -0
- package/dist/cjs/controller.native.js.map +1 -0
- package/dist/cjs/createSheet.cjs +191 -0
- package/dist/cjs/createSheet.native.js +208 -0
- package/dist/cjs/createSheet.native.js.map +1 -0
- package/dist/cjs/gestureState.cjs +39 -0
- package/dist/cjs/gestureState.native.js +42 -0
- package/dist/cjs/gestureState.native.js.map +1 -0
- package/dist/cjs/helpers.cjs +31 -0
- package/dist/cjs/helpers.native.js +35 -0
- package/dist/cjs/helpers.native.js.map +1 -0
- package/dist/cjs/index.cjs +28 -0
- package/dist/cjs/index.native.js +31 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/cjs/nativeSheet.cjs +87 -0
- package/dist/cjs/nativeSheet.native.js +101 -0
- package/dist/cjs/nativeSheet.native.js.map +1 -0
- package/dist/cjs/setupGestureHandler.cjs +46 -0
- package/dist/cjs/setupGestureHandler.native.js +50 -0
- package/dist/cjs/setupGestureHandler.native.js.map +1 -0
- package/dist/cjs/types.cjs +16 -0
- package/dist/cjs/types.native.js +19 -0
- package/dist/cjs/types.native.js.map +1 -0
- package/dist/cjs/useGestureHandlerPan.cjs +136 -0
- package/dist/cjs/useGestureHandlerPan.native.js +145 -0
- package/dist/cjs/useGestureHandlerPan.native.js.map +1 -0
- package/dist/cjs/useKeyboardControllerSheet.cjs +38 -0
- package/dist/cjs/useKeyboardControllerSheet.native.js +114 -0
- package/dist/cjs/useKeyboardControllerSheet.native.js.map +1 -0
- package/dist/cjs/useSheet.cjs +27 -0
- package/dist/cjs/useSheet.native.js +32 -0
- package/dist/cjs/useSheet.native.js.map +1 -0
- package/dist/cjs/useSheetController.cjs +50 -0
- package/dist/cjs/useSheetController.native.js +53 -0
- package/dist/cjs/useSheetController.native.js.map +1 -0
- package/dist/cjs/useSheetOffscreenSize.cjs +51 -0
- package/dist/cjs/useSheetOffscreenSize.native.js +61 -0
- package/dist/cjs/useSheetOffscreenSize.native.js.map +1 -0
- package/dist/cjs/useSheetOpenState.cjs +49 -0
- package/dist/cjs/useSheetOpenState.native.js +56 -0
- package/dist/cjs/useSheetOpenState.native.js.map +1 -0
- package/dist/cjs/useSheetProviderProps.cjs +133 -0
- package/dist/cjs/useSheetProviderProps.native.js +153 -0
- package/dist/cjs/useSheetProviderProps.native.js.map +1 -0
- package/dist/cjs/useSheetScrollViewGestures.cjs +123 -0
- package/dist/cjs/useSheetScrollViewGestures.native.js +110 -0
- package/dist/cjs/useSheetScrollViewGestures.native.js.map +1 -0
- package/dist/esm/GestureDetectorWrapper.mjs +25 -0
- package/dist/esm/GestureDetectorWrapper.mjs.map +1 -0
- package/dist/esm/GestureDetectorWrapper.native.js +27 -0
- package/dist/esm/GestureDetectorWrapper.native.js.map +1 -0
- package/dist/esm/GestureSheetContext.mjs +28 -0
- package/dist/esm/GestureSheetContext.mjs.map +1 -0
- package/dist/esm/GestureSheetContext.native.js +29 -0
- package/dist/esm/GestureSheetContext.native.js.map +1 -0
- package/dist/esm/Sheet.mjs +89 -0
- package/dist/esm/Sheet.mjs.map +1 -0
- package/dist/esm/Sheet.native.js +89 -0
- package/dist/esm/Sheet.native.js.map +1 -0
- package/dist/esm/SheetContext.mjs +6 -0
- package/dist/esm/SheetContext.mjs.map +1 -0
- package/dist/esm/SheetContext.native.js +6 -0
- package/dist/esm/SheetContext.native.js.map +1 -0
- package/dist/esm/SheetController.mjs +31 -0
- package/dist/esm/SheetController.mjs.map +1 -0
- package/dist/esm/SheetController.native.js +34 -0
- package/dist/esm/SheetController.native.js.map +1 -0
- package/dist/esm/SheetImplementationCustom.mjs +437 -0
- package/dist/esm/SheetImplementationCustom.mjs.map +1 -0
- package/dist/esm/SheetImplementationCustom.native.js +487 -0
- package/dist/esm/SheetImplementationCustom.native.js.map +1 -0
- package/dist/esm/SheetScrollView.mjs +146 -0
- package/dist/esm/SheetScrollView.mjs.map +1 -0
- package/dist/esm/SheetScrollView.native.js +160 -0
- package/dist/esm/SheetScrollView.native.js.map +1 -0
- package/dist/esm/constants.mjs +6 -0
- package/dist/esm/constants.mjs.map +1 -0
- package/dist/esm/constants.native.js +6 -0
- package/dist/esm/constants.native.js.map +1 -0
- package/dist/esm/contexts.mjs +7 -0
- package/dist/esm/contexts.mjs.map +1 -0
- package/dist/esm/contexts.native.js +7 -0
- package/dist/esm/contexts.native.js.map +1 -0
- package/dist/esm/controller.mjs +4 -0
- package/dist/esm/controller.mjs.map +1 -0
- package/dist/esm/controller.native.js +4 -0
- package/dist/esm/controller.native.js.map +1 -0
- package/dist/esm/createSheet.mjs +168 -0
- package/dist/esm/createSheet.mjs.map +1 -0
- package/dist/esm/createSheet.native.js +182 -0
- package/dist/esm/createSheet.native.js.map +1 -0
- package/dist/esm/gestureState.mjs +13 -0
- package/dist/esm/gestureState.mjs.map +1 -0
- package/dist/esm/gestureState.native.js +13 -0
- package/dist/esm/gestureState.native.js.map +1 -0
- package/dist/esm/helpers.mjs +8 -0
- package/dist/esm/helpers.mjs.map +1 -0
- package/dist/esm/helpers.native.js +9 -0
- package/dist/esm/helpers.native.js.map +1 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/index.mjs +12 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/index.native.js +12 -0
- package/dist/esm/index.native.js.map +1 -0
- package/dist/esm/nativeSheet.mjs +63 -0
- package/dist/esm/nativeSheet.mjs.map +1 -0
- package/dist/esm/nativeSheet.native.js +74 -0
- package/dist/esm/nativeSheet.native.js.map +1 -0
- package/dist/esm/setupGestureHandler.mjs +22 -0
- package/dist/esm/setupGestureHandler.mjs.map +1 -0
- package/dist/esm/setupGestureHandler.native.js +23 -0
- package/dist/esm/setupGestureHandler.native.js.map +1 -0
- package/dist/esm/types.mjs +2 -0
- package/dist/esm/types.mjs.map +1 -0
- package/dist/esm/types.native.js +2 -0
- package/dist/esm/types.native.js.map +1 -0
- package/dist/esm/useGestureHandlerPan.mjs +113 -0
- package/dist/esm/useGestureHandlerPan.mjs.map +1 -0
- package/dist/esm/useGestureHandlerPan.native.js +119 -0
- package/dist/esm/useGestureHandlerPan.native.js.map +1 -0
- package/dist/esm/useKeyboardControllerSheet.mjs +15 -0
- package/dist/esm/useKeyboardControllerSheet.mjs.map +1 -0
- package/dist/esm/useKeyboardControllerSheet.native.js +88 -0
- package/dist/esm/useKeyboardControllerSheet.native.js.map +1 -0
- package/dist/esm/useSheet.mjs +4 -0
- package/dist/esm/useSheet.mjs.map +1 -0
- package/dist/esm/useSheet.native.js +6 -0
- package/dist/esm/useSheet.native.js.map +1 -0
- package/dist/esm/useSheetController.mjs +15 -0
- package/dist/esm/useSheetController.mjs.map +1 -0
- package/dist/esm/useSheetController.native.js +15 -0
- package/dist/esm/useSheetController.native.js.map +1 -0
- package/dist/esm/useSheetOffscreenSize.mjs +28 -0
- package/dist/esm/useSheetOffscreenSize.mjs.map +1 -0
- package/dist/esm/useSheetOffscreenSize.native.js +35 -0
- package/dist/esm/useSheetOffscreenSize.native.js.map +1 -0
- package/dist/esm/useSheetOpenState.mjs +26 -0
- package/dist/esm/useSheetOpenState.mjs.map +1 -0
- package/dist/esm/useSheetOpenState.native.js +30 -0
- package/dist/esm/useSheetOpenState.native.js.map +1 -0
- package/dist/esm/useSheetProviderProps.mjs +99 -0
- package/dist/esm/useSheetProviderProps.mjs.map +1 -0
- package/dist/esm/useSheetProviderProps.native.js +116 -0
- package/dist/esm/useSheetProviderProps.native.js.map +1 -0
- package/dist/esm/useSheetScrollViewGestures.mjs +100 -0
- package/dist/esm/useSheetScrollViewGestures.mjs.map +1 -0
- package/dist/esm/useSheetScrollViewGestures.native.js +84 -0
- package/dist/esm/useSheetScrollViewGestures.native.js.map +1 -0
- package/dist/jsx/GestureDetectorWrapper.mjs +25 -0
- package/dist/jsx/GestureDetectorWrapper.mjs.map +1 -0
- package/dist/jsx/GestureDetectorWrapper.native.js +53 -0
- package/dist/jsx/GestureDetectorWrapper.native.js.map +1 -0
- package/dist/jsx/GestureSheetContext.mjs +28 -0
- package/dist/jsx/GestureSheetContext.mjs.map +1 -0
- package/dist/jsx/GestureSheetContext.native.js +56 -0
- package/dist/jsx/GestureSheetContext.native.js.map +1 -0
- package/dist/jsx/Sheet.mjs +89 -0
- package/dist/jsx/Sheet.mjs.map +1 -0
- package/dist/jsx/Sheet.native.js +120 -0
- package/dist/jsx/Sheet.native.js.map +1 -0
- package/dist/jsx/SheetContext.mjs +6 -0
- package/dist/jsx/SheetContext.mjs.map +1 -0
- package/dist/jsx/SheetContext.native.js +35 -0
- package/dist/jsx/SheetContext.native.js.map +1 -0
- package/dist/jsx/SheetController.mjs +31 -0
- package/dist/jsx/SheetController.mjs.map +1 -0
- package/dist/jsx/SheetController.native.js +71 -0
- package/dist/jsx/SheetController.native.js.map +1 -0
- package/dist/jsx/SheetImplementationCustom.mjs +437 -0
- package/dist/jsx/SheetImplementationCustom.mjs.map +1 -0
- package/dist/jsx/SheetImplementationCustom.native.js +524 -0
- package/dist/jsx/SheetImplementationCustom.native.js.map +1 -0
- package/dist/jsx/SheetScrollView.mjs +146 -0
- package/dist/jsx/SheetScrollView.mjs.map +1 -0
- package/dist/jsx/SheetScrollView.native.js +197 -0
- package/dist/jsx/SheetScrollView.native.js.map +1 -0
- package/dist/jsx/constants.mjs +6 -0
- package/dist/jsx/constants.mjs.map +1 -0
- package/dist/jsx/constants.native.js +35 -0
- package/dist/jsx/constants.native.js.map +1 -0
- package/dist/jsx/contexts.mjs +7 -0
- package/dist/jsx/contexts.mjs.map +1 -0
- package/dist/jsx/contexts.native.js +45 -0
- package/dist/jsx/contexts.native.js.map +1 -0
- package/dist/jsx/controller.mjs +4 -0
- package/dist/jsx/controller.mjs.map +1 -0
- package/dist/jsx/controller.native.js +32 -0
- package/dist/jsx/controller.native.js.map +1 -0
- package/dist/jsx/createSheet.mjs +168 -0
- package/dist/jsx/createSheet.mjs.map +1 -0
- package/dist/jsx/createSheet.native.js +208 -0
- package/dist/jsx/createSheet.native.js.map +1 -0
- package/dist/jsx/gestureState.mjs +13 -0
- package/dist/jsx/gestureState.mjs.map +1 -0
- package/dist/jsx/gestureState.native.js +42 -0
- package/dist/jsx/gestureState.native.js.map +1 -0
- package/dist/jsx/helpers.mjs +8 -0
- package/dist/jsx/helpers.mjs.map +1 -0
- package/dist/jsx/helpers.native.js +35 -0
- package/dist/jsx/helpers.native.js.map +1 -0
- package/dist/jsx/index.js +12 -0
- package/dist/jsx/index.js.map +1 -0
- package/dist/jsx/index.mjs +12 -0
- package/dist/jsx/index.mjs.map +1 -0
- package/dist/jsx/index.native.js +31 -0
- package/dist/jsx/index.native.js.map +1 -0
- package/dist/jsx/nativeSheet.mjs +63 -0
- package/dist/jsx/nativeSheet.mjs.map +1 -0
- package/dist/jsx/nativeSheet.native.js +101 -0
- package/dist/jsx/nativeSheet.native.js.map +1 -0
- package/dist/jsx/setupGestureHandler.mjs +22 -0
- package/dist/jsx/setupGestureHandler.mjs.map +1 -0
- package/dist/jsx/setupGestureHandler.native.js +50 -0
- package/dist/jsx/setupGestureHandler.native.js.map +1 -0
- package/dist/jsx/types.mjs +2 -0
- package/dist/jsx/types.mjs.map +1 -0
- package/dist/jsx/types.native.js +19 -0
- package/dist/jsx/types.native.js.map +1 -0
- package/dist/jsx/useGestureHandlerPan.mjs +113 -0
- package/dist/jsx/useGestureHandlerPan.mjs.map +1 -0
- package/dist/jsx/useGestureHandlerPan.native.js +145 -0
- package/dist/jsx/useGestureHandlerPan.native.js.map +1 -0
- package/dist/jsx/useKeyboardControllerSheet.mjs +15 -0
- package/dist/jsx/useKeyboardControllerSheet.mjs.map +1 -0
- package/dist/jsx/useKeyboardControllerSheet.native.js +114 -0
- package/dist/jsx/useKeyboardControllerSheet.native.js.map +1 -0
- package/dist/jsx/useSheet.mjs +4 -0
- package/dist/jsx/useSheet.mjs.map +1 -0
- package/dist/jsx/useSheet.native.js +32 -0
- package/dist/jsx/useSheet.native.js.map +1 -0
- package/dist/jsx/useSheetController.mjs +15 -0
- package/dist/jsx/useSheetController.mjs.map +1 -0
- package/dist/jsx/useSheetController.native.js +53 -0
- package/dist/jsx/useSheetController.native.js.map +1 -0
- package/dist/jsx/useSheetOffscreenSize.mjs +28 -0
- package/dist/jsx/useSheetOffscreenSize.mjs.map +1 -0
- package/dist/jsx/useSheetOffscreenSize.native.js +61 -0
- package/dist/jsx/useSheetOffscreenSize.native.js.map +1 -0
- package/dist/jsx/useSheetOpenState.mjs +26 -0
- package/dist/jsx/useSheetOpenState.mjs.map +1 -0
- package/dist/jsx/useSheetOpenState.native.js +56 -0
- package/dist/jsx/useSheetOpenState.native.js.map +1 -0
- package/dist/jsx/useSheetProviderProps.mjs +99 -0
- package/dist/jsx/useSheetProviderProps.mjs.map +1 -0
- package/dist/jsx/useSheetProviderProps.native.js +153 -0
- package/dist/jsx/useSheetProviderProps.native.js.map +1 -0
- package/dist/jsx/useSheetScrollViewGestures.mjs +100 -0
- package/dist/jsx/useSheetScrollViewGestures.mjs.map +1 -0
- package/dist/jsx/useSheetScrollViewGestures.native.js +110 -0
- package/dist/jsx/useSheetScrollViewGestures.native.js.map +1 -0
- package/next.md +78 -0
- package/package.json +96 -0
- package/setup-gesture-handler/index.cjs +2 -0
- package/setup-gesture-handler/index.js +2 -0
- package/setup-gesture-handler/index.native.cjs +2 -0
- package/setup-gesture-handler/index.native.js +2 -0
- package/setup-gesture-handler.cjs +1 -0
- package/src/GestureDetectorWrapper.tsx +41 -0
- package/src/GestureSheetContext.tsx +62 -0
- package/src/Sheet.tsx +114 -0
- package/src/SheetContext.tsx +11 -0
- package/src/SheetController.tsx +44 -0
- package/src/SheetImplementationCustom.tsx +868 -0
- package/src/SheetScrollView.tsx +195 -0
- package/src/constants.tsx +5 -0
- package/src/contexts.ts +9 -0
- package/src/controller.ts +9 -0
- package/src/createSheet.tsx +296 -0
- package/src/gestureState.ts +24 -0
- package/src/helpers.tsx +31 -0
- package/src/index.ts +11 -0
- package/src/nativeSheet.tsx +89 -0
- package/src/setupGestureHandler.ts +34 -0
- package/src/types.tsx +181 -0
- package/src/useGestureHandlerPan.tsx +364 -0
- package/src/useKeyboardControllerSheet.native.ts +136 -0
- package/src/useKeyboardControllerSheet.ts +26 -0
- package/src/useSheet.tsx +3 -0
- package/src/useSheetController.tsx +27 -0
- package/src/useSheetOffscreenSize.tsx +49 -0
- package/src/useSheetOpenState.tsx +33 -0
- package/src/useSheetProviderProps.tsx +223 -0
- package/src/useSheetScrollViewGestures.native.ts +163 -0
- package/src/useSheetScrollViewGestures.ts +194 -0
- package/tsconfig.json +56 -0
- package/types/GestureDetectorWrapper.d.ts +14 -0
- package/types/GestureSheetContext.d.ts +36 -0
- package/types/Sheet.d.ts +183 -0
- package/types/SheetContext.d.ts +43 -0
- package/types/SheetController.d.ts +6 -0
- package/types/SheetImplementationCustom.d.ts +36 -0
- package/types/SheetScrollView.d.ts +40 -0
- package/types/constants.d.ts +5 -0
- package/types/contexts.d.ts +6 -0
- package/types/controller.d.ts +3 -0
- package/types/createSheet.d.ts +194 -0
- package/types/gestureState.d.ts +11 -0
- package/types/helpers.d.ts +2 -0
- package/types/index.d.ts +12 -0
- package/types/nativeSheet.d.ts +10 -0
- package/types/setupGestureHandler.d.ts +11 -0
- package/types/types.d.ts +147 -0
- package/types/useGestureHandlerPan.d.ts +44 -0
- package/types/useKeyboardControllerSheet.d.ts +7 -0
- package/types/useKeyboardControllerSheet.native.d.ts +13 -0
- package/types/useSheet.d.ts +2 -0
- package/types/useSheetController.d.ts +17 -0
- package/types/useSheetOffscreenSize.d.ts +3 -0
- package/types/useSheetOpenState.d.ts +9 -0
- package/types/useSheetProviderProps.d.ts +36 -0
- package/types/useSheetScrollViewGestures.d.ts +12 -0
- package/types/useSheetScrollViewGestures.native.d.ts +21 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Legacy setup - prefer `import '@hanzogui/native/setup-gesture-handler'` instead.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { getGestureHandler } from '@hanzogui/native'
|
|
6
|
+
|
|
7
|
+
export function isGestureHandlerEnabled(): boolean {
|
|
8
|
+
return getGestureHandler().isEnabled
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface SetupGestureHandlerConfig {
|
|
12
|
+
Gesture: any
|
|
13
|
+
GestureDetector: any
|
|
14
|
+
ScrollView?: any
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function setupGestureHandler(config: SetupGestureHandlerConfig): void {
|
|
18
|
+
const g = globalThis as any
|
|
19
|
+
if (g.__gui_sheet_gesture_handler_setup) {
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
g.__gui_sheet_gesture_handler_setup = true
|
|
23
|
+
|
|
24
|
+
const { Gesture, GestureDetector, ScrollView } = config
|
|
25
|
+
|
|
26
|
+
if (Gesture && GestureDetector) {
|
|
27
|
+
getGestureHandler().set({
|
|
28
|
+
enabled: true,
|
|
29
|
+
Gesture,
|
|
30
|
+
GestureDetector,
|
|
31
|
+
ScrollView: ScrollView || null,
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
}
|
package/src/types.tsx
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import type { AnimatedNumberStrategy, TransitionProp } from '@hanzogui/core'
|
|
2
|
+
import type { ScopedProps } from '@hanzogui/create-context'
|
|
3
|
+
import type { PortalProps } from '@hanzogui/portal'
|
|
4
|
+
import type { RemoveScroll } from '@hanzogui/remove-scroll'
|
|
5
|
+
import type { ReactNode } from 'react'
|
|
6
|
+
import type React from 'react'
|
|
7
|
+
|
|
8
|
+
export type SheetProps = ScopedProps<
|
|
9
|
+
{
|
|
10
|
+
open?: boolean
|
|
11
|
+
defaultOpen?: boolean
|
|
12
|
+
onOpenChange?: OpenChangeHandler
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Control the index of the position in the `snapPoints` array
|
|
16
|
+
*/
|
|
17
|
+
position?: number
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Initial position from the `snapPoints` array
|
|
21
|
+
*/
|
|
22
|
+
defaultPosition?: number
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Array of pixels or percents the Sheet will attempt to move to when dragged.
|
|
26
|
+
* The first is the topmost and default when first opened via open prop.
|
|
27
|
+
*/
|
|
28
|
+
snapPoints?: (string | number)[]
|
|
29
|
+
|
|
30
|
+
snapPointsMode?: SnapPointsMode
|
|
31
|
+
onPositionChange?: PositionChangeHandler
|
|
32
|
+
children?: ReactNode
|
|
33
|
+
dismissOnOverlayPress?: boolean
|
|
34
|
+
dismissOnSnapToBottom?: boolean
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Disables the RemoveScroll behavior that prevents body scrolling while sheet is open.
|
|
38
|
+
* By default, RemoveScroll is enabled when the sheet is open and modal.
|
|
39
|
+
*/
|
|
40
|
+
disableRemoveScroll?: boolean
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @deprecated Use `disableRemoveScroll` instead. This prop will be removed in a future version.
|
|
44
|
+
* Note: `disableRemoveScroll={true}` is equivalent to `forceRemoveScrollEnabled={false}`
|
|
45
|
+
*/
|
|
46
|
+
forceRemoveScrollEnabled?: boolean
|
|
47
|
+
|
|
48
|
+
transitionConfig?: AnimatedNumberStrategy
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* By default Sheet will prefer the open prop over a parent component that is
|
|
52
|
+
* controlling it via Adapt. In general if you want to Adapt to a sheet, you'd
|
|
53
|
+
* leave the open prop undefined. If you'd like to have the parent override the
|
|
54
|
+
* prop you've set manually on Sheet, set this to true.
|
|
55
|
+
*/
|
|
56
|
+
preferAdaptParentOpenState?: boolean
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* (experimental) Remove the children while hidden (to save some performance, but can cause issues with animations)
|
|
60
|
+
*/
|
|
61
|
+
unmountChildrenWhenHidden?: boolean
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Adapts the sheet to use native sheet on the given platform (if available)
|
|
65
|
+
*/
|
|
66
|
+
native?: 'ios'[] | boolean
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Pass if you're using the CSS animation driver
|
|
70
|
+
*/
|
|
71
|
+
transition?: TransitionProp
|
|
72
|
+
handleDisableScroll?: boolean
|
|
73
|
+
disableDrag?: boolean
|
|
74
|
+
modal?: boolean
|
|
75
|
+
zIndex?: number
|
|
76
|
+
portalProps?: PortalProps
|
|
77
|
+
/**
|
|
78
|
+
* Native-only flag that will make the sheet move up when the mobile keyboard opens so the focused input remains visible
|
|
79
|
+
*/
|
|
80
|
+
moveOnKeyboardChange?: boolean
|
|
81
|
+
containerComponent?: React.ComponentType<any>
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Called when the sheet open/close animation completes.
|
|
85
|
+
*/
|
|
86
|
+
onAnimationComplete?: (info: { open: boolean }) => void
|
|
87
|
+
},
|
|
88
|
+
'Sheet'
|
|
89
|
+
>
|
|
90
|
+
|
|
91
|
+
export type PositionChangeHandler = (position: number) => void
|
|
92
|
+
|
|
93
|
+
type OpenChangeHandler =
|
|
94
|
+
| ((open: boolean) => void)
|
|
95
|
+
| React.Dispatch<React.SetStateAction<boolean>>
|
|
96
|
+
|
|
97
|
+
export type RemoveScrollProps = React.ComponentProps<typeof RemoveScroll>
|
|
98
|
+
|
|
99
|
+
export type SnapPointsMode = 'percent' | 'constant' | 'fit' | 'mixed'
|
|
100
|
+
|
|
101
|
+
export type SheetScopedProps<A> = ScopedProps<A, 'Sheet'>
|
|
102
|
+
|
|
103
|
+
export type ScrollBridge = {
|
|
104
|
+
enabled: boolean
|
|
105
|
+
y: number
|
|
106
|
+
paneY: number
|
|
107
|
+
paneMinY: number
|
|
108
|
+
scrollStartY: number
|
|
109
|
+
hasScrollableContent: boolean
|
|
110
|
+
drag: (dy: number) => void
|
|
111
|
+
release: (state: { dragAt: number; vy: number }) => void
|
|
112
|
+
scrollLock: boolean
|
|
113
|
+
isParentDragging: boolean
|
|
114
|
+
onParentDragging: (props: (val: boolean) => void) => () => void
|
|
115
|
+
setParentDragging: (val: boolean) => void
|
|
116
|
+
onFinishAnimate?: () => void
|
|
117
|
+
// gesture handler state for RNGH integration
|
|
118
|
+
blockPan?: boolean
|
|
119
|
+
initialPosition?: number
|
|
120
|
+
isScrollablePositionLocked?: boolean
|
|
121
|
+
// control scroll enabled state for RNGH coordination
|
|
122
|
+
// lockTo parameter: when disabling, lock scroll to this position (undefined = current position)
|
|
123
|
+
setScrollEnabled?: (enabled: boolean, lockTo?: number) => void
|
|
124
|
+
// track touch position for direction detection in RNGH
|
|
125
|
+
_lastTouchY?: number
|
|
126
|
+
// scroll lock position for forcing scroll back when pan handles
|
|
127
|
+
scrollLockY?: number
|
|
128
|
+
// force scroll to position (compensates for async setNativeProps)
|
|
129
|
+
forceScrollTo?: (y: number) => void
|
|
130
|
+
// whether sheet is at top position (for scroll enable/disable)
|
|
131
|
+
isAtTop?: boolean
|
|
132
|
+
// snap sheet to a specific position (for handoff UP)
|
|
133
|
+
snapToPosition?: (positionIndex: number) => void
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// keyboard controller sheet types
|
|
137
|
+
|
|
138
|
+
export interface KeyboardControllerSheetOptions {
|
|
139
|
+
/**
|
|
140
|
+
* Whether keyboard handling is enabled.
|
|
141
|
+
* When false, the hook is a no-op.
|
|
142
|
+
*/
|
|
143
|
+
enabled: boolean
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface KeyboardControllerSheetResult {
|
|
147
|
+
/**
|
|
148
|
+
* Whether keyboard-controller is available and enabled.
|
|
149
|
+
*/
|
|
150
|
+
keyboardControllerEnabled: boolean
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Current keyboard height (0 when hidden).
|
|
154
|
+
* On web or when keyboard-controller is not available, always 0.
|
|
155
|
+
*/
|
|
156
|
+
keyboardHeight: number
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Whether the keyboard is currently visible.
|
|
160
|
+
*/
|
|
161
|
+
isKeyboardVisible: boolean
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Dismiss the keyboard programmatically.
|
|
165
|
+
* Called when sheet closes to dismiss the keyboard.
|
|
166
|
+
*/
|
|
167
|
+
dismissKeyboard: () => void
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Ref to pause keyboard hide state updates (action-sheet pattern).
|
|
171
|
+
* When true, keyboard hide events are ignored — keeps isKeyboardVisible=true
|
|
172
|
+
* and keyboardHeight at their last values during drag.
|
|
173
|
+
*/
|
|
174
|
+
pauseKeyboardHandler: React.RefObject<boolean>
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Flush any keyboard hide event that was suppressed while paused.
|
|
178
|
+
* Call after drag ends to reconcile actual keyboard state.
|
|
179
|
+
*/
|
|
180
|
+
flushPendingHide: () => void
|
|
181
|
+
}
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { useCallback, useMemo, useRef, type RefObject } from 'react'
|
|
2
|
+
import { getGestureHandlerState, isGestureHandlerEnabled } from './gestureState'
|
|
3
|
+
import type { ScrollBridge } from './types'
|
|
4
|
+
|
|
5
|
+
// threshold in pixels for considering sheet "at top" position
|
|
6
|
+
// allows for small measurement variations
|
|
7
|
+
const AT_TOP_THRESHOLD = 5
|
|
8
|
+
|
|
9
|
+
interface GesturePanConfig {
|
|
10
|
+
positions: number[]
|
|
11
|
+
frameSize: number
|
|
12
|
+
setPosition: (pos: number) => void
|
|
13
|
+
animateTo: (pos: number, animationOverride?: any) => void
|
|
14
|
+
stopSpring: () => void
|
|
15
|
+
scrollBridge: ScrollBridge
|
|
16
|
+
setIsDragging: (val: boolean) => void
|
|
17
|
+
getCurrentPosition: () => number
|
|
18
|
+
resisted: (val: number, minY: number) => number
|
|
19
|
+
disableDrag?: boolean
|
|
20
|
+
isShowingInnerSheet?: boolean
|
|
21
|
+
// set the animated position directly (for smooth dragging)
|
|
22
|
+
setAnimatedPosition: (val: number) => void
|
|
23
|
+
// ref to scroll gesture for simultaneousWithExternalGesture
|
|
24
|
+
scrollGestureRef?: RefObject<any> | null
|
|
25
|
+
// ref to pause keyboard hide events during gesture (action-sheet pattern)
|
|
26
|
+
pauseKeyboardHandler?: RefObject<boolean>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface GesturePanResult {
|
|
30
|
+
panGesture: any | null
|
|
31
|
+
panGestureRef: RefObject<any>
|
|
32
|
+
gestureHandlerEnabled: boolean
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Hook that creates a Gesture.Pan() handler for use with react-native-gesture-handler.
|
|
37
|
+
* This provides native-quality gesture coordination between Sheet and ScrollView.
|
|
38
|
+
*
|
|
39
|
+
* Uses state-based decision pattern (like gorhom/bottom-sheet and react-native-actions-sheet):
|
|
40
|
+
* - Both pan and scroll gestures run simultaneously
|
|
41
|
+
* - In onChange, we decide whether to process pan or let scroll handle it
|
|
42
|
+
* - scrollBridge.setScrollEnabled toggles scroll on/off as needed
|
|
43
|
+
*
|
|
44
|
+
* Decision matrix:
|
|
45
|
+
* 1. Sheet not fully open + swiping up -> pan handles (disable scroll)
|
|
46
|
+
* 2. Sheet fully open + swiping up -> scroll handles (blockPan)
|
|
47
|
+
* 3. Sheet not fully open + swiping down -> pan handles (unless scrolled)
|
|
48
|
+
* 4. Sheet fully open + swiping down + scrollY=0 -> pan handles
|
|
49
|
+
* 5. Sheet fully open + swiping down + scrollY>0 -> scroll handles (blockPan)
|
|
50
|
+
*
|
|
51
|
+
* Returns null for the gesture if RNGH is not available or drag is disabled.
|
|
52
|
+
*/
|
|
53
|
+
export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult {
|
|
54
|
+
const {
|
|
55
|
+
positions,
|
|
56
|
+
frameSize,
|
|
57
|
+
setPosition,
|
|
58
|
+
animateTo,
|
|
59
|
+
stopSpring,
|
|
60
|
+
scrollBridge,
|
|
61
|
+
setIsDragging,
|
|
62
|
+
getCurrentPosition,
|
|
63
|
+
resisted,
|
|
64
|
+
disableDrag,
|
|
65
|
+
isShowingInnerSheet,
|
|
66
|
+
setAnimatedPosition,
|
|
67
|
+
scrollGestureRef,
|
|
68
|
+
} = config
|
|
69
|
+
|
|
70
|
+
const gestureHandlerEnabled = isGestureHandlerEnabled()
|
|
71
|
+
const panGestureRef = useRef<any>(null)
|
|
72
|
+
|
|
73
|
+
// use refs for values that need to persist across gesture lifecycle
|
|
74
|
+
// (useMemo closure variables get reset when gesture is recreated)
|
|
75
|
+
const gestureStateRef = useRef({
|
|
76
|
+
startY: 0,
|
|
77
|
+
// track last translation when pan was active (for position calculation after handoff)
|
|
78
|
+
lastPanTranslationY: 0,
|
|
79
|
+
// accumulated position offset from all pan movements
|
|
80
|
+
accumulatedOffset: 0,
|
|
81
|
+
// track previous translation for direction detection (like actions-sheet)
|
|
82
|
+
prevTranslationY: 0,
|
|
83
|
+
// track if scroll was engaged (scrollY > 0) at some point
|
|
84
|
+
scrollEngaged: false,
|
|
85
|
+
// positions frozen at gesture start — keyboard may dismiss during drag (input blur),
|
|
86
|
+
// causing positions to revert. Frozen positions ensure stable snap calculation.
|
|
87
|
+
frozenPositions: [] as number[],
|
|
88
|
+
frozenMinY: 0,
|
|
89
|
+
// whether pan gesture actually started (vs just a tap in onBegin)
|
|
90
|
+
panStarted: false,
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const onStart = useCallback(() => {
|
|
94
|
+
stopSpring()
|
|
95
|
+
}, [stopSpring])
|
|
96
|
+
|
|
97
|
+
const onEnd = useCallback(
|
|
98
|
+
(closestPoint: number, animationOverride?: any) => {
|
|
99
|
+
setIsDragging(false)
|
|
100
|
+
scrollBridge.setParentDragging(false)
|
|
101
|
+
// re-enable scroll when gesture ends
|
|
102
|
+
scrollBridge.setScrollEnabled?.(true)
|
|
103
|
+
setPosition(closestPoint)
|
|
104
|
+
animateTo(closestPoint, animationOverride)
|
|
105
|
+
},
|
|
106
|
+
[setIsDragging, scrollBridge, setPosition, animateTo]
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
const panGesture = useMemo(() => {
|
|
110
|
+
// don't create gesture if disabled or RNGH not available
|
|
111
|
+
if (!gestureHandlerEnabled || disableDrag || isShowingInnerSheet || !frameSize) {
|
|
112
|
+
return null
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const { Gesture } = getGestureHandlerState()
|
|
116
|
+
if (!Gesture) {
|
|
117
|
+
return null
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const minY = positions[0]
|
|
121
|
+
const gs = gestureStateRef.current // shorthand
|
|
122
|
+
|
|
123
|
+
// simultaneousHandlers pattern from react-native-actions-sheet
|
|
124
|
+
// both gestures run simultaneously, we use blockPan to decide who handles
|
|
125
|
+
// console.warn('[RNGH-Pan] CREATING gesture, minY:', minY, 'frameSize:', frameSize)
|
|
126
|
+
const gesture = Gesture.Pan()
|
|
127
|
+
.withRef(panGestureRef)
|
|
128
|
+
// NO manualActivation - let both gestures run via simultaneousHandlers
|
|
129
|
+
// activeOffsetY: activate pan when user moves 10px vertically (required on Android)
|
|
130
|
+
.activeOffsetY([-10, 10])
|
|
131
|
+
// failOffsetX: cancel pan if user moves 20px horizontally (horizontal scroll takes over)
|
|
132
|
+
.failOffsetX([-20, 20])
|
|
133
|
+
.shouldCancelWhenOutside(false)
|
|
134
|
+
.onBegin(() => {
|
|
135
|
+
// onBegin fires on ANY touch (including taps to focus inputs).
|
|
136
|
+
// We do NOT set isDragging here — that would block keyboard animation.
|
|
137
|
+
// Instead, isDragging is set in onStart (actual pan gesture recognized).
|
|
138
|
+
gs.panStarted = false
|
|
139
|
+
|
|
140
|
+
// lightweight: pause keyboard handler to suppress hide events during gesture.
|
|
141
|
+
// This prevents keyboard flicker if input blurs before onStart.
|
|
142
|
+
// If this is just a tap, onFinalize un-pauses without setting isDragging.
|
|
143
|
+
if (config.pauseKeyboardHandler) {
|
|
144
|
+
config.pauseKeyboardHandler.current = true
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// check position at gesture begin - before direction is known
|
|
148
|
+
const pos = getCurrentPosition()
|
|
149
|
+
const atTop = pos <= minY + AT_TOP_THRESHOLD
|
|
150
|
+
const currentScrollY = scrollBridge.y
|
|
151
|
+
// console.warn('[RNGH-Pan] onBegin', { pos, minY, atTop, currentScrollY })
|
|
152
|
+
gs.startY = pos
|
|
153
|
+
gs.lastPanTranslationY = 0
|
|
154
|
+
gs.accumulatedOffset = 0
|
|
155
|
+
gs.prevTranslationY = 0
|
|
156
|
+
gs.scrollEngaged = currentScrollY > 0 // track if scroll is already engaged
|
|
157
|
+
// freeze positions at gesture start so keyboard dismiss during drag
|
|
158
|
+
// doesn't change snap targets mid-gesture
|
|
159
|
+
gs.frozenPositions = [...positions]
|
|
160
|
+
gs.frozenMinY = minY
|
|
161
|
+
|
|
162
|
+
// if sheet not at top, DISABLE SCROLL immediately and lock to 0
|
|
163
|
+
// this prevents scroll from firing before pan takes over
|
|
164
|
+
if (!atTop) {
|
|
165
|
+
scrollBridge.setScrollEnabled?.(false, 0)
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
.onStart(() => {
|
|
169
|
+
// onStart fires only when pan gesture is recognized (finger moved enough).
|
|
170
|
+
// Safe to set isDragging here — this won't fire for taps to focus inputs.
|
|
171
|
+
gs.panStarted = true
|
|
172
|
+
setIsDragging(true)
|
|
173
|
+
|
|
174
|
+
// console.warn('[RNGH-Pan] onStart', { startY: gs.startY, minY })
|
|
175
|
+
scrollBridge.initialPosition = gs.startY
|
|
176
|
+
onStart()
|
|
177
|
+
})
|
|
178
|
+
.onChange((event: { translationY: number; velocityY: number }) => {
|
|
179
|
+
const { translationY } = event
|
|
180
|
+
|
|
181
|
+
// determine direction by comparing translations (like react-native-actions-sheet)
|
|
182
|
+
// this is more reliable than velocity which can be noisy during direction changes
|
|
183
|
+
const isSwipingDown = gs.prevTranslationY < translationY
|
|
184
|
+
const deltaY = translationY - gs.prevTranslationY
|
|
185
|
+
gs.prevTranslationY = translationY
|
|
186
|
+
|
|
187
|
+
const scrollY = scrollBridge.y
|
|
188
|
+
// track if scroll has been engaged at some point (needed for handoff detection)
|
|
189
|
+
if (scrollY > 0) {
|
|
190
|
+
gs.scrollEngaged = true
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// calculate current sheet position based on accumulated offset
|
|
194
|
+
const currentPos = gs.startY + gs.accumulatedOffset
|
|
195
|
+
const isCurrentlyAtTop = currentPos <= minY + AT_TOP_THRESHOLD
|
|
196
|
+
const nodeIsScrolling = scrollY > 0
|
|
197
|
+
|
|
198
|
+
// console.warn('[RNGH-Pan] onChange', { translationY: translationY.toFixed(1), deltaY: deltaY.toFixed(1), currentPos: currentPos.toFixed(1), minY, isCurrentlyAtTop, isSwipingDown, scrollY, scrollEngaged: gs.scrollEngaged })
|
|
199
|
+
|
|
200
|
+
// decision matrix (from react-native-actions-sheet pattern)
|
|
201
|
+
// each frame, decide who handles the movement based on current state
|
|
202
|
+
//
|
|
203
|
+
// Key insight: we track accumulated offset separately from translation
|
|
204
|
+
// This allows seamless handoffs between pan and scroll
|
|
205
|
+
let panHandles = false
|
|
206
|
+
|
|
207
|
+
// BUG #1 FIX: Check if scroll content is actually scrollable
|
|
208
|
+
// If content doesn't fill the ScrollView, gestures should pass through to sheet
|
|
209
|
+
const hasScrollableContent = scrollBridge.hasScrollableContent !== false
|
|
210
|
+
|
|
211
|
+
if (!isCurrentlyAtTop) {
|
|
212
|
+
// sheet not at top position
|
|
213
|
+
if (isSwipingDown) {
|
|
214
|
+
// swiping down while sheet not at top
|
|
215
|
+
// BUG #1 FIX: if content not scrollable, pan always handles
|
|
216
|
+
// only scroll if scrollY > 0 AND content is scrollable, otherwise pan handles
|
|
217
|
+
panHandles = !nodeIsScrolling || !hasScrollableContent
|
|
218
|
+
} else {
|
|
219
|
+
// swiping up while sheet not at top -> pan drags sheet up
|
|
220
|
+
panHandles = true
|
|
221
|
+
}
|
|
222
|
+
} else {
|
|
223
|
+
// sheet is at top position
|
|
224
|
+
if (isSwipingDown) {
|
|
225
|
+
// swiping down at top
|
|
226
|
+
if (nodeIsScrolling && hasScrollableContent) {
|
|
227
|
+
// scroll > 0 and content scrollable, let scroll handle (scroll back towards 0)
|
|
228
|
+
panHandles = false
|
|
229
|
+
} else if (gs.scrollEngaged && hasScrollableContent) {
|
|
230
|
+
// scroll WAS > 0 but now is 0 -> handoff from scroll to pan
|
|
231
|
+
// pan takes over to drag sheet down
|
|
232
|
+
// console.warn('[RNGH-Pan] *** HANDOFF FROM SCROLL TO PAN ***')
|
|
233
|
+
panHandles = true
|
|
234
|
+
} else {
|
|
235
|
+
// scroll never engaged OR content not scrollable, just drag sheet down
|
|
236
|
+
panHandles = true
|
|
237
|
+
}
|
|
238
|
+
} else {
|
|
239
|
+
// swiping up at top
|
|
240
|
+
// if there's scrollable content, let scroll handle so user can scroll into content
|
|
241
|
+
// resistance only applies when there's NO scrollable content
|
|
242
|
+
if (hasScrollableContent) {
|
|
243
|
+
// content is scrollable - let scroll handle (user wants to scroll down into content)
|
|
244
|
+
panHandles = false
|
|
245
|
+
} else {
|
|
246
|
+
// no scrollable content -> pan handles for resistance effect
|
|
247
|
+
panHandles = true
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// console.warn('[RNGH-Pan] decision', { panHandles, isCurrentlyAtTop, isSwipingDown, nodeIsScrolling, scrollEngaged: gs.scrollEngaged, hasScrollableContent, currentPos: currentPos.toFixed(1), minY })
|
|
253
|
+
|
|
254
|
+
if (panHandles) {
|
|
255
|
+
// pan handles - disable scroll and move sheet
|
|
256
|
+
// when swiping down at top after scroll was engaged: lock at current scroll position
|
|
257
|
+
// (handoff from scroll to pan — preserve scroll offset)
|
|
258
|
+
// otherwise: always lock scroll to 0 (prevents scroll from firing during sheet drag)
|
|
259
|
+
const lockTo =
|
|
260
|
+
isCurrentlyAtTop && isSwipingDown && gs.scrollEngaged ? undefined : 0
|
|
261
|
+
scrollBridge.setScrollEnabled?.(false, lockTo)
|
|
262
|
+
|
|
263
|
+
// accumulate the delta for position calculation
|
|
264
|
+
gs.accumulatedOffset += deltaY
|
|
265
|
+
const newPosition = resisted(gs.startY + gs.accumulatedOffset, minY)
|
|
266
|
+
|
|
267
|
+
// update position
|
|
268
|
+
scrollBridge.paneY = newPosition
|
|
269
|
+
setAnimatedPosition(newPosition)
|
|
270
|
+
scrollBridge.setParentDragging(newPosition > minY)
|
|
271
|
+
} else {
|
|
272
|
+
// scroll handles - enable scroll so it can move freely
|
|
273
|
+
scrollBridge.setScrollEnabled?.(true)
|
|
274
|
+
// don't accumulate offset when scroll is handling
|
|
275
|
+
}
|
|
276
|
+
})
|
|
277
|
+
.onEnd((event: { velocityY: number }) => {
|
|
278
|
+
const { velocityY } = event
|
|
279
|
+
const currentPos = gs.startY + gs.accumulatedOffset
|
|
280
|
+
|
|
281
|
+
// console.warn('[RNGH-Pan] onEnd', { velocityY, currentPos, accumulatedOffset: gs.accumulatedOffset, scrollY: scrollBridge.y })
|
|
282
|
+
|
|
283
|
+
// clear scroll lock
|
|
284
|
+
scrollBridge.scrollLockY = undefined
|
|
285
|
+
|
|
286
|
+
// use frozen positions from gesture start — keyboard may have dismissed
|
|
287
|
+
// during drag (input blur), reverting activePositions. Frozen positions
|
|
288
|
+
// ensure the snap index reflects the user's intent at drag start.
|
|
289
|
+
// The onEnd callback's animateTo uses latest activePositions for the
|
|
290
|
+
// actual animation target, so the sheet ends up at the right place.
|
|
291
|
+
const snapPositions =
|
|
292
|
+
gs.frozenPositions.length > 0 ? gs.frozenPositions : positions
|
|
293
|
+
const snapMinY = gs.frozenPositions.length > 0 ? gs.frozenMinY : minY
|
|
294
|
+
|
|
295
|
+
// if sheet is at top and scroll is engaged, just stay at top
|
|
296
|
+
if (currentPos <= snapMinY + AT_TOP_THRESHOLD && scrollBridge.y > 0) {
|
|
297
|
+
onEnd(0)
|
|
298
|
+
return
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// snap calculation using frozen positions
|
|
302
|
+
const velocity = velocityY / 1000
|
|
303
|
+
const projectedEnd = currentPos + frameSize * velocity * 0.2
|
|
304
|
+
|
|
305
|
+
let closestPoint = 0
|
|
306
|
+
let minDist = Number.POSITIVE_INFINITY
|
|
307
|
+
|
|
308
|
+
for (let i = 0; i < snapPositions.length; i++) {
|
|
309
|
+
const pos = snapPositions[i]
|
|
310
|
+
const dist = Math.abs(projectedEnd - pos)
|
|
311
|
+
if (dist < minDist) {
|
|
312
|
+
minDist = dist
|
|
313
|
+
closestPoint = i
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
onEnd(closestPoint)
|
|
318
|
+
})
|
|
319
|
+
.onFinalize(() => {
|
|
320
|
+
// console.warn('[RNGH-Pan] onFinalize', { panStarted: gs.panStarted })
|
|
321
|
+
// clear scroll lock on finalize too (safety)
|
|
322
|
+
scrollBridge.scrollLockY = undefined
|
|
323
|
+
if (gs.panStarted) {
|
|
324
|
+
// real pan gesture — reset isDragging (also un-pauses keyboard handler + flushes)
|
|
325
|
+
setIsDragging(false)
|
|
326
|
+
} else {
|
|
327
|
+
// just a tap (onBegin fired but onStart never did) — un-pause keyboard handler
|
|
328
|
+
// without setting isDragging (which would block keyboard animation effect)
|
|
329
|
+
if (config.pauseKeyboardHandler) {
|
|
330
|
+
config.pauseKeyboardHandler.current = false
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
})
|
|
334
|
+
.runOnJS(true)
|
|
335
|
+
|
|
336
|
+
// if we have a scroll gesture ref, make pan simultaneous with it
|
|
337
|
+
// this allows both gestures to run and we decide in onChange who handles it
|
|
338
|
+
if (scrollGestureRef?.current) {
|
|
339
|
+
// console.warn('[RNGH-Pan] adding simultaneousWithExternalGesture for scroll')
|
|
340
|
+
return gesture.simultaneousWithExternalGesture(scrollGestureRef.current)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return gesture
|
|
344
|
+
}, [
|
|
345
|
+
gestureHandlerEnabled,
|
|
346
|
+
disableDrag,
|
|
347
|
+
isShowingInnerSheet,
|
|
348
|
+
frameSize,
|
|
349
|
+
positions,
|
|
350
|
+
scrollBridge,
|
|
351
|
+
getCurrentPosition,
|
|
352
|
+
resisted,
|
|
353
|
+
onStart,
|
|
354
|
+
onEnd,
|
|
355
|
+
setIsDragging,
|
|
356
|
+
setAnimatedPosition,
|
|
357
|
+
])
|
|
358
|
+
|
|
359
|
+
return {
|
|
360
|
+
panGesture,
|
|
361
|
+
panGestureRef,
|
|
362
|
+
gestureHandlerEnabled,
|
|
363
|
+
}
|
|
364
|
+
}
|