@tamagui/sheet 3.0.0-beta.924.1 → 3.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/dist/cjs/Sheet.cjs +48 -16
- package/dist/cjs/Sheet.native.cjs +46 -17
- package/dist/cjs/Sheet.native.js +46 -17
- package/dist/cjs/Sheet.native.js.map +1 -1
- package/dist/cjs/SheetDragSurface.cjs +50 -0
- package/dist/{jsx/GestureDetectorWrapper.native.js → cjs/SheetDragSurface.native.cjs} +24 -12
- package/dist/cjs/{GestureDetectorWrapper.native.js → SheetDragSurface.native.js} +25 -11
- package/dist/cjs/SheetDragSurface.native.js.map +1 -0
- package/dist/cjs/SheetImplementationCustom.cjs +41 -58
- package/dist/cjs/SheetImplementationCustom.native.cjs +43 -59
- package/dist/cjs/SheetImplementationCustom.native.js +43 -59
- package/dist/cjs/SheetImplementationCustom.native.js.map +1 -1
- package/dist/cjs/SheetScrollView.cjs +15 -3
- package/dist/cjs/SheetScrollView.native.cjs +17 -4
- package/dist/cjs/SheetScrollView.native.js +17 -4
- package/dist/cjs/SheetScrollView.native.js.map +1 -1
- package/dist/cjs/nativeSheet.cjs +3 -59
- package/dist/cjs/nativeSheet.native.cjs +70 -58
- package/dist/cjs/nativeSheet.native.js +70 -58
- package/dist/cjs/nativeSheet.native.js.map +1 -1
- package/dist/cjs/stableViewportHeight.cjs +27 -0
- package/dist/cjs/stableViewportHeight.native.cjs +29 -0
- package/dist/cjs/stableViewportHeight.native.js +31 -0
- package/dist/cjs/stableViewportHeight.native.js.map +1 -0
- package/dist/cjs/useSheetOffscreenSize.cjs +3 -1
- package/dist/cjs/useSheetOffscreenSize.native.cjs +3 -2
- package/dist/cjs/useSheetOffscreenSize.native.js +3 -2
- package/dist/cjs/useSheetOffscreenSize.native.js.map +1 -1
- package/dist/cjs/useSheetOpenState.cjs +13 -6
- package/dist/cjs/useSheetOpenState.native.cjs +15 -5
- package/dist/cjs/useSheetOpenState.native.js +15 -5
- package/dist/cjs/useSheetOpenState.native.js.map +1 -1
- package/dist/cjs/useSheetProviderProps.cjs +5 -94
- package/dist/cjs/useSheetProviderProps.native.cjs +5 -103
- package/dist/cjs/useSheetProviderProps.native.js +5 -103
- package/dist/cjs/useSheetProviderProps.native.js.map +1 -1
- package/dist/cjs/useSheetState.cjs +120 -0
- package/dist/cjs/useSheetState.native.cjs +131 -0
- package/dist/cjs/useSheetState.native.js +133 -0
- package/dist/cjs/useSheetState.native.js.map +1 -0
- package/dist/esm/Sheet.mjs +48 -15
- package/dist/esm/Sheet.mjs.map +1 -1
- package/dist/esm/Sheet.native.js +46 -17
- package/dist/esm/Sheet.native.js.map +1 -1
- package/dist/esm/SheetDragSurface.mjs +25 -0
- package/dist/esm/SheetDragSurface.mjs.map +1 -0
- package/dist/esm/SheetDragSurface.native.js +34 -0
- package/dist/esm/SheetDragSurface.native.js.map +1 -0
- package/dist/esm/SheetImplementationCustom.mjs +39 -56
- package/dist/esm/SheetImplementationCustom.mjs.map +1 -1
- package/dist/esm/SheetImplementationCustom.native.js +41 -57
- package/dist/esm/SheetImplementationCustom.native.js.map +1 -1
- package/dist/esm/SheetScrollView.mjs +16 -4
- package/dist/esm/SheetScrollView.mjs.map +1 -1
- package/dist/esm/SheetScrollView.native.js +18 -5
- package/dist/esm/SheetScrollView.native.js.map +1 -1
- package/dist/esm/nativeSheet.mjs +3 -60
- package/dist/esm/nativeSheet.mjs.map +1 -1
- package/dist/esm/nativeSheet.native.js +70 -58
- package/dist/esm/nativeSheet.native.js.map +1 -1
- package/dist/esm/stableViewportHeight.mjs +8 -0
- package/dist/esm/stableViewportHeight.mjs.map +1 -0
- package/dist/esm/stableViewportHeight.native.js +8 -0
- package/dist/esm/stableViewportHeight.native.js.map +1 -0
- package/dist/esm/useKeyboardControllerSheet.native.js +0 -5
- package/dist/esm/useSheetOffscreenSize.mjs +3 -1
- package/dist/esm/useSheetOffscreenSize.mjs.map +1 -1
- package/dist/esm/useSheetOffscreenSize.native.js +3 -2
- package/dist/esm/useSheetOffscreenSize.native.js.map +1 -1
- package/dist/esm/useSheetOpenState.mjs +14 -7
- package/dist/esm/useSheetOpenState.mjs.map +1 -1
- package/dist/esm/useSheetOpenState.native.js +16 -6
- package/dist/esm/useSheetOpenState.native.js.map +1 -1
- package/dist/esm/useSheetProviderProps.mjs +5 -88
- package/dist/esm/useSheetProviderProps.mjs.map +1 -1
- package/dist/esm/useSheetProviderProps.native.js +5 -97
- package/dist/esm/useSheetProviderProps.native.js.map +1 -1
- package/dist/esm/useSheetState.mjs +95 -0
- package/dist/esm/useSheetState.mjs.map +1 -0
- package/dist/esm/useSheetState.native.js +104 -0
- package/dist/esm/useSheetState.native.js.map +1 -0
- package/dist/jsx/Sheet.mjs +48 -15
- package/dist/jsx/Sheet.mjs.map +1 -1
- package/dist/jsx/Sheet.native.cjs +46 -17
- package/dist/jsx/Sheet.native.js +46 -17
- package/dist/jsx/Sheet.native.js.map +1 -1
- package/dist/jsx/SheetDragSurface.mjs +25 -0
- package/dist/jsx/SheetDragSurface.mjs.map +1 -0
- package/dist/{cjs/GestureDetectorWrapper.native.cjs → jsx/SheetDragSurface.native.cjs} +24 -10
- package/dist/jsx/{GestureDetectorWrapper.native.cjs → SheetDragSurface.native.js} +26 -10
- package/dist/jsx/SheetDragSurface.native.js.map +1 -0
- package/dist/jsx/SheetImplementationCustom.mjs +39 -56
- package/dist/jsx/SheetImplementationCustom.mjs.map +1 -1
- package/dist/jsx/SheetImplementationCustom.native.cjs +43 -59
- package/dist/jsx/SheetImplementationCustom.native.js +43 -59
- package/dist/jsx/SheetImplementationCustom.native.js.map +1 -1
- package/dist/jsx/SheetScrollView.mjs +16 -4
- package/dist/jsx/SheetScrollView.mjs.map +1 -1
- package/dist/jsx/SheetScrollView.native.cjs +17 -4
- package/dist/jsx/SheetScrollView.native.js +17 -4
- package/dist/jsx/SheetScrollView.native.js.map +1 -1
- package/dist/jsx/nativeSheet.mjs +3 -60
- package/dist/jsx/nativeSheet.mjs.map +1 -1
- package/dist/jsx/nativeSheet.native.cjs +70 -58
- package/dist/jsx/nativeSheet.native.js +70 -58
- package/dist/jsx/nativeSheet.native.js.map +1 -1
- package/dist/jsx/stableViewportHeight.mjs +8 -0
- package/dist/jsx/stableViewportHeight.mjs.map +1 -0
- package/dist/jsx/stableViewportHeight.native.cjs +29 -0
- package/dist/jsx/stableViewportHeight.native.js +31 -0
- package/dist/jsx/stableViewportHeight.native.js.map +1 -0
- package/dist/jsx/useSheetOffscreenSize.mjs +3 -1
- package/dist/jsx/useSheetOffscreenSize.mjs.map +1 -1
- package/dist/jsx/useSheetOffscreenSize.native.cjs +3 -2
- package/dist/jsx/useSheetOffscreenSize.native.js +3 -2
- package/dist/jsx/useSheetOffscreenSize.native.js.map +1 -1
- package/dist/jsx/useSheetOpenState.mjs +14 -7
- package/dist/jsx/useSheetOpenState.mjs.map +1 -1
- package/dist/jsx/useSheetOpenState.native.cjs +15 -5
- package/dist/jsx/useSheetOpenState.native.js +15 -5
- package/dist/jsx/useSheetOpenState.native.js.map +1 -1
- package/dist/jsx/useSheetProviderProps.mjs +5 -88
- package/dist/jsx/useSheetProviderProps.mjs.map +1 -1
- package/dist/jsx/useSheetProviderProps.native.cjs +5 -103
- package/dist/jsx/useSheetProviderProps.native.js +5 -103
- package/dist/jsx/useSheetProviderProps.native.js.map +1 -1
- package/dist/jsx/useSheetState.mjs +95 -0
- package/dist/jsx/useSheetState.mjs.map +1 -0
- package/dist/jsx/useSheetState.native.cjs +131 -0
- package/dist/jsx/useSheetState.native.js +133 -0
- package/dist/jsx/useSheetState.native.js.map +1 -0
- package/package.json +27 -22
- package/src/Sheet.tsx +45 -18
- package/src/SheetDragSurface.native.tsx +42 -0
- package/src/SheetDragSurface.tsx +40 -0
- package/src/SheetImplementationCustom.tsx +67 -92
- package/src/SheetScrollView.tsx +26 -4
- package/src/nativeSheet.native.tsx +110 -0
- package/src/nativeSheet.ts +16 -0
- package/src/stableViewportHeight.native.ts +9 -0
- package/src/stableViewportHeight.ts +15 -0
- package/src/types.tsx +44 -1
- package/src/useSheetOffscreenSize.tsx +3 -7
- package/src/useSheetOpenState.tsx +18 -8
- package/src/useSheetProviderProps.tsx +18 -149
- package/src/useSheetScrollViewGestures.native.ts +4 -1
- package/src/useSheetState.tsx +139 -0
- package/types/Sheet.d.ts +71 -167
- package/types/Sheet.d.ts.map +1 -1
- package/types/SheetDragSurface.d.ts +11 -0
- package/types/SheetDragSurface.d.ts.map +1 -0
- package/types/SheetDragSurface.native.d.ts +11 -0
- package/types/SheetDragSurface.native.d.ts.map +1 -0
- package/types/SheetImplementationCustom.d.ts +1 -2
- package/types/SheetImplementationCustom.d.ts.map +1 -1
- package/types/SheetScrollView.d.ts +3 -3
- package/types/SheetScrollView.d.ts.map +1 -1
- package/types/nativeSheet.d.ts +8 -9
- package/types/nativeSheet.d.ts.map +1 -1
- package/types/nativeSheet.native.d.ts +4 -0
- package/types/nativeSheet.native.d.ts.map +1 -0
- package/types/stableViewportHeight.d.ts +12 -0
- package/types/stableViewportHeight.d.ts.map +1 -0
- package/types/stableViewportHeight.native.d.ts +6 -0
- package/types/stableViewportHeight.native.d.ts.map +1 -0
- package/types/types.d.ts +34 -1
- package/types/types.d.ts.map +1 -1
- package/types/useSheetOffscreenSize.d.ts +1 -1
- package/types/useSheetOffscreenSize.d.ts.map +1 -1
- package/types/useSheetOpenState.d.ts +3 -1
- package/types/useSheetOpenState.d.ts.map +1 -1
- package/types/useSheetProviderProps.d.ts +15 -13
- package/types/useSheetProviderProps.d.ts.map +1 -1
- package/types/useSheetScrollViewGestures.native.d.ts +1 -1
- package/types/useSheetScrollViewGestures.native.d.ts.map +1 -1
- package/types/useSheetState.d.ts +26 -0
- package/types/useSheetState.d.ts.map +1 -0
- package/dist/cjs/GestureDetectorWrapper.cjs +0 -44
- package/dist/cjs/GestureDetectorWrapper.native.js.map +0 -1
- package/dist/esm/GestureDetectorWrapper.mjs +0 -25
- package/dist/esm/GestureDetectorWrapper.mjs.map +0 -1
- package/dist/esm/GestureDetectorWrapper.native.js +0 -26
- package/dist/esm/GestureDetectorWrapper.native.js.map +0 -1
- package/dist/jsx/GestureDetectorWrapper.mjs +0 -25
- package/dist/jsx/GestureDetectorWrapper.mjs.map +0 -1
- package/dist/jsx/GestureDetectorWrapper.native.js.map +0 -1
- package/src/GestureDetectorWrapper.tsx +0 -38
- package/src/nativeSheet.tsx +0 -86
- package/types/GestureDetectorWrapper.d.ts +0 -14
- package/types/GestureDetectorWrapper.d.ts.map +0 -1
|
@@ -1,137 +1,25 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import type { TamaguiElement } from '@tamagui/core'
|
|
3
1
|
import { useConfiguration } from '@tamagui/core'
|
|
4
2
|
import { useConstant } from '@tamagui/use-constant'
|
|
5
|
-
import { useControllableState } from '@tamagui/use-controllable-state'
|
|
6
3
|
|
|
7
4
|
import type { ScrollBridge, SheetProps } from './types'
|
|
8
5
|
import type { SheetOpenState } from './useSheetOpenState'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
setHasScrollView: (val: boolean) => void
|
|
23
|
-
}
|
|
6
|
+
import { useSheetState } from './useSheetState'
|
|
7
|
+
|
|
8
|
+
export type SheetContextValue =
|
|
9
|
+
| (ReturnType<typeof useSheetProviderProps> & {
|
|
10
|
+
keyboardOccludedHeight: number
|
|
11
|
+
isKeyboardVisible: boolean
|
|
12
|
+
keyboardStableFrameHeight: number
|
|
13
|
+
setHasScrollView: (val: boolean) => void
|
|
14
|
+
})
|
|
15
|
+
| (Omit<ReturnType<typeof useSheetState>, 'maxContentSize'> & {
|
|
16
|
+
onlyShowContainer: true
|
|
17
|
+
scrollBridge?: undefined
|
|
18
|
+
})
|
|
24
19
|
|
|
25
20
|
export function useSheetProviderProps(props: SheetProps, state: SheetOpenState) {
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const [frameSize, setFrameSize] = React.useState<number>(0)
|
|
29
|
-
const [maxContentSize, setMaxContentSize] = React.useState<number>(0)
|
|
30
|
-
const snapPointsMode = props.snapPointsMode ?? 'percent'
|
|
31
|
-
const snapPointsProp: (string | number)[] =
|
|
32
|
-
props.snapPoints ??
|
|
33
|
-
(snapPointsMode === 'percent'
|
|
34
|
-
? [80]
|
|
35
|
-
: snapPointsMode === 'constant'
|
|
36
|
-
? [256]
|
|
37
|
-
: ['fit'])
|
|
38
|
-
const hasFit = snapPointsProp[0] === 'fit'
|
|
39
|
-
|
|
40
|
-
const snapPoints = React.useMemo(
|
|
41
|
-
() => (props.dismissOnSnapToBottom ? [...snapPointsProp, 0] : snapPointsProp),
|
|
42
|
-
|
|
43
|
-
[JSON.stringify(snapPointsProp), props.dismissOnSnapToBottom]
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
// lets set -1 to be always the "open = false" position
|
|
47
|
-
const [position_, setPositionImmediate] = useControllableState({
|
|
48
|
-
prop: props.position,
|
|
49
|
-
defaultProp: props.defaultPosition || (state.open ? 0 : -1),
|
|
50
|
-
onChange: props.onPositionChange,
|
|
51
|
-
strategy: 'most-recent-wins',
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
const position = state.open === false ? -1 : position_
|
|
55
|
-
|
|
56
|
-
const { open } = state
|
|
57
|
-
|
|
58
|
-
const setPosition = React.useCallback(
|
|
59
|
-
(next: number) => {
|
|
60
|
-
// close on dismissOnSnapToBottom (and set position so it animates)
|
|
61
|
-
if (props.dismissOnSnapToBottom && next === snapPoints.length - 1) {
|
|
62
|
-
state.setOpen(false)
|
|
63
|
-
} else {
|
|
64
|
-
setPositionImmediate(next)
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
[props.dismissOnSnapToBottom, snapPoints.length, setPositionImmediate, state.setOpen]
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
if (process.env.NODE_ENV === 'development') {
|
|
71
|
-
if (
|
|
72
|
-
snapPointsMode === 'mixed' &&
|
|
73
|
-
snapPoints.some((p) => {
|
|
74
|
-
if (typeof p === 'string') {
|
|
75
|
-
if (p === 'fit') {
|
|
76
|
-
return false
|
|
77
|
-
}
|
|
78
|
-
if (p.endsWith('%')) {
|
|
79
|
-
const n = Number(p.slice(0, -1))
|
|
80
|
-
return n < 0 || n > 100
|
|
81
|
-
}
|
|
82
|
-
return true
|
|
83
|
-
}
|
|
84
|
-
return typeof p !== 'number' || p < 0
|
|
85
|
-
})
|
|
86
|
-
) {
|
|
87
|
-
console.warn(
|
|
88
|
-
'⚠️ Invalid snapPoint given, snapPoints must be positive numeric values, string percentages between 0-100%, or "fit" when snapPointsMode is mixed'
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
|
-
if (snapPointsMode === 'mixed' && snapPoints.indexOf('fit') > 0) {
|
|
92
|
-
console.warn(
|
|
93
|
-
'⚠️ Invalid snapPoint given, "fit" must be the first/largest snap point when snapPointsMode is mixed'
|
|
94
|
-
)
|
|
95
|
-
}
|
|
96
|
-
if (
|
|
97
|
-
snapPointsMode === 'fit' &&
|
|
98
|
-
(snapPoints.length !== (props.dismissOnSnapToBottom ? 2 : 1) ||
|
|
99
|
-
snapPoints[0] !== 'fit')
|
|
100
|
-
) {
|
|
101
|
-
console.warn(
|
|
102
|
-
'⚠️ Invalid snapPoint given, there are no snap points when snapPointsMode is fit'
|
|
103
|
-
)
|
|
104
|
-
}
|
|
105
|
-
if (
|
|
106
|
-
snapPointsMode === 'constant' &&
|
|
107
|
-
snapPoints.some((p) => typeof p !== 'number' || p < 0)
|
|
108
|
-
) {
|
|
109
|
-
console.warn(
|
|
110
|
-
'⚠️ Invalid snapPoint given, snapPoints must be positive numeric values when snapPointsMode is constant'
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
if (
|
|
114
|
-
snapPointsMode === 'percent' &&
|
|
115
|
-
snapPoints.some((p) => typeof p !== 'number' || p < 0 || p > 100)
|
|
116
|
-
) {
|
|
117
|
-
console.warn(
|
|
118
|
-
'⚠️ Invalid snapPoint given, snapPoints must be numeric values between 0 and 100 when snapPointsMode is percent'
|
|
119
|
-
)
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// reset position to fully open on re-open after dismissOnSnapToBottom
|
|
124
|
-
if (open && props.dismissOnSnapToBottom && position === snapPoints.length - 1) {
|
|
125
|
-
setPositionImmediate(0)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// open must set position
|
|
129
|
-
const shouldSetPositionOpen = open && position < 0
|
|
130
|
-
React.useEffect(() => {
|
|
131
|
-
if (shouldSetPositionOpen) {
|
|
132
|
-
setPosition(0)
|
|
133
|
-
}
|
|
134
|
-
}, [setPosition, shouldSetPositionOpen])
|
|
21
|
+
const { maxContentSize, ...sheetState } = useSheetState(props, state)
|
|
22
|
+
const { frameSize, snapPointsMode, snapPoints, open } = sheetState
|
|
135
23
|
|
|
136
24
|
const { animationDriver } = useConfiguration()
|
|
137
25
|
if (!animationDriver) {
|
|
@@ -181,31 +69,12 @@ export function useSheetProviderProps(props: SheetProps, state: SheetOpenState)
|
|
|
181
69
|
? frameSize / ((typeof maxSnapPoint === 'number' ? maxSnapPoint : 100) / 100)
|
|
182
70
|
: maxContentSize
|
|
183
71
|
|
|
184
|
-
|
|
72
|
+
return {
|
|
73
|
+
...sheetState,
|
|
185
74
|
screenSize,
|
|
186
75
|
maxSnapPoint,
|
|
187
76
|
disableRemoveScroll,
|
|
188
77
|
scrollBridge,
|
|
189
|
-
|
|
190
|
-
open: state.open,
|
|
191
|
-
setOpen: state.setOpen,
|
|
192
|
-
hidden: !!state.isHidden,
|
|
193
|
-
contentRef,
|
|
194
|
-
handleRef,
|
|
195
|
-
frameSize,
|
|
196
|
-
setFrameSize,
|
|
197
|
-
dismissOnOverlayPress: props.dismissOnOverlayPress ?? true,
|
|
198
|
-
dismissOnSnapToBottom: props.dismissOnSnapToBottom ?? false,
|
|
199
|
-
scope: props.scope ?? '',
|
|
200
|
-
hasFit,
|
|
201
|
-
position,
|
|
202
|
-
snapPoints,
|
|
203
|
-
snapPointsMode,
|
|
204
|
-
setMaxContentSize,
|
|
205
|
-
setPosition,
|
|
206
|
-
setPositionImmediate,
|
|
207
|
-
onlyShowContainer: false,
|
|
78
|
+
onlyShowContainer: false as const,
|
|
208
79
|
}
|
|
209
|
-
|
|
210
|
-
return providerProps
|
|
211
80
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { useRef } from 'react'
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
GestureResponderEvent,
|
|
4
|
+
ScrollViewInstance as RNScrollView,
|
|
5
|
+
} from 'react-native'
|
|
3
6
|
import type { ScrollBridge } from './types'
|
|
4
7
|
|
|
5
8
|
interface ResponderState {
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { TamaguiElement } from '@tamagui/core'
|
|
3
|
+
import { useControllableState } from '@tamagui/use-controllable-state'
|
|
4
|
+
import type { SheetProps } from './types'
|
|
5
|
+
import type { SheetOpenState } from './useSheetOpenState'
|
|
6
|
+
|
|
7
|
+
export function useSheetState(props: SheetProps, state: SheetOpenState) {
|
|
8
|
+
const handleRef = React.useRef<TamaguiElement>(null)
|
|
9
|
+
const contentRef = React.useRef<TamaguiElement>(null)
|
|
10
|
+
const [frameSize, setFrameSize] = React.useState<number>(0)
|
|
11
|
+
const [maxContentSize, setMaxContentSize] = React.useState<number>(0)
|
|
12
|
+
const snapPointsMode = props.snapPointsMode ?? 'percent'
|
|
13
|
+
const snapPointsProp: (string | number)[] =
|
|
14
|
+
props.snapPoints ??
|
|
15
|
+
(snapPointsMode === 'percent'
|
|
16
|
+
? [80]
|
|
17
|
+
: snapPointsMode === 'constant'
|
|
18
|
+
? [256]
|
|
19
|
+
: ['fit'])
|
|
20
|
+
const hasFit = snapPointsProp[0] === 'fit'
|
|
21
|
+
|
|
22
|
+
const snapPoints = React.useMemo(
|
|
23
|
+
() => (props.dismissOnSnapToBottom ? [...snapPointsProp, 0] : snapPointsProp),
|
|
24
|
+
|
|
25
|
+
[JSON.stringify(snapPointsProp), props.dismissOnSnapToBottom]
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
// lets set -1 to be always the "open = false" position
|
|
29
|
+
const [position_, setPositionImmediate] = useControllableState({
|
|
30
|
+
prop: props.position,
|
|
31
|
+
defaultProp: props.defaultPosition || (state.open ? 0 : -1),
|
|
32
|
+
onChange: props.onPositionChange,
|
|
33
|
+
strategy: state.strategy,
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const position = state.open === false ? -1 : position_
|
|
37
|
+
|
|
38
|
+
const { open } = state
|
|
39
|
+
|
|
40
|
+
const setPosition = React.useCallback(
|
|
41
|
+
(next: number) => {
|
|
42
|
+
// close on dismissOnSnapToBottom (and set position so it animates)
|
|
43
|
+
if (props.dismissOnSnapToBottom && next === snapPoints.length - 1) {
|
|
44
|
+
state.setOpen(false)
|
|
45
|
+
} else {
|
|
46
|
+
setPositionImmediate(next)
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
[props.dismissOnSnapToBottom, snapPoints.length, setPositionImmediate, state.setOpen]
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
if (process.env.NODE_ENV === 'development') {
|
|
53
|
+
if (
|
|
54
|
+
snapPointsMode === 'mixed' &&
|
|
55
|
+
snapPoints.some((p) => {
|
|
56
|
+
if (typeof p === 'string') {
|
|
57
|
+
if (p === 'fit') {
|
|
58
|
+
return false
|
|
59
|
+
}
|
|
60
|
+
if (p.endsWith('%')) {
|
|
61
|
+
const n = Number(p.slice(0, -1))
|
|
62
|
+
return n < 0 || n > 100
|
|
63
|
+
}
|
|
64
|
+
return true
|
|
65
|
+
}
|
|
66
|
+
return typeof p !== 'number' || p < 0
|
|
67
|
+
})
|
|
68
|
+
) {
|
|
69
|
+
console.warn(
|
|
70
|
+
'⚠️ Invalid snapPoint given, snapPoints must be positive numeric values, string percentages between 0-100%, or "fit" when snapPointsMode is mixed'
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
if (snapPointsMode === 'mixed' && snapPoints.indexOf('fit') > 0) {
|
|
74
|
+
console.warn(
|
|
75
|
+
'⚠️ Invalid snapPoint given, "fit" must be the first/largest snap point when snapPointsMode is mixed'
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
if (
|
|
79
|
+
snapPointsMode === 'fit' &&
|
|
80
|
+
(snapPoints.length !== (props.dismissOnSnapToBottom ? 2 : 1) ||
|
|
81
|
+
snapPoints[0] !== 'fit')
|
|
82
|
+
) {
|
|
83
|
+
console.warn(
|
|
84
|
+
'⚠️ Invalid snapPoint given, there are no snap points when snapPointsMode is fit'
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
if (
|
|
88
|
+
snapPointsMode === 'constant' &&
|
|
89
|
+
snapPoints.some((p) => typeof p !== 'number' || p < 0)
|
|
90
|
+
) {
|
|
91
|
+
console.warn(
|
|
92
|
+
'⚠️ Invalid snapPoint given, snapPoints must be positive numeric values when snapPointsMode is constant'
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
if (
|
|
96
|
+
snapPointsMode === 'percent' &&
|
|
97
|
+
snapPoints.some((p) => typeof p !== 'number' || p < 0 || p > 100)
|
|
98
|
+
) {
|
|
99
|
+
console.warn(
|
|
100
|
+
'⚠️ Invalid snapPoint given, snapPoints must be numeric values between 0 and 100 when snapPointsMode is percent'
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// reset position to fully open on re-open after dismissOnSnapToBottom
|
|
106
|
+
if (open && props.dismissOnSnapToBottom && position === snapPoints.length - 1) {
|
|
107
|
+
setPositionImmediate(0)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// open must set position
|
|
111
|
+
const shouldSetPositionOpen = open && position < 0
|
|
112
|
+
React.useEffect(() => {
|
|
113
|
+
if (shouldSetPositionOpen) {
|
|
114
|
+
setPosition(0)
|
|
115
|
+
}
|
|
116
|
+
}, [setPosition, shouldSetPositionOpen])
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
modal: !!props.modal,
|
|
120
|
+
open: state.open,
|
|
121
|
+
setOpen: state.setOpen,
|
|
122
|
+
hidden: !!state.isHidden,
|
|
123
|
+
contentRef,
|
|
124
|
+
handleRef,
|
|
125
|
+
frameSize,
|
|
126
|
+
setFrameSize,
|
|
127
|
+
maxContentSize,
|
|
128
|
+
dismissOnOverlayPress: props.dismissOnOverlayPress ?? true,
|
|
129
|
+
dismissOnSnapToBottom: props.dismissOnSnapToBottom ?? false,
|
|
130
|
+
scope: props.scope ?? '',
|
|
131
|
+
hasFit,
|
|
132
|
+
position,
|
|
133
|
+
snapPoints,
|
|
134
|
+
snapPointsMode,
|
|
135
|
+
setMaxContentSize,
|
|
136
|
+
setPosition,
|
|
137
|
+
setPositionImmediate,
|
|
138
|
+
}
|
|
139
|
+
}
|