@tamagui/sheet 2.0.0-rc.9 → 2.1.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/.turbo/turbo-build.log +2 -0
- package/controller/index.cjs +2 -1
- 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 +27 -21
- package/dist/cjs/GestureDetectorWrapper.native.js +33 -28
- package/dist/cjs/GestureDetectorWrapper.native.js.map +1 -1
- package/dist/cjs/GestureSheetContext.cjs +14 -12
- package/dist/cjs/GestureSheetContext.native.js +29 -27
- package/dist/cjs/GestureSheetContext.native.js.map +1 -1
- package/dist/cjs/Sheet.cjs +88 -86
- package/dist/cjs/Sheet.native.js +88 -86
- package/dist/cjs/Sheet.native.js.map +1 -1
- package/dist/cjs/SheetContext.cjs +16 -14
- package/dist/cjs/SheetContext.native.js +16 -14
- package/dist/cjs/SheetContext.native.js.map +1 -1
- package/dist/cjs/SheetController.cjs +40 -32
- package/dist/cjs/SheetController.native.js +62 -54
- package/dist/cjs/SheetController.native.js.map +1 -1
- package/dist/cjs/SheetImplementationCustom.cjs +617 -429
- package/dist/cjs/SheetImplementationCustom.native.js +647 -474
- package/dist/cjs/SheetImplementationCustom.native.js.map +1 -1
- package/dist/cjs/SheetScrollView.cjs +198 -135
- package/dist/cjs/SheetScrollView.native.js +216 -163
- package/dist/cjs/SheetScrollView.native.js.map +1 -1
- package/dist/cjs/constants.cjs +16 -14
- package/dist/cjs/constants.native.js +16 -14
- package/dist/cjs/constants.native.js.map +1 -1
- package/dist/cjs/contexts.cjs +27 -25
- package/dist/cjs/contexts.native.js +29 -27
- package/dist/cjs/contexts.native.js.map +1 -1
- package/dist/cjs/controller.cjs +14 -12
- package/dist/cjs/controller.native.js +14 -12
- package/dist/cjs/controller.native.js.map +1 -1
- package/dist/cjs/createSheet.cjs +159 -160
- package/dist/cjs/createSheet.native.js +172 -180
- package/dist/cjs/createSheet.native.js.map +1 -1
- package/dist/cjs/gestureState.cjs +12 -10
- package/dist/cjs/gestureState.native.js +12 -10
- package/dist/cjs/gestureState.native.js.map +1 -1
- package/dist/cjs/helpers.cjs +17 -13
- package/dist/cjs/helpers.native.js +17 -13
- package/dist/cjs/helpers.native.js.map +1 -1
- package/dist/cjs/index.cjs +7 -5
- package/dist/cjs/index.native.js +7 -5
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/keyboardAvoidance.cjs +42 -0
- package/dist/cjs/keyboardAvoidance.native.js +46 -0
- package/dist/cjs/keyboardAvoidance.native.js.map +1 -0
- package/dist/cjs/nativeSheet.cjs +68 -55
- package/dist/cjs/nativeSheet.native.js +77 -68
- package/dist/cjs/nativeSheet.native.js.map +1 -1
- package/dist/cjs/setupGestureHandler.cjs +24 -18
- package/dist/cjs/setupGestureHandler.native.js +24 -19
- package/dist/cjs/setupGestureHandler.native.js.map +1 -1
- package/dist/cjs/types.cjs +7 -5
- package/dist/cjs/types.native.js +7 -5
- package/dist/cjs/types.native.js.map +1 -1
- package/dist/cjs/useGestureHandlerPan.cjs +181 -111
- package/dist/cjs/useGestureHandlerPan.native.js +183 -115
- package/dist/cjs/useGestureHandlerPan.native.js.map +1 -1
- package/dist/cjs/useKeyboardControllerSheet.cjs +76 -18
- package/dist/cjs/useKeyboardControllerSheet.native.js +100 -82
- package/dist/cjs/useKeyboardControllerSheet.native.js.map +1 -1
- package/dist/cjs/useSheet.cjs +12 -10
- package/dist/cjs/useSheet.native.js +16 -14
- package/dist/cjs/useSheet.native.js.map +1 -1
- package/dist/cjs/useSheetController.cjs +35 -33
- package/dist/cjs/useSheetController.native.js +37 -35
- package/dist/cjs/useSheetController.native.js.map +1 -1
- package/dist/cjs/useSheetOffscreenSize.cjs +35 -23
- package/dist/cjs/useSheetOffscreenSize.native.js +36 -27
- package/dist/cjs/useSheetOffscreenSize.native.js.map +1 -1
- package/dist/cjs/useSheetOpenState.cjs +28 -25
- package/dist/cjs/useSheetOpenState.native.js +39 -37
- package/dist/cjs/useSheetOpenState.native.js.map +1 -1
- package/dist/cjs/useSheetProviderProps.cjs +129 -81
- package/dist/cjs/useSheetProviderProps.native.js +165 -122
- package/dist/cjs/useSheetProviderProps.native.js.map +1 -1
- package/dist/cjs/useSheetScrollViewGestures.cjs +129 -81
- package/dist/cjs/useSheetScrollViewGestures.native.js +128 -79
- package/dist/cjs/useSheetScrollViewGestures.native.js.map +1 -1
- package/dist/cjs/webViewport.cjs +50 -0
- package/dist/cjs/webViewport.native.js +54 -0
- package/dist/cjs/webViewport.native.js.map +1 -0
- package/dist/esm/GestureDetectorWrapper.mjs +12 -8
- package/dist/esm/GestureDetectorWrapper.mjs.map +1 -1
- package/dist/esm/GestureDetectorWrapper.native.js +18 -15
- package/dist/esm/GestureDetectorWrapper.native.js.map +1 -1
- package/dist/esm/GestureSheetContext.native.js +14 -14
- package/dist/esm/GestureSheetContext.native.js.map +1 -1
- package/dist/esm/Sheet.mjs +70 -70
- package/dist/esm/Sheet.mjs.map +1 -1
- package/dist/esm/Sheet.native.js +70 -70
- package/dist/esm/Sheet.native.js.map +1 -1
- package/dist/esm/SheetContext.mjs +2 -2
- package/dist/esm/SheetContext.mjs.map +1 -1
- package/dist/esm/SheetContext.native.js +2 -2
- package/dist/esm/SheetContext.native.js.map +1 -1
- package/dist/esm/SheetController.mjs +12 -6
- package/dist/esm/SheetController.mjs.map +1 -1
- package/dist/esm/SheetController.native.js +18 -12
- package/dist/esm/SheetController.native.js.map +1 -1
- package/dist/esm/SheetImplementationCustom.mjs +575 -389
- package/dist/esm/SheetImplementationCustom.mjs.map +1 -1
- package/dist/esm/SheetImplementationCustom.native.js +601 -434
- package/dist/esm/SheetImplementationCustom.native.js.map +1 -1
- package/dist/esm/SheetScrollView.mjs +165 -104
- package/dist/esm/SheetScrollView.mjs.map +1 -1
- package/dist/esm/SheetScrollView.native.js +184 -133
- package/dist/esm/SheetScrollView.native.js.map +1 -1
- package/dist/esm/constants.mjs +4 -4
- package/dist/esm/constants.mjs.map +1 -1
- package/dist/esm/constants.native.js +4 -4
- package/dist/esm/constants.native.js.map +1 -1
- package/dist/esm/contexts.mjs +3 -3
- package/dist/esm/contexts.mjs.map +1 -1
- package/dist/esm/contexts.native.js +3 -3
- package/dist/esm/contexts.native.js.map +1 -1
- package/dist/esm/createSheet.mjs +130 -133
- package/dist/esm/createSheet.mjs.map +1 -1
- package/dist/esm/createSheet.native.js +142 -152
- package/dist/esm/createSheet.native.js.map +1 -1
- package/dist/esm/helpers.mjs +5 -3
- package/dist/esm/helpers.mjs.map +1 -1
- package/dist/esm/helpers.native.js +5 -3
- package/dist/esm/helpers.native.js.map +1 -1
- package/dist/esm/index.js +11 -11
- package/dist/esm/index.js.map +1 -6
- package/dist/esm/keyboardAvoidance.mjs +17 -0
- package/dist/esm/keyboardAvoidance.mjs.map +1 -0
- package/dist/esm/keyboardAvoidance.native.js +18 -0
- package/dist/esm/keyboardAvoidance.native.js.map +1 -0
- package/dist/esm/nativeSheet.mjs +49 -38
- package/dist/esm/nativeSheet.mjs.map +1 -1
- package/dist/esm/nativeSheet.native.js +55 -48
- package/dist/esm/nativeSheet.native.js.map +1 -1
- package/dist/esm/setupGestureHandler.mjs +12 -8
- package/dist/esm/setupGestureHandler.mjs.map +1 -1
- package/dist/esm/setupGestureHandler.native.js +12 -9
- package/dist/esm/setupGestureHandler.native.js.map +1 -1
- package/dist/esm/useGestureHandlerPan.mjs +167 -99
- package/dist/esm/useGestureHandlerPan.mjs.map +1 -1
- package/dist/esm/useGestureHandlerPan.native.js +168 -102
- package/dist/esm/useGestureHandlerPan.native.js.map +1 -1
- package/dist/esm/useKeyboardControllerSheet.mjs +65 -9
- package/dist/esm/useKeyboardControllerSheet.mjs.map +1 -1
- package/dist/esm/useKeyboardControllerSheet.native.js +85 -69
- package/dist/esm/useKeyboardControllerSheet.native.js.map +1 -1
- package/dist/esm/useSheetController.mjs +11 -11
- package/dist/esm/useSheetController.mjs.map +1 -1
- package/dist/esm/useSheetController.native.js +11 -11
- package/dist/esm/useSheetController.native.js.map +1 -1
- package/dist/esm/useSheetOffscreenSize.mjs +23 -13
- package/dist/esm/useSheetOffscreenSize.mjs.map +1 -1
- package/dist/esm/useSheetOffscreenSize.native.js +24 -17
- package/dist/esm/useSheetOffscreenSize.native.js.map +1 -1
- package/dist/esm/useSheetOpenState.mjs +14 -13
- package/dist/esm/useSheetOpenState.mjs.map +1 -1
- package/dist/esm/useSheetOpenState.native.js +17 -17
- package/dist/esm/useSheetOpenState.native.js.map +1 -1
- package/dist/esm/useSheetProviderProps.mjs +101 -55
- package/dist/esm/useSheetProviderProps.mjs.map +1 -1
- package/dist/esm/useSheetProviderProps.native.js +137 -96
- package/dist/esm/useSheetProviderProps.native.js.map +1 -1
- package/dist/esm/useSheetScrollViewGestures.mjs +117 -71
- package/dist/esm/useSheetScrollViewGestures.mjs.map +1 -1
- package/dist/esm/useSheetScrollViewGestures.native.js +116 -69
- package/dist/esm/useSheetScrollViewGestures.native.js.map +1 -1
- package/dist/esm/webViewport.mjs +22 -0
- package/dist/esm/webViewport.mjs.map +1 -0
- package/dist/esm/webViewport.native.js +23 -0
- package/dist/esm/webViewport.native.js.map +1 -0
- package/dist/jsx/GestureDetectorWrapper.mjs +12 -8
- package/dist/jsx/GestureDetectorWrapper.mjs.map +1 -1
- package/dist/jsx/GestureDetectorWrapper.native.js +33 -28
- package/dist/jsx/GestureDetectorWrapper.native.js.map +1 -1
- package/dist/jsx/GestureSheetContext.native.js +29 -27
- package/dist/jsx/GestureSheetContext.native.js.map +1 -1
- package/dist/jsx/Sheet.mjs +70 -70
- package/dist/jsx/Sheet.mjs.map +1 -1
- package/dist/jsx/Sheet.native.js +88 -86
- package/dist/jsx/Sheet.native.js.map +1 -1
- package/dist/jsx/SheetContext.mjs +2 -2
- package/dist/jsx/SheetContext.mjs.map +1 -1
- package/dist/jsx/SheetContext.native.js +16 -14
- package/dist/jsx/SheetContext.native.js.map +1 -1
- package/dist/jsx/SheetController.mjs +12 -6
- package/dist/jsx/SheetController.mjs.map +1 -1
- package/dist/jsx/SheetController.native.js +62 -54
- package/dist/jsx/SheetController.native.js.map +1 -1
- package/dist/jsx/SheetImplementationCustom.mjs +575 -389
- package/dist/jsx/SheetImplementationCustom.mjs.map +1 -1
- package/dist/jsx/SheetImplementationCustom.native.js +647 -474
- package/dist/jsx/SheetImplementationCustom.native.js.map +1 -1
- package/dist/jsx/SheetScrollView.mjs +165 -104
- package/dist/jsx/SheetScrollView.mjs.map +1 -1
- package/dist/jsx/SheetScrollView.native.js +216 -163
- package/dist/jsx/SheetScrollView.native.js.map +1 -1
- package/dist/jsx/constants.mjs +4 -4
- package/dist/jsx/constants.mjs.map +1 -1
- package/dist/jsx/constants.native.js +16 -14
- package/dist/jsx/constants.native.js.map +1 -1
- package/dist/jsx/contexts.mjs +3 -3
- package/dist/jsx/contexts.mjs.map +1 -1
- package/dist/jsx/contexts.native.js +29 -27
- package/dist/jsx/contexts.native.js.map +1 -1
- package/dist/jsx/controller.native.js +14 -12
- package/dist/jsx/createSheet.mjs +130 -133
- package/dist/jsx/createSheet.mjs.map +1 -1
- package/dist/jsx/createSheet.native.js +172 -180
- package/dist/jsx/createSheet.native.js.map +1 -1
- package/dist/jsx/gestureState.native.js +12 -10
- package/dist/jsx/gestureState.native.js.map +1 -1
- package/dist/jsx/helpers.mjs +5 -3
- package/dist/jsx/helpers.mjs.map +1 -1
- package/dist/jsx/helpers.native.js +17 -13
- package/dist/jsx/helpers.native.js.map +1 -1
- package/dist/jsx/index.js +11 -11
- package/dist/jsx/index.js.map +1 -6
- package/dist/jsx/index.native.js +7 -5
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/keyboardAvoidance.mjs +17 -0
- package/dist/jsx/keyboardAvoidance.mjs.map +1 -0
- package/dist/jsx/keyboardAvoidance.native.js +46 -0
- package/dist/jsx/keyboardAvoidance.native.js.map +1 -0
- package/dist/jsx/nativeSheet.mjs +49 -38
- package/dist/jsx/nativeSheet.mjs.map +1 -1
- package/dist/jsx/nativeSheet.native.js +77 -68
- package/dist/jsx/nativeSheet.native.js.map +1 -1
- package/dist/jsx/setupGestureHandler.mjs +12 -8
- package/dist/jsx/setupGestureHandler.mjs.map +1 -1
- package/dist/jsx/setupGestureHandler.native.js +24 -19
- package/dist/jsx/setupGestureHandler.native.js.map +1 -1
- package/dist/jsx/types.native.js +7 -5
- package/dist/jsx/useGestureHandlerPan.mjs +167 -99
- package/dist/jsx/useGestureHandlerPan.mjs.map +1 -1
- package/dist/jsx/useGestureHandlerPan.native.js +183 -115
- package/dist/jsx/useGestureHandlerPan.native.js.map +1 -1
- package/dist/jsx/useKeyboardControllerSheet.mjs +65 -9
- package/dist/jsx/useKeyboardControllerSheet.mjs.map +1 -1
- package/dist/jsx/useKeyboardControllerSheet.native.js +100 -82
- package/dist/jsx/useKeyboardControllerSheet.native.js.map +1 -1
- package/dist/jsx/useSheet.native.js +16 -14
- package/dist/jsx/useSheetController.mjs +11 -11
- package/dist/jsx/useSheetController.mjs.map +1 -1
- package/dist/jsx/useSheetController.native.js +37 -35
- package/dist/jsx/useSheetController.native.js.map +1 -1
- package/dist/jsx/useSheetOffscreenSize.mjs +23 -13
- package/dist/jsx/useSheetOffscreenSize.mjs.map +1 -1
- package/dist/jsx/useSheetOffscreenSize.native.js +36 -27
- package/dist/jsx/useSheetOffscreenSize.native.js.map +1 -1
- package/dist/jsx/useSheetOpenState.mjs +14 -13
- package/dist/jsx/useSheetOpenState.mjs.map +1 -1
- package/dist/jsx/useSheetOpenState.native.js +39 -37
- package/dist/jsx/useSheetOpenState.native.js.map +1 -1
- package/dist/jsx/useSheetProviderProps.mjs +101 -55
- package/dist/jsx/useSheetProviderProps.mjs.map +1 -1
- package/dist/jsx/useSheetProviderProps.native.js +165 -122
- package/dist/jsx/useSheetProviderProps.native.js.map +1 -1
- package/dist/jsx/useSheetScrollViewGestures.mjs +117 -71
- package/dist/jsx/useSheetScrollViewGestures.mjs.map +1 -1
- package/dist/jsx/useSheetScrollViewGestures.native.js +128 -79
- package/dist/jsx/useSheetScrollViewGestures.native.js.map +1 -1
- package/dist/jsx/webViewport.mjs +22 -0
- package/dist/jsx/webViewport.mjs.map +1 -0
- package/dist/jsx/webViewport.native.js +54 -0
- package/dist/jsx/webViewport.native.js.map +1 -0
- package/next.md +78 -0
- package/package.json +29 -39
- 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/src/GestureDetectorWrapper.tsx +0 -3
- package/src/SheetController.tsx +4 -1
- package/src/SheetImplementationCustom.tsx +414 -84
- package/src/SheetScrollView.tsx +74 -9
- package/src/keyboardAvoidance.ts +30 -0
- package/src/nativeSheet.tsx +9 -1
- package/src/types.tsx +16 -1
- package/src/useGestureHandlerPan.tsx +5 -15
- package/src/useKeyboardControllerSheet.ts +106 -10
- package/src/useSheetController.tsx +4 -0
- package/src/useSheetProviderProps.tsx +17 -0
- package/src/useSheetScrollViewGestures.ts +23 -2
- package/src/webViewport.ts +52 -0
- package/test/keyboardAvoidance.test.ts +53 -0
- package/tsconfig.json +57 -0
- package/types/GestureDetectorWrapper.d.ts.map +1 -1
- package/types/Sheet.d.ts +3 -0
- package/types/Sheet.d.ts.map +1 -1
- package/types/SheetContext.d.ts +4 -0
- package/types/SheetContext.d.ts.map +1 -1
- package/types/SheetController.d.ts +1 -1
- package/types/SheetController.d.ts.map +1 -1
- package/types/SheetImplementationCustom.d.ts +3 -0
- package/types/SheetImplementationCustom.d.ts.map +1 -1
- package/types/SheetScrollView.d.ts.map +1 -1
- package/types/createSheet.d.ts +3 -0
- package/types/createSheet.d.ts.map +1 -1
- package/types/keyboardAvoidance.d.ts +8 -0
- package/types/keyboardAvoidance.d.ts.map +1 -0
- package/types/nativeSheet.d.ts.map +1 -1
- package/types/types.d.ts +10 -1
- package/types/types.d.ts.map +1 -1
- package/types/useGestureHandlerPan.d.ts.map +1 -1
- package/types/useKeyboardControllerSheet.d.ts +14 -3
- package/types/useKeyboardControllerSheet.d.ts.map +1 -1
- package/types/useSheetController.d.ts +3 -0
- package/types/useSheetController.d.ts.map +1 -1
- package/types/useSheetProviderProps.d.ts +4 -0
- package/types/useSheetProviderProps.d.ts.map +1 -1
- package/types/useSheetScrollViewGestures.d.ts.map +1 -1
- package/types/webViewport.d.ts +30 -0
- package/types/webViewport.d.ts.map +1 -0
- package/dist/cjs/GestureDetectorWrapper.js +0 -29
- package/dist/cjs/GestureDetectorWrapper.js.map +0 -6
- package/dist/cjs/GestureSheetContext.js +0 -43
- package/dist/cjs/GestureSheetContext.js.map +0 -6
- package/dist/cjs/Sheet.js +0 -104
- package/dist/cjs/Sheet.js.map +0 -6
- package/dist/cjs/SheetContext.js +0 -28
- package/dist/cjs/SheetContext.js.map +0 -6
- package/dist/cjs/SheetController.js +0 -52
- package/dist/cjs/SheetController.js.map +0 -6
- package/dist/cjs/SheetImplementationCustom.js +0 -393
- package/dist/cjs/SheetImplementationCustom.js.map +0 -6
- package/dist/cjs/SheetScrollView.js +0 -137
- package/dist/cjs/SheetScrollView.js.map +0 -6
- package/dist/cjs/constants.js +0 -24
- package/dist/cjs/constants.js.map +0 -6
- package/dist/cjs/contexts.js +0 -33
- package/dist/cjs/contexts.js.map +0 -6
- package/dist/cjs/controller.js +0 -23
- package/dist/cjs/controller.js.map +0 -6
- package/dist/cjs/createSheet.js +0 -152
- package/dist/cjs/createSheet.js.map +0 -6
- package/dist/cjs/gestureState.js +0 -34
- package/dist/cjs/gestureState.js.map +0 -6
- package/dist/cjs/helpers.js +0 -26
- package/dist/cjs/helpers.js.map +0 -6
- package/dist/cjs/index.js +0 -25
- package/dist/cjs/index.js.map +0 -6
- package/dist/cjs/nativeSheet.js +0 -56
- package/dist/cjs/nativeSheet.js.map +0 -6
- package/dist/cjs/setupGestureHandler.js +0 -38
- package/dist/cjs/setupGestureHandler.js.map +0 -6
- package/dist/cjs/types.js +0 -14
- package/dist/cjs/types.js.map +0 -6
- package/dist/cjs/useGestureHandlerPan.js +0 -126
- package/dist/cjs/useGestureHandlerPan.js.map +0 -6
- package/dist/cjs/useKeyboardControllerSheet.js +0 -34
- package/dist/cjs/useKeyboardControllerSheet.js.map +0 -6
- package/dist/cjs/useSheet.js +0 -22
- package/dist/cjs/useSheet.js.map +0 -6
- package/dist/cjs/useSheetController.js +0 -39
- package/dist/cjs/useSheetController.js.map +0 -6
- package/dist/cjs/useSheetOffscreenSize.js +0 -43
- package/dist/cjs/useSheetOffscreenSize.js.map +0 -6
- package/dist/cjs/useSheetOpenState.js +0 -37
- package/dist/cjs/useSheetOpenState.js.map +0 -6
- package/dist/cjs/useSheetProviderProps.js +0 -130
- package/dist/cjs/useSheetProviderProps.js.map +0 -6
- package/dist/cjs/useSheetScrollViewGestures.js +0 -102
- package/dist/cjs/useSheetScrollViewGestures.js.map +0 -6
- package/dist/esm/GestureDetectorWrapper.js +0 -15
- package/dist/esm/GestureDetectorWrapper.js.map +0 -6
- package/dist/esm/GestureSheetContext.js +0 -28
- package/dist/esm/GestureSheetContext.js.map +0 -6
- package/dist/esm/Sheet.js +0 -92
- package/dist/esm/Sheet.js.map +0 -6
- package/dist/esm/SheetContext.js +0 -13
- package/dist/esm/SheetContext.js.map +0 -6
- package/dist/esm/SheetController.js +0 -31
- package/dist/esm/SheetController.js.map +0 -6
- package/dist/esm/SheetImplementationCustom.js +0 -395
- package/dist/esm/SheetImplementationCustom.js.map +0 -6
- package/dist/esm/SheetScrollView.js +0 -122
- package/dist/esm/SheetScrollView.js.map +0 -6
- package/dist/esm/constants.js +0 -8
- package/dist/esm/constants.js.map +0 -6
- package/dist/esm/contexts.js +0 -9
- package/dist/esm/contexts.js.map +0 -6
- package/dist/esm/controller.js +0 -11
- package/dist/esm/controller.js.map +0 -6
- package/dist/esm/createSheet.js +0 -153
- package/dist/esm/createSheet.js.map +0 -6
- package/dist/esm/gestureState.js +0 -18
- package/dist/esm/gestureState.js.map +0 -6
- package/dist/esm/helpers.js +0 -10
- package/dist/esm/helpers.js.map +0 -6
- package/dist/esm/nativeSheet.js +0 -46
- package/dist/esm/nativeSheet.js.map +0 -6
- package/dist/esm/setupGestureHandler.js +0 -22
- package/dist/esm/setupGestureHandler.js.map +0 -6
- package/dist/esm/types.js +0 -1
- package/dist/esm/types.js.map +0 -6
- package/dist/esm/useGestureHandlerPan.js +0 -111
- package/dist/esm/useGestureHandlerPan.js.map +0 -6
- package/dist/esm/useKeyboardControllerSheet.js +0 -18
- package/dist/esm/useKeyboardControllerSheet.js.map +0 -6
- package/dist/esm/useSheet.js +0 -6
- package/dist/esm/useSheet.js.map +0 -6
- package/dist/esm/useSheetController.js +0 -15
- package/dist/esm/useSheetController.js.map +0 -6
- package/dist/esm/useSheetOffscreenSize.js +0 -27
- package/dist/esm/useSheetOffscreenSize.js.map +0 -6
- package/dist/esm/useSheetOpenState.js +0 -22
- package/dist/esm/useSheetOpenState.js.map +0 -6
- package/dist/esm/useSheetProviderProps.js +0 -109
- package/dist/esm/useSheetProviderProps.js.map +0 -6
- package/dist/esm/useSheetScrollViewGestures.js +0 -86
- package/dist/esm/useSheetScrollViewGestures.js.map +0 -6
- package/dist/jsx/GestureDetectorWrapper.js +0 -15
- package/dist/jsx/GestureDetectorWrapper.js.map +0 -6
- package/dist/jsx/GestureSheetContext.js +0 -28
- package/dist/jsx/GestureSheetContext.js.map +0 -6
- package/dist/jsx/Sheet.js +0 -92
- package/dist/jsx/Sheet.js.map +0 -6
- package/dist/jsx/SheetContext.js +0 -13
- package/dist/jsx/SheetContext.js.map +0 -6
- package/dist/jsx/SheetController.js +0 -31
- package/dist/jsx/SheetController.js.map +0 -6
- package/dist/jsx/SheetImplementationCustom.js +0 -395
- package/dist/jsx/SheetImplementationCustom.js.map +0 -6
- package/dist/jsx/SheetScrollView.js +0 -122
- package/dist/jsx/SheetScrollView.js.map +0 -6
- package/dist/jsx/constants.js +0 -8
- package/dist/jsx/constants.js.map +0 -6
- package/dist/jsx/contexts.js +0 -9
- package/dist/jsx/contexts.js.map +0 -6
- package/dist/jsx/controller.js +0 -11
- package/dist/jsx/controller.js.map +0 -6
- package/dist/jsx/createSheet.js +0 -153
- package/dist/jsx/createSheet.js.map +0 -6
- package/dist/jsx/gestureState.js +0 -18
- package/dist/jsx/gestureState.js.map +0 -6
- package/dist/jsx/helpers.js +0 -10
- package/dist/jsx/helpers.js.map +0 -6
- package/dist/jsx/nativeSheet.js +0 -46
- package/dist/jsx/nativeSheet.js.map +0 -6
- package/dist/jsx/setupGestureHandler.js +0 -22
- package/dist/jsx/setupGestureHandler.js.map +0 -6
- package/dist/jsx/types.js +0 -1
- package/dist/jsx/types.js.map +0 -6
- package/dist/jsx/useGestureHandlerPan.js +0 -111
- package/dist/jsx/useGestureHandlerPan.js.map +0 -6
- package/dist/jsx/useKeyboardControllerSheet.js +0 -18
- package/dist/jsx/useKeyboardControllerSheet.js.map +0 -6
- package/dist/jsx/useSheet.js +0 -6
- package/dist/jsx/useSheet.js.map +0 -6
- package/dist/jsx/useSheetController.js +0 -15
- package/dist/jsx/useSheetController.js.map +0 -6
- package/dist/jsx/useSheetOffscreenSize.js +0 -27
- package/dist/jsx/useSheetOffscreenSize.js.map +0 -6
- package/dist/jsx/useSheetOpenState.js +0 -22
- package/dist/jsx/useSheetOpenState.js.map +0 -6
- package/dist/jsx/useSheetProviderProps.js +0 -109
- package/dist/jsx/useSheetProviderProps.js.map +0 -6
- package/dist/jsx/useSheetScrollViewGestures.js +0 -86
- package/dist/jsx/useSheetScrollViewGestures.js.map +0 -6
- package/types/GestureDetectorWrapper.native.d.ts +0 -14
- package/types/gestureState.native.d.ts +0 -12
- package/types/setupGestureHandler.native.d.ts +0 -41
- package/types/useGestureHandlerPan.native.d.ts +0 -33
- package/types/useSheetScrollViewGestures.web.d.ts +0 -15
- package/types/useSheetScrollViewGestures.web.d.ts.map +0 -1
package/src/SheetScrollView.tsx
CHANGED
|
@@ -10,6 +10,7 @@ import { getGestureHandlerState, isGestureHandlerEnabled } from './gestureState'
|
|
|
10
10
|
import { useSheetContext } from './SheetContext'
|
|
11
11
|
import type { SheetScopedProps } from './types'
|
|
12
12
|
import { useSheetScrollViewGestures } from './useSheetScrollViewGestures'
|
|
13
|
+
import { getWebKeyboardHeight, MIN_KEYBOARD_HEIGHT } from './webViewport'
|
|
13
14
|
|
|
14
15
|
const SHEET_SCROLL_VIEW_NAME = 'SheetScrollView'
|
|
15
16
|
|
|
@@ -29,13 +30,66 @@ export const SheetScrollView = React.forwardRef<
|
|
|
29
30
|
) => {
|
|
30
31
|
const context = useSheetContext(SHEET_SCROLL_VIEW_NAME, __scopeSheet)
|
|
31
32
|
const gestureContext = useGestureSheetContext()
|
|
32
|
-
const { scrollBridge, setHasScrollView } = context
|
|
33
|
+
const { scrollBridge, setHasScrollView, hasFit, screenSize } = context
|
|
34
|
+
const keyboardOccludedHeight = Math.max(0, context.keyboardOccludedHeight || 0)
|
|
35
|
+
// OR a LIVE DOM check: context.isKeyboardVisible (React state) lags the
|
|
36
|
+
// viewport resize, so on the open-transition render this component can re-run
|
|
37
|
+
// with the shrunk consumer maxHeight BEFORE the context flag flips. reading
|
|
38
|
+
// the keyboard height straight from visualViewport closes that race so the
|
|
39
|
+
// height freeze engages on the same render that would otherwise collapse it.
|
|
40
|
+
const isKeyboardVisible =
|
|
41
|
+
context.isKeyboardVisible === true ||
|
|
42
|
+
(isWeb && getWebKeyboardHeight() >= MIN_KEYBOARD_HEIGHT)
|
|
33
43
|
const [scrollEnabled] = useControllableState({
|
|
34
44
|
prop: scrollEnabledProp,
|
|
35
45
|
defaultProp: true,
|
|
36
46
|
})
|
|
37
47
|
const scrollRef = React.useRef<RNScrollView | null>(null)
|
|
38
48
|
|
|
49
|
+
const [hasScrollableContent, setHasScrollableContent] = useState(true)
|
|
50
|
+
const parentHeight = useRef(0)
|
|
51
|
+
const contentHeight = useRef(0)
|
|
52
|
+
// the sheet's authoritative pre-keyboard frame height (see SheetImpl). a
|
|
53
|
+
// scroll-view-local high-water mark used to live here, but it was unreliable
|
|
54
|
+
// (the ref could read 0 if the view remounted on focus / never laid out while
|
|
55
|
+
// closed), so the height now comes from the sheet, which doesn't remount.
|
|
56
|
+
const frozenFrameHeight = Math.max(0, context.keyboardStableFrameHeight || 0)
|
|
57
|
+
|
|
58
|
+
// with snapPointsMode="fit", Frame is content-sized (flex: 0, flex-basis: auto, height: undefined).
|
|
59
|
+
// a flex: 1 child can't grow inside a content-sized parent, so the ScrollView (and the Frame
|
|
60
|
+
// around it) collapse to 0 height. instead, let the ScrollView size to its content and cap it
|
|
61
|
+
// at the available viewport (screenSize / maxContentSize) so scrolling kicks in for tall content.
|
|
62
|
+
const fitSizingStyle = hasFit
|
|
63
|
+
? {
|
|
64
|
+
flex: undefined as undefined,
|
|
65
|
+
height: undefined as undefined,
|
|
66
|
+
maxHeight: screenSize || undefined,
|
|
67
|
+
}
|
|
68
|
+
: { flex: 1 }
|
|
69
|
+
|
|
70
|
+
// AUTOFOCUS-ON-OPEN seed (web): the sheet is still reconstructing its
|
|
71
|
+
// pre-keyboard frame baseline and needs THIS scroll view to size to its
|
|
72
|
+
// content so it can measure the true content height. so we apply the stable
|
|
73
|
+
// screen only as a maxHeight cap (UNCLIP from the shrunk consumer maxHeight)
|
|
74
|
+
// and leave height undefined so it stays content-sized.
|
|
75
|
+
const isKeyboardSeeding = context.isKeyboardSeeding === true
|
|
76
|
+
|
|
77
|
+
// when the keyboard is open the sheet stays ANCHORED at the bottom and keeps
|
|
78
|
+
// its full pre-keyboard height — the keyboard overlays its lower part and the
|
|
79
|
+
// keyboardOccludedHeight tail padding (added to the scroll content below) +
|
|
80
|
+
// browser scroll-into-view lift the focused input above the keyboard. so we
|
|
81
|
+
// pin the height to the sheet's authoritative frozenFrameHeight, overriding
|
|
82
|
+
// any consumer maxHeight (on web that's often tied to useWindowDimensions,
|
|
83
|
+
// which SHRINKS when the keyboard opens and would otherwise collapse the
|
|
84
|
+
// sheet). holding the height constant means nothing animates on keyboard
|
|
85
|
+
// open/close — no jump/teleport. applied AFTER {...props} so it wins.
|
|
86
|
+
const keyboardFrozenOverride =
|
|
87
|
+
hasFit && isKeyboardVisible && frozenFrameHeight > 0
|
|
88
|
+
? isKeyboardSeeding
|
|
89
|
+
? { maxHeight: frozenFrameHeight }
|
|
90
|
+
: { height: frozenFrameHeight, maxHeight: frozenFrameHeight }
|
|
91
|
+
: null
|
|
92
|
+
|
|
39
93
|
const panGestureRef = gestureContext?.panGestureRef
|
|
40
94
|
const { ScrollView: RNGHScrollView } = getGestureHandlerState()
|
|
41
95
|
const useRNGHScrollView = isGestureHandlerEnabled() && RNGHScrollView && panGestureRef
|
|
@@ -73,16 +127,18 @@ export const SheetScrollView = React.forwardRef<
|
|
|
73
127
|
}
|
|
74
128
|
}, [])
|
|
75
129
|
|
|
76
|
-
const [hasScrollableContent, setHasScrollableContent] = useState(true)
|
|
77
|
-
const parentHeight = useRef(0)
|
|
78
|
-
const contentHeight = useRef(0)
|
|
79
|
-
|
|
80
130
|
const updateScrollable = () => {
|
|
81
131
|
if (parentHeight.current && contentHeight.current) {
|
|
82
132
|
setHasScrollableContent(contentHeight.current > parentHeight.current)
|
|
83
133
|
}
|
|
84
134
|
}
|
|
85
135
|
|
|
136
|
+
// track the fit height for the scrollable-content check. the keyboard-freeze
|
|
137
|
+
// height is supplied by the sheet (frozenFrameHeight), not derived here.
|
|
138
|
+
const recordFitHeight = (height: number) => {
|
|
139
|
+
parentHeight.current = height
|
|
140
|
+
}
|
|
141
|
+
|
|
86
142
|
useEffect(() => {
|
|
87
143
|
scrollBridge.hasScrollableContent = hasScrollableContent
|
|
88
144
|
}, [hasScrollableContent])
|
|
@@ -108,6 +164,13 @@ export const SheetScrollView = React.forwardRef<
|
|
|
108
164
|
}}
|
|
109
165
|
>
|
|
110
166
|
{children}
|
|
167
|
+
{keyboardOccludedHeight > 0 && (
|
|
168
|
+
<View
|
|
169
|
+
data-sheet-keyboard-scroll-pad
|
|
170
|
+
height={keyboardOccludedHeight}
|
|
171
|
+
width="100%"
|
|
172
|
+
/>
|
|
173
|
+
)}
|
|
111
174
|
</View>
|
|
112
175
|
)
|
|
113
176
|
|
|
@@ -117,12 +180,12 @@ export const SheetScrollView = React.forwardRef<
|
|
|
117
180
|
return (
|
|
118
181
|
<RNGHComponent
|
|
119
182
|
ref={composeRefs(scrollRef as any, ref)}
|
|
120
|
-
style={
|
|
183
|
+
style={fitSizingStyle}
|
|
121
184
|
scrollEventThrottle={1}
|
|
122
185
|
scrollEnabled={scrollEnabled}
|
|
123
186
|
simultaneousHandlers={[panGestureRef]}
|
|
124
187
|
onLayout={(e: any) => {
|
|
125
|
-
|
|
188
|
+
recordFitHeight(Math.ceil(e.nativeEvent.layout.height))
|
|
126
189
|
updateScrollable()
|
|
127
190
|
}}
|
|
128
191
|
onScroll={(e: any) => {
|
|
@@ -160,6 +223,7 @@ export const SheetScrollView = React.forwardRef<
|
|
|
160
223
|
keyboardShouldPersistTaps="always"
|
|
161
224
|
keyboardDismissMode="none"
|
|
162
225
|
{...props}
|
|
226
|
+
{...keyboardFrozenOverride}
|
|
163
227
|
>
|
|
164
228
|
{contentWrapper}
|
|
165
229
|
</RNGHComponent>
|
|
@@ -170,11 +234,11 @@ export const SheetScrollView = React.forwardRef<
|
|
|
170
234
|
return (
|
|
171
235
|
<ScrollView
|
|
172
236
|
onLayout={(e) => {
|
|
173
|
-
|
|
237
|
+
recordFitHeight(Math.ceil(e.nativeEvent.layout.height))
|
|
174
238
|
updateScrollable()
|
|
175
239
|
}}
|
|
176
240
|
ref={composeRefs(scrollRef as any, ref)}
|
|
177
|
-
|
|
241
|
+
{...fitSizingStyle}
|
|
178
242
|
scrollEventThrottle={1}
|
|
179
243
|
className="_ovs-contain"
|
|
180
244
|
scrollEnabled={scrollEnabled}
|
|
@@ -187,6 +251,7 @@ export const SheetScrollView = React.forwardRef<
|
|
|
187
251
|
contentContainerStyle={{ minHeight: '100%' }}
|
|
188
252
|
{...gestureProps}
|
|
189
253
|
{...props}
|
|
254
|
+
{...keyboardFrozenOverride}
|
|
190
255
|
>
|
|
191
256
|
{contentWrapper}
|
|
192
257
|
</ScrollView>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function getKeyboardOccludedHeight({
|
|
2
|
+
frameSize,
|
|
3
|
+
isKeyboardVisible,
|
|
4
|
+
keyboardHeight,
|
|
5
|
+
screenSize,
|
|
6
|
+
sheetY,
|
|
7
|
+
}: {
|
|
8
|
+
frameSize: number
|
|
9
|
+
isKeyboardVisible: boolean
|
|
10
|
+
keyboardHeight: number
|
|
11
|
+
screenSize: number
|
|
12
|
+
sheetY: number | undefined
|
|
13
|
+
}) {
|
|
14
|
+
if (
|
|
15
|
+
!isKeyboardVisible ||
|
|
16
|
+
keyboardHeight <= 0 ||
|
|
17
|
+
screenSize <= 0 ||
|
|
18
|
+
frameSize <= 0 ||
|
|
19
|
+
sheetY === undefined ||
|
|
20
|
+
sheetY >= screenSize
|
|
21
|
+
) {
|
|
22
|
+
return 0
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const keyboardTop = screenSize - keyboardHeight
|
|
26
|
+
const sheetBottom = sheetY + frameSize
|
|
27
|
+
const occludedHeight = Math.ceil(sheetBottom - keyboardTop)
|
|
28
|
+
|
|
29
|
+
return Math.min(frameSize, Math.max(0, occludedHeight))
|
|
30
|
+
}
|
package/src/nativeSheet.tsx
CHANGED
|
@@ -59,7 +59,15 @@ export function setupNativeSheet(
|
|
|
59
59
|
|
|
60
60
|
return (
|
|
61
61
|
<>
|
|
62
|
-
<SheetProvider
|
|
62
|
+
<SheetProvider
|
|
63
|
+
setHasScrollView={emptyFn}
|
|
64
|
+
keyboardOccludedHeight={0}
|
|
65
|
+
isKeyboardVisible={false}
|
|
66
|
+
keyboardStableFrameHeight={0}
|
|
67
|
+
isKeyboardSeeding={false}
|
|
68
|
+
{...providerProps}
|
|
69
|
+
onlyShowFrame
|
|
70
|
+
>
|
|
63
71
|
<ModalSheetView ref={ref} onModalDidDismiss={() => setOpenInternal(false)}>
|
|
64
72
|
<ModalSheetViewMainContent>
|
|
65
73
|
<View style={{ flex: 1 }}>{props.children}</View>
|
package/src/types.tsx
CHANGED
|
@@ -75,10 +75,16 @@ export type SheetProps = ScopedProps<
|
|
|
75
75
|
zIndex?: number
|
|
76
76
|
portalProps?: PortalProps
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
78
|
+
* Makes the sheet move up when the mobile keyboard opens so the focused input remains visible.
|
|
79
|
+
* Works on native (via keyboard events) and on mobile web (via the VisualViewport API).
|
|
79
80
|
*/
|
|
80
81
|
moveOnKeyboardChange?: boolean
|
|
81
82
|
containerComponent?: React.ComponentType<any>
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Called when the sheet open/close animation completes.
|
|
86
|
+
*/
|
|
87
|
+
onAnimationComplete?: (info: { open: boolean }) => void
|
|
82
88
|
},
|
|
83
89
|
'Sheet'
|
|
84
90
|
>
|
|
@@ -126,6 +132,15 @@ export type ScrollBridge = {
|
|
|
126
132
|
isAtTop?: boolean
|
|
127
133
|
// snap sheet to a specific position (for handoff UP)
|
|
128
134
|
snapToPosition?: (positionIndex: number) => void
|
|
135
|
+
// re-baseline the pan drag origin to the current animated position. the web
|
|
136
|
+
// scroll-view hook calls this on each transition into pan ownership so a
|
|
137
|
+
// scroll→pan handoff resumes from where the sheet is, not a stale origin.
|
|
138
|
+
startPanDrag?: () => void
|
|
139
|
+
// web only: true while a touch is active on the ScrollView node. The web
|
|
140
|
+
// scroll-view gesture hook owns drag detection for those touches (it calls
|
|
141
|
+
// drag/release on this bridge), so the PanResponder must NOT also grant for
|
|
142
|
+
// them — otherwise two systems drive the animated position and it jitters.
|
|
143
|
+
scrollNodeTouched?: boolean
|
|
129
144
|
}
|
|
130
145
|
|
|
131
146
|
// keyboard controller sheet types
|
|
@@ -122,7 +122,6 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
|
|
|
122
122
|
|
|
123
123
|
// simultaneousHandlers pattern from react-native-actions-sheet
|
|
124
124
|
// both gestures run simultaneously, we use blockPan to decide who handles
|
|
125
|
-
// console.warn('[RNGH-Pan] CREATING gesture, minY:', minY, 'frameSize:', frameSize)
|
|
126
125
|
const gesture = Gesture.Pan()
|
|
127
126
|
.withRef(panGestureRef)
|
|
128
127
|
// NO manualActivation - let both gestures run via simultaneousHandlers
|
|
@@ -148,7 +147,6 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
|
|
|
148
147
|
const pos = getCurrentPosition()
|
|
149
148
|
const atTop = pos <= minY + AT_TOP_THRESHOLD
|
|
150
149
|
const currentScrollY = scrollBridge.y
|
|
151
|
-
// console.warn('[RNGH-Pan] onBegin', { pos, minY, atTop, currentScrollY })
|
|
152
150
|
gs.startY = pos
|
|
153
151
|
gs.lastPanTranslationY = 0
|
|
154
152
|
gs.accumulatedOffset = 0
|
|
@@ -171,7 +169,6 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
|
|
|
171
169
|
gs.panStarted = true
|
|
172
170
|
setIsDragging(true)
|
|
173
171
|
|
|
174
|
-
// console.warn('[RNGH-Pan] onStart', { startY: gs.startY, minY })
|
|
175
172
|
scrollBridge.initialPosition = gs.startY
|
|
176
173
|
onStart()
|
|
177
174
|
})
|
|
@@ -195,8 +192,6 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
|
|
|
195
192
|
const isCurrentlyAtTop = currentPos <= minY + AT_TOP_THRESHOLD
|
|
196
193
|
const nodeIsScrolling = scrollY > 0
|
|
197
194
|
|
|
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
195
|
// decision matrix (from react-native-actions-sheet pattern)
|
|
201
196
|
// each frame, decide who handles the movement based on current state
|
|
202
197
|
//
|
|
@@ -229,7 +224,6 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
|
|
|
229
224
|
} else if (gs.scrollEngaged && hasScrollableContent) {
|
|
230
225
|
// scroll WAS > 0 but now is 0 -> handoff from scroll to pan
|
|
231
226
|
// pan takes over to drag sheet down
|
|
232
|
-
// console.warn('[RNGH-Pan] *** HANDOFF FROM SCROLL TO PAN ***')
|
|
233
227
|
panHandles = true
|
|
234
228
|
} else {
|
|
235
229
|
// scroll never engaged OR content not scrollable, just drag sheet down
|
|
@@ -249,13 +243,13 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
|
|
|
249
243
|
}
|
|
250
244
|
}
|
|
251
245
|
|
|
252
|
-
// console.warn('[RNGH-Pan] decision', { panHandles, isCurrentlyAtTop, isSwipingDown, nodeIsScrolling, scrollEngaged: gs.scrollEngaged, hasScrollableContent, currentPos: currentPos.toFixed(1), minY })
|
|
253
|
-
|
|
254
246
|
if (panHandles) {
|
|
255
247
|
// pan handles - disable scroll and move sheet
|
|
256
|
-
// when
|
|
257
|
-
//
|
|
258
|
-
|
|
248
|
+
// when swiping down at top after scroll was engaged: lock at current scroll position
|
|
249
|
+
// (handoff from scroll to pan — preserve scroll offset)
|
|
250
|
+
// otherwise: always lock scroll to 0 (prevents scroll from firing during sheet drag)
|
|
251
|
+
const lockTo =
|
|
252
|
+
isCurrentlyAtTop && isSwipingDown && gs.scrollEngaged ? undefined : 0
|
|
259
253
|
scrollBridge.setScrollEnabled?.(false, lockTo)
|
|
260
254
|
|
|
261
255
|
// accumulate the delta for position calculation
|
|
@@ -276,8 +270,6 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
|
|
|
276
270
|
const { velocityY } = event
|
|
277
271
|
const currentPos = gs.startY + gs.accumulatedOffset
|
|
278
272
|
|
|
279
|
-
// console.warn('[RNGH-Pan] onEnd', { velocityY, currentPos, accumulatedOffset: gs.accumulatedOffset, scrollY: scrollBridge.y })
|
|
280
|
-
|
|
281
273
|
// clear scroll lock
|
|
282
274
|
scrollBridge.scrollLockY = undefined
|
|
283
275
|
|
|
@@ -315,7 +307,6 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
|
|
|
315
307
|
onEnd(closestPoint)
|
|
316
308
|
})
|
|
317
309
|
.onFinalize(() => {
|
|
318
|
-
// console.warn('[RNGH-Pan] onFinalize', { panStarted: gs.panStarted })
|
|
319
310
|
// clear scroll lock on finalize too (safety)
|
|
320
311
|
scrollBridge.scrollLockY = undefined
|
|
321
312
|
if (gs.panStarted) {
|
|
@@ -334,7 +325,6 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
|
|
|
334
325
|
// if we have a scroll gesture ref, make pan simultaneous with it
|
|
335
326
|
// this allows both gestures to run and we decide in onChange who handles it
|
|
336
327
|
if (scrollGestureRef?.current) {
|
|
337
|
-
// console.warn('[RNGH-Pan] adding simultaneousWithExternalGesture for scroll')
|
|
338
328
|
return gesture.simultaneousWithExternalGesture(scrollGestureRef.current)
|
|
339
329
|
}
|
|
340
330
|
|
|
@@ -1,26 +1,122 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Web
|
|
3
|
-
*
|
|
2
|
+
* Web implementation of the keyboard controller sheet hook.
|
|
3
|
+
*
|
|
4
|
+
* Mobile browsers don't expose a keyboard API, but they do resize the
|
|
5
|
+
* VisualViewport when the soft keyboard opens. We derive the keyboard height as
|
|
6
|
+
* `getStableLayoutViewportHeight() - visualViewport.height` (see webViewport —
|
|
7
|
+
* the stable baseline is document.documentElement.clientHeight, NOT innerHeight,
|
|
8
|
+
* which itself shrinks with the keyboard on real iOS Safari) and feed it into the
|
|
9
|
+
* keyboardOccludedHeight scroll padding in SheetImplementationCustom.
|
|
10
|
+
*
|
|
11
|
+
* Without this, a bottom sheet on mobile web stays pinned behind the keyboard:
|
|
12
|
+
* react-native-web's Dimensions tracks the (shrinking) VisualViewport, so any
|
|
13
|
+
* content sized off window dimensions collapses while the sheet's bottom stays
|
|
14
|
+
* occluded. See SheetImplementationCustom's activePositions / keyboardOccludedHeight.
|
|
4
15
|
*/
|
|
5
16
|
|
|
6
|
-
import { useRef } from 'react'
|
|
17
|
+
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
18
|
+
import { isWeb } from '@tamagui/constants'
|
|
7
19
|
import type {
|
|
8
20
|
KeyboardControllerSheetOptions,
|
|
9
21
|
KeyboardControllerSheetResult,
|
|
10
22
|
} from './types'
|
|
11
|
-
|
|
12
|
-
|
|
23
|
+
import {
|
|
24
|
+
getWebKeyboardHeight,
|
|
25
|
+
isEditableElement,
|
|
26
|
+
MIN_KEYBOARD_HEIGHT,
|
|
27
|
+
} from './webViewport'
|
|
13
28
|
|
|
14
29
|
export function useKeyboardControllerSheet(
|
|
15
|
-
|
|
30
|
+
options: KeyboardControllerSheetOptions
|
|
16
31
|
): KeyboardControllerSheetResult {
|
|
32
|
+
const { enabled } = options
|
|
33
|
+
|
|
34
|
+
const [keyboardHeight, setKeyboardHeight] = useState(0)
|
|
35
|
+
const [isKeyboardVisible, setIsKeyboardVisible] = useState(false)
|
|
36
|
+
|
|
37
|
+
// action-sheet pattern: pause keyboard hide events during drag so the sheet
|
|
38
|
+
// position doesn't revert mid-gesture when a TextInput blurs.
|
|
17
39
|
const pauseKeyboardHandler = useRef(false)
|
|
40
|
+
const pendingHide = useRef(false)
|
|
41
|
+
// live mirror of isKeyboardVisible so the listener can read it without
|
|
42
|
+
// re-subscribing on every toggle.
|
|
43
|
+
const isVisibleRef = useRef(false)
|
|
44
|
+
isVisibleRef.current = isKeyboardVisible
|
|
45
|
+
|
|
46
|
+
const dismissKeyboard = useCallback(() => {
|
|
47
|
+
if (typeof document === 'undefined') return
|
|
48
|
+
const active = document.activeElement as HTMLElement | null
|
|
49
|
+
if (isEditableElement(active)) {
|
|
50
|
+
active?.blur?.()
|
|
51
|
+
}
|
|
52
|
+
}, [])
|
|
53
|
+
|
|
54
|
+
const flushPendingHide = useCallback(() => {
|
|
55
|
+
if (pendingHide.current) {
|
|
56
|
+
pendingHide.current = false
|
|
57
|
+
setIsKeyboardVisible(false)
|
|
58
|
+
setKeyboardHeight(0)
|
|
59
|
+
}
|
|
60
|
+
}, [])
|
|
61
|
+
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!isWeb || !enabled) return
|
|
64
|
+
if (typeof window === 'undefined') return
|
|
65
|
+
const vv = window.visualViewport
|
|
66
|
+
if (!vv) return
|
|
67
|
+
|
|
68
|
+
const update = () => {
|
|
69
|
+
const height = getWebKeyboardHeight()
|
|
70
|
+
const tall = height >= MIN_KEYBOARD_HEIGHT
|
|
71
|
+
// require an editable element focused to *show* — this rules out URL-bar
|
|
72
|
+
// collapse and other viewport changes that aren't a keyboard. but stay
|
|
73
|
+
// visible while the viewport remains shrunk even if focus momentarily
|
|
74
|
+
// moves to a non-editable element (e.g. tapping between two inputs fires
|
|
75
|
+
// focusout→focusin), so the sheet doesn't flicker mid-transition.
|
|
76
|
+
const editableFocused = isEditableElement(document.activeElement)
|
|
77
|
+
const visible = tall && (editableFocused || isVisibleRef.current)
|
|
78
|
+
|
|
79
|
+
if (!visible) {
|
|
80
|
+
// suppress hide during an active drag so positions stay frozen; the
|
|
81
|
+
// drag-end flush reconciles the real state.
|
|
82
|
+
if (pauseKeyboardHandler.current && isVisibleRef.current) {
|
|
83
|
+
pendingHide.current = true
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
setIsKeyboardVisible(false)
|
|
87
|
+
setKeyboardHeight(0)
|
|
88
|
+
return
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
pendingHide.current = false
|
|
92
|
+
setIsKeyboardVisible(true)
|
|
93
|
+
setKeyboardHeight((prev) => (prev === height ? prev : height))
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// only react to resize (keyboard height changes). we intentionally do NOT
|
|
97
|
+
// listen to visualViewport 'scroll' — that fires continuously while the
|
|
98
|
+
// sheet content scrolls and would re-derive the keyboard height from a
|
|
99
|
+
// shifting viewport, making the sheet jump.
|
|
100
|
+
vv.addEventListener('resize', update)
|
|
101
|
+
// focus changes flip editable state without necessarily resizing the viewport
|
|
102
|
+
window.addEventListener('focusin', update)
|
|
103
|
+
window.addEventListener('focusout', update)
|
|
104
|
+
|
|
105
|
+
update()
|
|
106
|
+
|
|
107
|
+
return () => {
|
|
108
|
+
vv.removeEventListener('resize', update)
|
|
109
|
+
window.removeEventListener('focusin', update)
|
|
110
|
+
window.removeEventListener('focusout', update)
|
|
111
|
+
}
|
|
112
|
+
}, [enabled])
|
|
113
|
+
|
|
18
114
|
return {
|
|
19
115
|
keyboardControllerEnabled: false,
|
|
20
|
-
keyboardHeight
|
|
21
|
-
isKeyboardVisible
|
|
22
|
-
dismissKeyboard
|
|
116
|
+
keyboardHeight,
|
|
117
|
+
isKeyboardVisible,
|
|
118
|
+
dismissKeyboard,
|
|
23
119
|
pauseKeyboardHandler,
|
|
24
|
-
flushPendingHide
|
|
120
|
+
flushPendingHide,
|
|
25
121
|
}
|
|
26
122
|
}
|
|
@@ -22,6 +22,10 @@ export type SheetControllerContextValue = {
|
|
|
22
22
|
// hide without "closing" to prevent re-animation when shown again
|
|
23
23
|
hidden?: boolean
|
|
24
24
|
onOpenChange?: React.Dispatch<React.SetStateAction<boolean>> | ((val: boolean) => void)
|
|
25
|
+
// fired by the sheet after its open/close animation finishes. used by
|
|
26
|
+
// Dialog adapt to know when it's safe to tear down adapted children
|
|
27
|
+
// without cutting off the slide-out mid-animation.
|
|
28
|
+
onAnimationComplete?: (state: { open: boolean }) => void
|
|
25
29
|
// when true, the sheet should skip its open animation (used for adapt handoff)
|
|
26
30
|
skipNextAnimation?: boolean
|
|
27
31
|
}
|
|
@@ -8,6 +8,23 @@ import type { ScrollBridge, SheetProps } from './types'
|
|
|
8
8
|
import type { SheetOpenState } from './useSheetOpenState'
|
|
9
9
|
|
|
10
10
|
export type SheetContextValue = ReturnType<typeof useSheetProviderProps> & {
|
|
11
|
+
keyboardOccludedHeight: number
|
|
12
|
+
// whether the soft keyboard is currently open. distinct from
|
|
13
|
+
// keyboardOccludedHeight (which is 0 once the sheet fits above the keyboard):
|
|
14
|
+
// the fit-mode height freeze must persist for the whole time the keyboard is
|
|
15
|
+
// open, not just while occluded, or it releases and the sheet collapses.
|
|
16
|
+
isKeyboardVisible: boolean
|
|
17
|
+
// the sheet's authoritative pre-keyboard frame height (web). SheetScrollView
|
|
18
|
+
// pins its height to this while the keyboard is open so the frame stays its
|
|
19
|
+
// full size (anchored to the screen bottom) instead of collapsing to a
|
|
20
|
+
// consumer maxHeight that shrank with the viewport. 0 when not applicable.
|
|
21
|
+
keyboardStableFrameHeight: number
|
|
22
|
+
// AUTOFOCUS-ON-OPEN seed phase (web). while reconstructing the pre-keyboard
|
|
23
|
+
// baseline, SheetScrollView must UNCLIP (apply keyboardStableFrameHeight as
|
|
24
|
+
// maxHeight only, not a fixed height) so it sizes to its content and the sheet
|
|
25
|
+
// can measure the true content height. once settled the fixed-height pin
|
|
26
|
+
// applies. false outside the seed window.
|
|
27
|
+
isKeyboardSeeding: boolean
|
|
11
28
|
setHasScrollView: (val: boolean) => void
|
|
12
29
|
}
|
|
13
30
|
|
|
@@ -75,6 +75,10 @@ export function useSheetScrollViewGestures({
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
scrollBridge.scrollStartY = touch.pageY
|
|
78
|
+
// claim this touch for the scroll-view gesture hook so the PanResponder
|
|
79
|
+
// (which also negotiates this touch via RNW's responder system) defers
|
|
80
|
+
// and doesn't double-drive the sheet position. cleared on touchend.
|
|
81
|
+
scrollBridge.scrollNodeTouched = true
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
const handleTouchMove = (e: TouchEvent) => {
|
|
@@ -115,6 +119,10 @@ export function useSheetScrollViewGestures({
|
|
|
115
119
|
if (newOwner === 'pan') {
|
|
116
120
|
s.panDragOffset = 0
|
|
117
121
|
s.dys = []
|
|
122
|
+
// re-baseline the pan origin to the sheet's CURRENT position so the
|
|
123
|
+
// offset (reset to 0 here) maps to where it actually is — required for
|
|
124
|
+
// a correct scroll→pan handoff now that the PanResponder defers to us.
|
|
125
|
+
scrollBridge.startPanDrag?.()
|
|
118
126
|
scrollBridge.setParentDragging(true)
|
|
119
127
|
disableScroll()
|
|
120
128
|
} else {
|
|
@@ -133,8 +141,13 @@ export function useSheetScrollViewGestures({
|
|
|
133
141
|
|
|
134
142
|
s.dys.push(dy)
|
|
135
143
|
if (s.dys.length > 100) s.dys = s.dys.slice(-10)
|
|
136
|
-
} else if (s.owner === 'scroll') {
|
|
137
|
-
//
|
|
144
|
+
} else if (s.owner === 'scroll' && !e.isTrusted) {
|
|
145
|
+
// SYNTHETIC events only (tests): dispatched TouchEvents don't trigger the
|
|
146
|
+
// browser's native overflow scroll, so we move scrollTop ourselves. for a
|
|
147
|
+
// REAL touch (e.isTrusted) the browser already scrolls the overflow
|
|
148
|
+
// container natively — doing it again here double-applies the delta and
|
|
149
|
+
// makes scrollTop jitter / snap around. so for real touches we let native
|
|
150
|
+
// scrolling own it and only track the offset via the ScrollView onScroll.
|
|
138
151
|
const scrollDelta = -dy
|
|
139
152
|
const maxScrollY = node.scrollHeight - node.clientHeight
|
|
140
153
|
const newScrollY = Math.max(0, Math.min(maxScrollY, currentScrollY + scrollDelta))
|
|
@@ -159,12 +172,20 @@ export function useSheetScrollViewGestures({
|
|
|
159
172
|
}
|
|
160
173
|
|
|
161
174
|
scrollBridge.release({ dragAt: s.panDragOffset, vy })
|
|
175
|
+
} else if (s.owner === 'scroll') {
|
|
176
|
+
// gesture ended while scrolling. a pan→scroll handoff only happens once
|
|
177
|
+
// the pane reached the top, so commit the top snap (index 0) and clear
|
|
178
|
+
// the dragging state HERE, on touchend — never mid-gesture (that would
|
|
179
|
+
// fight the live gesture). this replaces the PanResponder's release,
|
|
180
|
+
// which used to fire on touchend before it deferred to this hook.
|
|
181
|
+
scrollBridge.snapToPosition?.(0)
|
|
162
182
|
}
|
|
163
183
|
|
|
164
184
|
enableScroll()
|
|
165
185
|
s.owner = 'none'
|
|
166
186
|
s.panDragOffset = 0
|
|
167
187
|
s.dys = []
|
|
188
|
+
scrollBridge.scrollNodeTouched = false
|
|
168
189
|
}
|
|
169
190
|
|
|
170
191
|
node.addEventListener('touchstart', handleTouchStart, {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web (mobile-browser) viewport helpers for the Sheet's keyboard handling.
|
|
3
|
+
*
|
|
4
|
+
* On real iOS Safari (verified on-device, iOS 26) the soft keyboard shrinks
|
|
5
|
+
* BOTH `window.visualViewport.height` AND `window.innerHeight` — neither is the
|
|
6
|
+
* stable layout viewport. Measured during a keyboard open: visualViewport
|
|
7
|
+
* 714 -> 404, innerHeight 714 -> 561 (it wobbles), but
|
|
8
|
+
* `document.documentElement.clientHeight` holds rock-steady at 714 the whole
|
|
9
|
+
* time (open, mid-keyboard, and close). So clientHeight IS the stable layout
|
|
10
|
+
* viewport, and we derive everything from it:
|
|
11
|
+
* - soft-keyboard height = clientHeight - visualViewport.height (stays correct
|
|
12
|
+
* even as innerHeight drifts), so the scroll padding clears the input.
|
|
13
|
+
* - the sheet's fit-mode anchor cap (translateY = screenSize - frameSize) reads
|
|
14
|
+
* clientHeight, so it never re-measures against a shrunk value and the frame
|
|
15
|
+
* stays anchored at the bottom.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// ignore small viewport changes (URL bar collapse, accessory bars) so they
|
|
19
|
+
// don't read as a full keyboard. a real soft keyboard is well above this.
|
|
20
|
+
export const MIN_KEYBOARD_HEIGHT = 80
|
|
21
|
+
|
|
22
|
+
export function isEditableElement(el: Element | null): boolean {
|
|
23
|
+
if (!el) return false
|
|
24
|
+
const tag = el.tagName
|
|
25
|
+
if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true
|
|
26
|
+
if ((el as HTMLElement).isContentEditable) return true
|
|
27
|
+
return false
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The stable layout-viewport height. document.documentElement.clientHeight is
|
|
32
|
+
* unaffected by the soft keyboard on iOS Safari (unlike innerHeight /
|
|
33
|
+
* visualViewport), so it stays constant while the keyboard animates in/out.
|
|
34
|
+
*/
|
|
35
|
+
export function getStableLayoutViewportHeight(): number {
|
|
36
|
+
if (typeof window === 'undefined') return 0
|
|
37
|
+
const ch = typeof document !== 'undefined' ? document.documentElement?.clientHeight : 0
|
|
38
|
+
if (ch && ch > 0) return ch
|
|
39
|
+
// fallback when clientHeight is unavailable (SSR / detached): best effort
|
|
40
|
+
return Math.max(window.innerHeight || 0, window.visualViewport?.height || 0)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Soft-keyboard height = the occluded region between the (stable) layout
|
|
45
|
+
* viewport bottom and the visual viewport bottom.
|
|
46
|
+
*/
|
|
47
|
+
export function getWebKeyboardHeight(): number {
|
|
48
|
+
if (typeof window === 'undefined') return 0
|
|
49
|
+
const vv = window.visualViewport
|
|
50
|
+
if (!vv) return 0
|
|
51
|
+
return Math.max(0, Math.round(getStableLayoutViewportHeight() - vv.height))
|
|
52
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { getKeyboardOccludedHeight } from '../src/keyboardAvoidance'
|
|
4
|
+
|
|
5
|
+
describe('getKeyboardOccludedHeight', () => {
|
|
6
|
+
const base = {
|
|
7
|
+
frameSize: 700,
|
|
8
|
+
isKeyboardVisible: true,
|
|
9
|
+
keyboardHeight: 300,
|
|
10
|
+
screenSize: 844,
|
|
11
|
+
sheetY: 59,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
test('returns overflow below the keyboard top after the sheet is clamped', () => {
|
|
15
|
+
expect(getKeyboardOccludedHeight(base)).toBe(215)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('returns zero when the keyboard-adjusted sheet clears the keyboard', () => {
|
|
19
|
+
expect(
|
|
20
|
+
getKeyboardOccludedHeight({
|
|
21
|
+
...base,
|
|
22
|
+
frameSize: 400,
|
|
23
|
+
sheetY: 144,
|
|
24
|
+
})
|
|
25
|
+
).toBe(0)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('ignores hidden keyboard and offscreen sheet positions', () => {
|
|
29
|
+
expect(
|
|
30
|
+
getKeyboardOccludedHeight({
|
|
31
|
+
...base,
|
|
32
|
+
isKeyboardVisible: false,
|
|
33
|
+
})
|
|
34
|
+
).toBe(0)
|
|
35
|
+
expect(
|
|
36
|
+
getKeyboardOccludedHeight({
|
|
37
|
+
...base,
|
|
38
|
+
sheetY: base.screenSize,
|
|
39
|
+
})
|
|
40
|
+
).toBe(0)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('clamps occlusion to the frame height', () => {
|
|
44
|
+
expect(
|
|
45
|
+
getKeyboardOccludedHeight({
|
|
46
|
+
...base,
|
|
47
|
+
frameSize: 120,
|
|
48
|
+
keyboardHeight: 1000,
|
|
49
|
+
sheetY: 0,
|
|
50
|
+
})
|
|
51
|
+
).toBe(120)
|
|
52
|
+
})
|
|
53
|
+
})
|