@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,195 @@
|
|
|
1
|
+
import { composeRefs } from '@hanzogui/compose-refs'
|
|
2
|
+
import { isWeb, View, type GetRef } from '@hanzogui/core'
|
|
3
|
+
import type { ScrollViewProps } from '@hanzogui/scroll-view'
|
|
4
|
+
import { ScrollView } from '@hanzogui/scroll-view'
|
|
5
|
+
import { useControllableState } from '@hanzogui/use-controllable-state'
|
|
6
|
+
import React, { useEffect, useRef, useState } from 'react'
|
|
7
|
+
import type { ScrollView as RNScrollView } from 'react-native'
|
|
8
|
+
import { useGestureSheetContext } from './GestureSheetContext'
|
|
9
|
+
import { getGestureHandlerState, isGestureHandlerEnabled } from './gestureState'
|
|
10
|
+
import { useSheetContext } from './SheetContext'
|
|
11
|
+
import type { SheetScopedProps } from './types'
|
|
12
|
+
import { useSheetScrollViewGestures } from './useSheetScrollViewGestures'
|
|
13
|
+
|
|
14
|
+
const SHEET_SCROLL_VIEW_NAME = 'SheetScrollView'
|
|
15
|
+
|
|
16
|
+
export const SheetScrollView = React.forwardRef<
|
|
17
|
+
GetRef<typeof ScrollView>,
|
|
18
|
+
ScrollViewProps
|
|
19
|
+
>(
|
|
20
|
+
(
|
|
21
|
+
{
|
|
22
|
+
__scopeSheet,
|
|
23
|
+
children,
|
|
24
|
+
onScroll,
|
|
25
|
+
scrollEnabled: scrollEnabledProp,
|
|
26
|
+
...props
|
|
27
|
+
}: SheetScopedProps<ScrollViewProps>,
|
|
28
|
+
ref
|
|
29
|
+
) => {
|
|
30
|
+
const context = useSheetContext(SHEET_SCROLL_VIEW_NAME, __scopeSheet)
|
|
31
|
+
const gestureContext = useGestureSheetContext()
|
|
32
|
+
const { scrollBridge, setHasScrollView } = context
|
|
33
|
+
const [scrollEnabled] = useControllableState({
|
|
34
|
+
prop: scrollEnabledProp,
|
|
35
|
+
defaultProp: true,
|
|
36
|
+
})
|
|
37
|
+
const scrollRef = React.useRef<RNScrollView | null>(null)
|
|
38
|
+
|
|
39
|
+
const panGestureRef = gestureContext?.panGestureRef
|
|
40
|
+
const { ScrollView: RNGHScrollView } = getGestureHandlerState()
|
|
41
|
+
const useRNGHScrollView = isGestureHandlerEnabled() && RNGHScrollView && panGestureRef
|
|
42
|
+
|
|
43
|
+
// RNGH scroll locking state
|
|
44
|
+
const currentScrollOffset = useRef(0)
|
|
45
|
+
const lockedScrollY = useRef(0)
|
|
46
|
+
|
|
47
|
+
const setScrollEnabled = (next: boolean, lockTo?: number) => {
|
|
48
|
+
if (!next) {
|
|
49
|
+
const lockY = lockTo ?? currentScrollOffset.current
|
|
50
|
+
lockedScrollY.current = lockY
|
|
51
|
+
scrollBridge.scrollLockY = lockY
|
|
52
|
+
scrollRef.current?.scrollTo?.({ x: 0, y: lockY, animated: false })
|
|
53
|
+
} else {
|
|
54
|
+
lockedScrollY.current = currentScrollOffset.current
|
|
55
|
+
scrollBridge.scrollLockY = undefined
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const forceScrollTo = (y: number) => {
|
|
60
|
+
scrollRef.current?.scrollTo?.({ x: 0, y, animated: false })
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
setHasScrollView(true)
|
|
65
|
+
if (isGestureHandlerEnabled()) {
|
|
66
|
+
scrollBridge.setScrollEnabled = setScrollEnabled
|
|
67
|
+
scrollBridge.forceScrollTo = forceScrollTo
|
|
68
|
+
}
|
|
69
|
+
return () => {
|
|
70
|
+
setHasScrollView(false)
|
|
71
|
+
scrollBridge.setScrollEnabled = undefined
|
|
72
|
+
scrollBridge.forceScrollTo = undefined
|
|
73
|
+
}
|
|
74
|
+
}, [])
|
|
75
|
+
|
|
76
|
+
const [hasScrollableContent, setHasScrollableContent] = useState(true)
|
|
77
|
+
const parentHeight = useRef(0)
|
|
78
|
+
const contentHeight = useRef(0)
|
|
79
|
+
|
|
80
|
+
const updateScrollable = () => {
|
|
81
|
+
if (parentHeight.current && contentHeight.current) {
|
|
82
|
+
setHasScrollableContent(contentHeight.current > parentHeight.current)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
scrollBridge.hasScrollableContent = hasScrollableContent
|
|
88
|
+
}, [hasScrollableContent])
|
|
89
|
+
|
|
90
|
+
// platform-specific gesture handling
|
|
91
|
+
const gestureProps = useSheetScrollViewGestures({
|
|
92
|
+
scrollRef,
|
|
93
|
+
scrollBridge,
|
|
94
|
+
hasScrollableContent,
|
|
95
|
+
scrollEnabled,
|
|
96
|
+
setScrollEnabled,
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
// content wrapper for measuring height
|
|
100
|
+
const contentWrapper = (
|
|
101
|
+
<View
|
|
102
|
+
onLayout={(e) => {
|
|
103
|
+
const height = Math.floor(e.nativeEvent.layout.height)
|
|
104
|
+
if (height !== contentHeight.current) {
|
|
105
|
+
contentHeight.current = height
|
|
106
|
+
updateScrollable()
|
|
107
|
+
}
|
|
108
|
+
}}
|
|
109
|
+
>
|
|
110
|
+
{children}
|
|
111
|
+
</View>
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
// RNGH ScrollView path
|
|
115
|
+
if (useRNGHScrollView && RNGHScrollView && panGestureRef) {
|
|
116
|
+
const RNGHComponent = RNGHScrollView as any
|
|
117
|
+
return (
|
|
118
|
+
<RNGHComponent
|
|
119
|
+
ref={composeRefs(scrollRef as any, ref)}
|
|
120
|
+
style={{ flex: 1 }}
|
|
121
|
+
scrollEventThrottle={1}
|
|
122
|
+
scrollEnabled={scrollEnabled}
|
|
123
|
+
simultaneousHandlers={[panGestureRef]}
|
|
124
|
+
onLayout={(e: any) => {
|
|
125
|
+
parentHeight.current = Math.ceil(e.nativeEvent.layout.height)
|
|
126
|
+
updateScrollable()
|
|
127
|
+
}}
|
|
128
|
+
onScroll={(e: any) => {
|
|
129
|
+
const { y } = e.nativeEvent.contentOffset
|
|
130
|
+
currentScrollOffset.current = y
|
|
131
|
+
|
|
132
|
+
if (scrollBridge.scrollLockY !== undefined) {
|
|
133
|
+
if (y !== scrollBridge.scrollLockY) {
|
|
134
|
+
scrollRef.current?.scrollTo?.({
|
|
135
|
+
x: 0,
|
|
136
|
+
y: scrollBridge.scrollLockY,
|
|
137
|
+
animated: false,
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
scrollBridge.y = scrollBridge.scrollLockY
|
|
141
|
+
onScroll?.({
|
|
142
|
+
...e,
|
|
143
|
+
nativeEvent: {
|
|
144
|
+
...e.nativeEvent,
|
|
145
|
+
contentOffset: {
|
|
146
|
+
...e.nativeEvent.contentOffset,
|
|
147
|
+
y: scrollBridge.scrollLockY,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
})
|
|
151
|
+
return
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
scrollBridge.y = y
|
|
155
|
+
if (y > 0) scrollBridge.scrollStartY = -1
|
|
156
|
+
onScroll?.(e)
|
|
157
|
+
}}
|
|
158
|
+
contentContainerStyle={{ minHeight: '100%' }}
|
|
159
|
+
bounces={false}
|
|
160
|
+
keyboardShouldPersistTaps="always"
|
|
161
|
+
keyboardDismissMode="none"
|
|
162
|
+
{...props}
|
|
163
|
+
>
|
|
164
|
+
{contentWrapper}
|
|
165
|
+
</RNGHComponent>
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// fallback ScrollView with platform-specific gesture props
|
|
170
|
+
return (
|
|
171
|
+
<ScrollView
|
|
172
|
+
onLayout={(e) => {
|
|
173
|
+
parentHeight.current = Math.ceil(e.nativeEvent.layout.height)
|
|
174
|
+
updateScrollable()
|
|
175
|
+
}}
|
|
176
|
+
ref={composeRefs(scrollRef as any, ref)}
|
|
177
|
+
flex={1}
|
|
178
|
+
scrollEventThrottle={1}
|
|
179
|
+
className="_ovs-contain"
|
|
180
|
+
scrollEnabled={scrollEnabled}
|
|
181
|
+
onScroll={(e) => {
|
|
182
|
+
const { y } = e.nativeEvent.contentOffset
|
|
183
|
+
scrollBridge.y = y
|
|
184
|
+
if (y > 0) scrollBridge.scrollStartY = -1
|
|
185
|
+
onScroll?.(e)
|
|
186
|
+
}}
|
|
187
|
+
contentContainerStyle={{ minHeight: '100%' }}
|
|
188
|
+
{...gestureProps}
|
|
189
|
+
{...props}
|
|
190
|
+
>
|
|
191
|
+
{contentWrapper}
|
|
192
|
+
</ScrollView>
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
)
|
package/src/contexts.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Lightweight controller exports - no styled components
|
|
2
|
+
// Use this entry point when you only need SheetController without the full Sheet
|
|
3
|
+
|
|
4
|
+
export { SheetController } from './SheetController'
|
|
5
|
+
export {
|
|
6
|
+
SheetControllerContext,
|
|
7
|
+
useSheetController,
|
|
8
|
+
type SheetControllerContextValue,
|
|
9
|
+
} from './useSheetController'
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { useComposedRefs } from '@hanzogui/compose-refs'
|
|
2
|
+
import { useIsomorphicLayoutEffect } from '@hanzogui/constants'
|
|
3
|
+
import type {
|
|
4
|
+
GetProps,
|
|
5
|
+
ViewProps,
|
|
6
|
+
GuiComponent,
|
|
7
|
+
GuiComponentExpectingVariants,
|
|
8
|
+
GuiElement,
|
|
9
|
+
} from '@hanzogui/core'
|
|
10
|
+
import { View } from '@hanzogui/core'
|
|
11
|
+
import { composeEventHandlers, withStaticProperties } from '@hanzogui/helpers'
|
|
12
|
+
import { resolveViewZIndex } from '@hanzogui/portal'
|
|
13
|
+
import { RemoveScroll } from '@hanzogui/remove-scroll'
|
|
14
|
+
import { useDidFinishSSR } from '@hanzogui/use-did-finish-ssr'
|
|
15
|
+
import { StackZIndexContext } from '@hanzogui/z-index-stack'
|
|
16
|
+
import type { ForwardRefExoticComponent, FunctionComponent, RefAttributes } from 'react'
|
|
17
|
+
import { forwardRef, memo, useMemo, useEffect, useRef } from 'react'
|
|
18
|
+
import type { View as RNView } from 'react-native'
|
|
19
|
+
import { Platform } from 'react-native'
|
|
20
|
+
import { SHEET_HANDLE_NAME, SHEET_NAME, SHEET_OVERLAY_NAME } from './constants'
|
|
21
|
+
import { getNativeSheet } from './nativeSheet'
|
|
22
|
+
import { useSheetContext } from './SheetContext'
|
|
23
|
+
import { SheetImplementationCustom } from './SheetImplementationCustom'
|
|
24
|
+
import { SheetScrollView } from './SheetScrollView'
|
|
25
|
+
import type { SheetProps, SheetScopedProps } from './types'
|
|
26
|
+
import { useSheetController } from './useSheetController'
|
|
27
|
+
import { useSheetOffscreenSize } from './useSheetOffscreenSize'
|
|
28
|
+
|
|
29
|
+
type SharedSheetProps = {
|
|
30
|
+
open?: boolean
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type BaseProps = ViewProps & SharedSheetProps
|
|
34
|
+
|
|
35
|
+
type SheetStyledComponent = GuiComponentExpectingVariants<BaseProps, SharedSheetProps>
|
|
36
|
+
|
|
37
|
+
export function createSheet<
|
|
38
|
+
H extends GuiComponent | SheetStyledComponent,
|
|
39
|
+
F extends GuiComponent | SheetStyledComponent,
|
|
40
|
+
O extends GuiComponent | SheetStyledComponent,
|
|
41
|
+
>({ Handle, Frame, Overlay }: { Handle: H; Frame: F; Overlay: O }) {
|
|
42
|
+
const SheetHandle = Handle.styleable<any>(
|
|
43
|
+
(
|
|
44
|
+
{ __scopeSheet, ...props }: SheetScopedProps<SheetStyledComponent>,
|
|
45
|
+
forwardedRef
|
|
46
|
+
) => {
|
|
47
|
+
const context = useSheetContext(SHEET_HANDLE_NAME, __scopeSheet)
|
|
48
|
+
const composedRef = useComposedRefs<GuiElement>(context.handleRef, forwardedRef)
|
|
49
|
+
|
|
50
|
+
// track if sheet was being dragged to prevent onPress toggle after drag
|
|
51
|
+
const wasDraggingRef = useRef(false)
|
|
52
|
+
|
|
53
|
+
// subscribe to parent dragging changes to track if we dragged during this press
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (!context.scrollBridge) return
|
|
56
|
+
return context.scrollBridge.onParentDragging((isDragging: boolean) => {
|
|
57
|
+
if (isDragging) {
|
|
58
|
+
wasDraggingRef.current = true
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
}, [context.scrollBridge])
|
|
62
|
+
|
|
63
|
+
if (context.onlyShowFrame) {
|
|
64
|
+
return null
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
<Handle
|
|
70
|
+
ref={composedRef}
|
|
71
|
+
onPressIn={() => {
|
|
72
|
+
// reset at start of new press
|
|
73
|
+
wasDraggingRef.current = false
|
|
74
|
+
}}
|
|
75
|
+
onPress={() => {
|
|
76
|
+
// skip toggle if this was a drag gesture
|
|
77
|
+
if (wasDraggingRef.current) {
|
|
78
|
+
wasDraggingRef.current = false
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
// don't toggle to the bottom snap position when dismissOnSnapToBottom set
|
|
82
|
+
const max =
|
|
83
|
+
context.snapPoints.length + (context.dismissOnSnapToBottom ? -1 : 0)
|
|
84
|
+
const nextPos = (context.position + 1) % max
|
|
85
|
+
context.setPosition(nextPos)
|
|
86
|
+
}}
|
|
87
|
+
open={context.open}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
/* -------------------------------------------------------------------------------------------------
|
|
95
|
+
* SheetOverlay
|
|
96
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
97
|
+
|
|
98
|
+
const SheetOverlay = Overlay.styleable<SheetScopedProps<{}>>((propsIn, ref) => {
|
|
99
|
+
const { __scopeSheet, ...props } = propsIn
|
|
100
|
+
const context = useSheetContext(SHEET_OVERLAY_NAME, __scopeSheet)
|
|
101
|
+
|
|
102
|
+
// this ones a bit weird for legacy reasons, we need to hoist it above <Sheet /> AnimatedView
|
|
103
|
+
// so we just pass it up to context
|
|
104
|
+
|
|
105
|
+
const element = useMemo(() => {
|
|
106
|
+
return (
|
|
107
|
+
// @ts-ignore
|
|
108
|
+
<Overlay
|
|
109
|
+
{...props}
|
|
110
|
+
onPress={composeEventHandlers(
|
|
111
|
+
props.onPress,
|
|
112
|
+
context.dismissOnOverlayPress
|
|
113
|
+
? () => {
|
|
114
|
+
context.setOpen(false)
|
|
115
|
+
}
|
|
116
|
+
: undefined
|
|
117
|
+
)}
|
|
118
|
+
/>
|
|
119
|
+
)
|
|
120
|
+
}, [props.onPress, props.opacity, context.dismissOnOverlayPress])
|
|
121
|
+
|
|
122
|
+
useIsomorphicLayoutEffect(() => {
|
|
123
|
+
context.onOverlayComponent?.(element)
|
|
124
|
+
}, [element])
|
|
125
|
+
|
|
126
|
+
if (context.onlyShowFrame) {
|
|
127
|
+
return null
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return null
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
/* -------------------------------------------------------------------------------------------------
|
|
134
|
+
* Sheet
|
|
135
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
136
|
+
|
|
137
|
+
type ExtraFrameProps = {
|
|
138
|
+
/**
|
|
139
|
+
* By default the sheet adds a view below its bottom that extends down another 50%,
|
|
140
|
+
* this is useful if your Sheet has a spring animation that bounces "past" the top when
|
|
141
|
+
* opening, preventing it from showing the content underneath.
|
|
142
|
+
*/
|
|
143
|
+
disableHideBottomOverflow?: boolean
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Adds padding accounting for the currently offscreen content, so if you put a flex element inside
|
|
147
|
+
* the sheet, it will always flex to the height of the visible amount of the sheet. If this is not
|
|
148
|
+
* turned on, the inner content is always set to the max height of the sheet.
|
|
149
|
+
*/
|
|
150
|
+
adjustPaddingForOffscreenContent?: boolean
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const SheetFrame = Frame.styleable<SheetProps & ExtraFrameProps>(
|
|
154
|
+
(
|
|
155
|
+
{
|
|
156
|
+
__scopeSheet,
|
|
157
|
+
adjustPaddingForOffscreenContent,
|
|
158
|
+
disableHideBottomOverflow,
|
|
159
|
+
children,
|
|
160
|
+
...props
|
|
161
|
+
},
|
|
162
|
+
forwardedRef
|
|
163
|
+
) => {
|
|
164
|
+
const context = useSheetContext(SHEET_NAME, __scopeSheet)
|
|
165
|
+
const { hasFit, disableRemoveScroll, frameSize, contentRef, open } = context
|
|
166
|
+
const composedContentRef = useComposedRefs(forwardedRef, contentRef)
|
|
167
|
+
const offscreenSize = useSheetOffscreenSize(context)
|
|
168
|
+
|
|
169
|
+
// FIX: Store the frameSize when open for use during close animation
|
|
170
|
+
const stableFrameSize = useRef(frameSize)
|
|
171
|
+
useEffect(() => {
|
|
172
|
+
if (open && frameSize) {
|
|
173
|
+
stableFrameSize.current = frameSize
|
|
174
|
+
}
|
|
175
|
+
}, [open, frameSize])
|
|
176
|
+
|
|
177
|
+
const sheetContents = useMemo(() => {
|
|
178
|
+
// FIX: Use fixed height during close animation to prevent content-driven resizing
|
|
179
|
+
const shouldUseFixedHeight = hasFit && !open && stableFrameSize.current
|
|
180
|
+
|
|
181
|
+
return (
|
|
182
|
+
// @ts-expect-error
|
|
183
|
+
<Frame
|
|
184
|
+
ref={composedContentRef}
|
|
185
|
+
flex={hasFit && open ? 0 : 1}
|
|
186
|
+
flexBasis={hasFit ? 'auto' : undefined}
|
|
187
|
+
height={
|
|
188
|
+
shouldUseFixedHeight
|
|
189
|
+
? stableFrameSize.current
|
|
190
|
+
: hasFit
|
|
191
|
+
? undefined
|
|
192
|
+
: frameSize
|
|
193
|
+
}
|
|
194
|
+
pointerEvents={open ? 'auto' : 'none'}
|
|
195
|
+
data-state={open ? 'open' : 'closed'}
|
|
196
|
+
{...props}
|
|
197
|
+
>
|
|
198
|
+
<StackZIndexContext zIndex={resolveViewZIndex(props.zIndex)}>
|
|
199
|
+
{children}
|
|
200
|
+
</StackZIndexContext>
|
|
201
|
+
|
|
202
|
+
{adjustPaddingForOffscreenContent && (
|
|
203
|
+
<View data-sheet-offscreen-pad height={offscreenSize} width="100%" />
|
|
204
|
+
)}
|
|
205
|
+
</Frame>
|
|
206
|
+
)
|
|
207
|
+
}, [
|
|
208
|
+
open,
|
|
209
|
+
props,
|
|
210
|
+
frameSize,
|
|
211
|
+
offscreenSize,
|
|
212
|
+
adjustPaddingForOffscreenContent,
|
|
213
|
+
hasFit,
|
|
214
|
+
])
|
|
215
|
+
|
|
216
|
+
return (
|
|
217
|
+
<>
|
|
218
|
+
<RemoveScroll enabled={!disableRemoveScroll && context.open}>
|
|
219
|
+
{sheetContents}
|
|
220
|
+
</RemoveScroll>
|
|
221
|
+
|
|
222
|
+
{/* below frame hide when bouncing past 100% */}
|
|
223
|
+
{!disableHideBottomOverflow && (
|
|
224
|
+
// @ts-ignore
|
|
225
|
+
<Frame
|
|
226
|
+
{...props}
|
|
227
|
+
componentName="SheetCover"
|
|
228
|
+
children={null}
|
|
229
|
+
// Don't inherit testID - this is a visual helper element
|
|
230
|
+
testID={undefined}
|
|
231
|
+
id={undefined}
|
|
232
|
+
position="absolute"
|
|
233
|
+
bottom="-100%"
|
|
234
|
+
zIndex={-1}
|
|
235
|
+
height={context.frameSize}
|
|
236
|
+
left={0}
|
|
237
|
+
right={0}
|
|
238
|
+
borderWidth={0}
|
|
239
|
+
borderRadius={0}
|
|
240
|
+
shadowOpacity={0}
|
|
241
|
+
/>
|
|
242
|
+
)}
|
|
243
|
+
</>
|
|
244
|
+
)
|
|
245
|
+
}
|
|
246
|
+
) as any as ForwardRefExoticComponent<
|
|
247
|
+
SheetScopedProps<
|
|
248
|
+
Omit<GetProps<typeof Frame>, keyof ExtraFrameProps> & ExtraFrameProps
|
|
249
|
+
>
|
|
250
|
+
>
|
|
251
|
+
|
|
252
|
+
const Sheet = forwardRef<RNView, SheetProps>(function Sheet(props, ref) {
|
|
253
|
+
const hydrated = useDidFinishSSR()
|
|
254
|
+
const { isShowingNonSheet } = useSheetController()
|
|
255
|
+
|
|
256
|
+
let SheetImplementation = SheetImplementationCustom
|
|
257
|
+
|
|
258
|
+
if (props.native && Platform.OS === 'ios') {
|
|
259
|
+
if (process.env.HANZO_GUI_TARGET === 'native') {
|
|
260
|
+
const impl = getNativeSheet('ios')
|
|
261
|
+
if (impl) {
|
|
262
|
+
// @ts-expect-error accepting external sheet implementation
|
|
263
|
+
SheetImplementation = impl
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Performance is sensitive here so avoid all the hooks below with this
|
|
270
|
+
*/
|
|
271
|
+
if (isShowingNonSheet || !hydrated) {
|
|
272
|
+
return null
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return <SheetImplementation ref={ref} {...props} />
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
const components = {
|
|
279
|
+
Frame: SheetFrame,
|
|
280
|
+
Overlay: SheetOverlay,
|
|
281
|
+
Handle: SheetHandle,
|
|
282
|
+
ScrollView: SheetScrollView,
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const Controlled = withStaticProperties(Sheet, components) as any as FunctionComponent<
|
|
286
|
+
Omit<SheetProps, 'open' | 'onOpenChange'> & RefAttributes<RNView>
|
|
287
|
+
> &
|
|
288
|
+
typeof components
|
|
289
|
+
|
|
290
|
+
return withStaticProperties(Sheet, {
|
|
291
|
+
...components,
|
|
292
|
+
Controlled,
|
|
293
|
+
})
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/* -------------------------------------------------------------------------------------------------*/
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-export gesture state from @hanzogui/native.
|
|
3
|
+
* Sheet uses this for backward compatibility with existing code.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { getGestureHandler, type GestureState } from '@hanzogui/native'
|
|
7
|
+
|
|
8
|
+
export type { GestureState as GestureHandlerState } from '@hanzogui/native'
|
|
9
|
+
|
|
10
|
+
// backward compat helpers
|
|
11
|
+
export function isGestureHandlerEnabled(): boolean {
|
|
12
|
+
return getGestureHandler().isEnabled
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getGestureHandlerState(): GestureState {
|
|
16
|
+
return getGestureHandler().state
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function setGestureHandlerState(updates: Partial<GestureState>): void {
|
|
20
|
+
getGestureHandler().set(updates)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// alias for backward compatibility
|
|
24
|
+
export const setGestureState = setGestureHandlerState
|
package/src/helpers.tsx
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function resisted(y: number, minY: number, maxOverflow = 25) {
|
|
2
|
+
// If we're not past the boundary, return the original position
|
|
3
|
+
if (y >= minY) {
|
|
4
|
+
return y
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// Calculate how far we've gone past the boundary
|
|
8
|
+
const pastBoundary = minY - y
|
|
9
|
+
|
|
10
|
+
// Use a square root function for very gentle resistance
|
|
11
|
+
// This creates a milder resistance curve than logarithmic
|
|
12
|
+
// Reduced multiplier from 1.5 to 1.0 for even less resistance
|
|
13
|
+
const resistedDistance = Math.sqrt(pastBoundary) * 2
|
|
14
|
+
|
|
15
|
+
// Return the position with resistance applied
|
|
16
|
+
return minY - resistedDistance
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// // set all the way off screen
|
|
20
|
+
// // + 0.1 ensures this is unique - see hasntMeasured ref
|
|
21
|
+
|
|
22
|
+
// let hiddenSize: number
|
|
23
|
+
|
|
24
|
+
// export function getHiddenSize() {
|
|
25
|
+
// if (hiddenSize == undefined) {
|
|
26
|
+
// // this trigger reflow on web avoid doing on startup
|
|
27
|
+
// const screen = Dimensions.get('screen')
|
|
28
|
+
// hiddenSize = Math.max(screen.height, screen.width) + 0.1
|
|
29
|
+
// }
|
|
30
|
+
// return hiddenSize
|
|
31
|
+
// }
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './Sheet'
|
|
2
|
+
export * from './useSheet'
|
|
3
|
+
export * from './createSheet'
|
|
4
|
+
export * from './SheetController'
|
|
5
|
+
export * from './useSheetController'
|
|
6
|
+
export * from './useSheetOpenState'
|
|
7
|
+
export * from './useSheetOffscreenSize'
|
|
8
|
+
export * from './SheetScrollView'
|
|
9
|
+
export * from './nativeSheet'
|
|
10
|
+
export * from './types'
|
|
11
|
+
export * from './contexts'
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { YStack } from '@hanzogui/stacks'
|
|
2
|
+
import type { FunctionComponent } from 'react'
|
|
3
|
+
import { useEffect, useRef } from 'react'
|
|
4
|
+
import { View } from 'react-native'
|
|
5
|
+
import { SheetProvider } from './SheetContext'
|
|
6
|
+
import type { SheetProps } from './types'
|
|
7
|
+
import { useSheetOpenState } from './useSheetOpenState'
|
|
8
|
+
import { useSheetProviderProps } from './useSheetProviderProps'
|
|
9
|
+
|
|
10
|
+
// import { useSheetSnapPoints } from './useSheetSnapPoints'
|
|
11
|
+
|
|
12
|
+
type SheetNativePlatforms = 'ios'
|
|
13
|
+
|
|
14
|
+
const nativeSheets: Record<SheetNativePlatforms, FunctionComponent<SheetProps> | null> = {
|
|
15
|
+
ios: null,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getNativeSheet(platform: SheetNativePlatforms) {
|
|
19
|
+
return nativeSheets[platform]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function setupNativeSheet(
|
|
23
|
+
platform: SheetNativePlatforms,
|
|
24
|
+
RNIOSModal: { ModalSheetView: any; ModalSheetViewMainContent: any }
|
|
25
|
+
) {
|
|
26
|
+
const { ModalSheetView, ModalSheetViewMainContent } = RNIOSModal
|
|
27
|
+
|
|
28
|
+
if (platform === 'ios') {
|
|
29
|
+
nativeSheets[platform] = (props: SheetProps) => {
|
|
30
|
+
const state = useSheetOpenState(props)
|
|
31
|
+
const providerProps = useSheetProviderProps(props, state)
|
|
32
|
+
// const { position } = providerProps
|
|
33
|
+
// const { positions } = useSheetSnapPoints(providerProps)
|
|
34
|
+
|
|
35
|
+
const { open, setOpen } = state
|
|
36
|
+
const ref = useRef<{
|
|
37
|
+
presentModal: Function
|
|
38
|
+
dismissModal: Function
|
|
39
|
+
}>(undefined)
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (open) {
|
|
43
|
+
ref.current?.presentModal()
|
|
44
|
+
} else {
|
|
45
|
+
ref.current?.dismissModal()
|
|
46
|
+
}
|
|
47
|
+
}, [open])
|
|
48
|
+
|
|
49
|
+
function setOpenInternal(next: boolean) {
|
|
50
|
+
props.onOpenChange?.(open)
|
|
51
|
+
setOpen(next)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// modalContentPreferredContentSize={{
|
|
55
|
+
// mode: 'percent',
|
|
56
|
+
// percentWidth: '100%',
|
|
57
|
+
// percentHeight:
|
|
58
|
+
// }}
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<>
|
|
62
|
+
<SheetProvider setHasScrollView={emptyFn} {...providerProps} onlyShowFrame>
|
|
63
|
+
<ModalSheetView ref={ref} onModalDidDismiss={() => setOpenInternal(false)}>
|
|
64
|
+
<ModalSheetViewMainContent>
|
|
65
|
+
<View style={{ flex: 1 }}>{props.children}</View>
|
|
66
|
+
</ModalSheetViewMainContent>
|
|
67
|
+
</ModalSheetView>
|
|
68
|
+
|
|
69
|
+
{/* for some reason select triggers wont show on native if this isn't inside the actual tree not inside implementation... */}
|
|
70
|
+
{/* so just hiding it here for now... not great... */}
|
|
71
|
+
<YStack
|
|
72
|
+
position="absolute"
|
|
73
|
+
opacity={0}
|
|
74
|
+
pointerEvents="none"
|
|
75
|
+
width={0}
|
|
76
|
+
height={0}
|
|
77
|
+
>
|
|
78
|
+
{props.children}
|
|
79
|
+
</YStack>
|
|
80
|
+
</SheetProvider>
|
|
81
|
+
</>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const emptyFn = () => {
|
|
88
|
+
// TODO
|
|
89
|
+
}
|