@mustmove/bottom-sheet 1.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/README.md +66 -0
- package/mock.js +231 -0
- package/package.json +107 -0
- package/src/components/bottomSheet/BottomSheet.tsx +1885 -0
- package/src/components/bottomSheet/BottomSheetBody.tsx +44 -0
- package/src/components/bottomSheet/BottomSheetContent.tsx +261 -0
- package/src/components/bottomSheet/constants.ts +58 -0
- package/src/components/bottomSheet/index.ts +2 -0
- package/src/components/bottomSheet/styles.ts +11 -0
- package/src/components/bottomSheet/types.d.ts +358 -0
- package/src/components/bottomSheetBackdrop/BottomSheetBackdrop.tsx +165 -0
- package/src/components/bottomSheetBackdrop/constants.ts +22 -0
- package/src/components/bottomSheetBackdrop/index.ts +2 -0
- package/src/components/bottomSheetBackdrop/styles.ts +8 -0
- package/src/components/bottomSheetBackdrop/types.d.ts +58 -0
- package/src/components/bottomSheetBackground/BottomSheetBackground.tsx +20 -0
- package/src/components/bottomSheetBackground/BottomSheetBackgroundContainer.tsx +35 -0
- package/src/components/bottomSheetBackground/index.ts +2 -0
- package/src/components/bottomSheetBackground/styles.ts +9 -0
- package/src/components/bottomSheetBackground/types.d.ts +12 -0
- package/src/components/bottomSheetDebugView/BottomSheetDebugView.tsx +26 -0
- package/src/components/bottomSheetDebugView/ReText.tsx +72 -0
- package/src/components/bottomSheetDebugView/ReText.webx.tsx +55 -0
- package/src/components/bottomSheetDebugView/index.ts +1 -0
- package/src/components/bottomSheetDebugView/styles.ts +19 -0
- package/src/components/bottomSheetDebugView/styles.web.ts +20 -0
- package/src/components/bottomSheetDraggableView/BottomSheetDraggableView.tsx +123 -0
- package/src/components/bottomSheetDraggableView/index.ts +1 -0
- package/src/components/bottomSheetDraggableView/types.d.ts +9 -0
- package/src/components/bottomSheetFooter/BottomSheetFooter.tsx +119 -0
- package/src/components/bottomSheetFooter/BottomSheetFooterContainer.tsx +43 -0
- package/src/components/bottomSheetFooter/index.ts +3 -0
- package/src/components/bottomSheetFooter/styles.ts +12 -0
- package/src/components/bottomSheetFooter/types.d.ts +41 -0
- package/src/components/bottomSheetGestureHandlersProvider/BottomSheetGestureHandlersProvider.tsx +69 -0
- package/src/components/bottomSheetGestureHandlersProvider/index.ts +1 -0
- package/src/components/bottomSheetGestureHandlersProvider/types.d.ts +8 -0
- package/src/components/bottomSheetHandle/BottomSheetHandle.tsx +51 -0
- package/src/components/bottomSheetHandle/BottomSheetHandleContainer.tsx +187 -0
- package/src/components/bottomSheetHandle/constants.ts +12 -0
- package/src/components/bottomSheetHandle/index.ts +6 -0
- package/src/components/bottomSheetHandle/styles.ts +23 -0
- package/src/components/bottomSheetHandle/types.d.ts +52 -0
- package/src/components/bottomSheetHostingContainer/BottomSheetHostingContainer.tsx +130 -0
- package/src/components/bottomSheetHostingContainer/index.ts +2 -0
- package/src/components/bottomSheetHostingContainer/styles.ts +5 -0
- package/src/components/bottomSheetHostingContainer/styles.web.ts +11 -0
- package/src/components/bottomSheetHostingContainer/types.d.ts +17 -0
- package/src/components/bottomSheetModal/BottomSheetModal.tsx +482 -0
- package/src/components/bottomSheetModal/constants.ts +4 -0
- package/src/components/bottomSheetModal/index.ts +6 -0
- package/src/components/bottomSheetModal/types.d.ts +67 -0
- package/src/components/bottomSheetModalProvider/BottomSheetModalProvider.tsx +211 -0
- package/src/components/bottomSheetModalProvider/index.ts +1 -0
- package/src/components/bottomSheetModalProvider/types.d.ts +12 -0
- package/src/components/bottomSheetRefreshControl/BottomSheetRefreshControl.android.tsx +84 -0
- package/src/components/bottomSheetRefreshControl/BottomSheetRefreshControl.tsx +1 -0
- package/src/components/bottomSheetRefreshControl/index.ts +20 -0
- package/src/components/bottomSheetScrollable/BottomSheetDraggableScrollable.tsx +23 -0
- package/src/components/bottomSheetScrollable/BottomSheetFlashList.tsx +88 -0
- package/src/components/bottomSheetScrollable/BottomSheetFlashList.web.tsx +1 -0
- package/src/components/bottomSheetScrollable/BottomSheetFlatList.tsx +26 -0
- package/src/components/bottomSheetScrollable/BottomSheetScrollView.tsx +27 -0
- package/src/components/bottomSheetScrollable/BottomSheetSectionList.tsx +29 -0
- package/src/components/bottomSheetScrollable/BottomSheetVirtualizedList.tsx +27 -0
- package/src/components/bottomSheetScrollable/ScrollableContainer.android.tsx +55 -0
- package/src/components/bottomSheetScrollable/ScrollableContainer.tsx +22 -0
- package/src/components/bottomSheetScrollable/ScrollableContainer.web.tsx +102 -0
- package/src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.tsx +153 -0
- package/src/components/bottomSheetScrollable/index.ts +15 -0
- package/src/components/bottomSheetScrollable/styles.ts +8 -0
- package/src/components/bottomSheetScrollable/types.d.ts +280 -0
- package/src/components/bottomSheetScrollable/useBottomSheetContentSizeSetter.ts +32 -0
- package/src/components/bottomSheetTextInput/BottomSheetTextInput.tsx +127 -0
- package/src/components/bottomSheetTextInput/index.ts +2 -0
- package/src/components/bottomSheetTextInput/types.ts +3 -0
- package/src/components/bottomSheetView/BottomSheetView.tsx +93 -0
- package/src/components/bottomSheetView/index.ts +1 -0
- package/src/components/bottomSheetView/styles.ts +10 -0
- package/src/components/bottomSheetView/types.d.ts +24 -0
- package/src/components/touchables/Touchables.ios.tsx +5 -0
- package/src/components/touchables/Touchables.tsx +5 -0
- package/src/components/touchables/index.ts +20 -0
- package/src/constants.ts +159 -0
- package/src/contexts/external.ts +8 -0
- package/src/contexts/gesture.ts +13 -0
- package/src/contexts/index.ts +15 -0
- package/src/contexts/internal.ts +65 -0
- package/src/contexts/modal/external.ts +11 -0
- package/src/contexts/modal/internal.ts +25 -0
- package/src/hooks/index.ts +29 -0
- package/src/hooks/useAnimatedDetents.ts +119 -0
- package/src/hooks/useAnimatedKeyboard.ts +174 -0
- package/src/hooks/useAnimatedLayout.ts +109 -0
- package/src/hooks/useBottomSheet.ts +12 -0
- package/src/hooks/useBottomSheetContentContainerStyle.ts +88 -0
- package/src/hooks/useBottomSheetGestureHandlers.ts +12 -0
- package/src/hooks/useBottomSheetInternal.ts +25 -0
- package/src/hooks/useBottomSheetModal.ts +12 -0
- package/src/hooks/useBottomSheetModalInternal.ts +25 -0
- package/src/hooks/useBottomSheetScrollableCreator.tsx +60 -0
- package/src/hooks/useBottomSheetSpringConfigs.ts +11 -0
- package/src/hooks/useBottomSheetTimingConfigs.ts +36 -0
- package/src/hooks/useBoundingClientRect.ts +77 -0
- package/src/hooks/useGestureEventsHandlersDefault.tsx +436 -0
- package/src/hooks/useGestureEventsHandlersDefault.web.tsx +418 -0
- package/src/hooks/useGestureHandler.ts +90 -0
- package/src/hooks/usePropsValidator.ts +108 -0
- package/src/hooks/useReactiveSharedValue.ts +45 -0
- package/src/hooks/useScrollEventsHandlersDefault.ts +167 -0
- package/src/hooks/useScrollHandler.ts +72 -0
- package/src/hooks/useScrollHandler.web.ts +181 -0
- package/src/hooks/useScrollable.ts +131 -0
- package/src/hooks/useScrollableSetter.ts +56 -0
- package/src/hooks/useStableCallback.ts +26 -0
- package/src/index.ts +79 -0
- package/src/types.d.ts +336 -0
- package/src/utilities/animate.ts +56 -0
- package/src/utilities/clamp.ts +8 -0
- package/src/utilities/easingExp.ts +10 -0
- package/src/utilities/findNodeHandle.ts +1 -0
- package/src/utilities/findNodeHandle.web.ts +33 -0
- package/src/utilities/getKeyboardAnimationConfigs.ts +44 -0
- package/src/utilities/getRefNativeTag.web.ts +6 -0
- package/src/utilities/id.ts +6 -0
- package/src/utilities/index.ts +7 -0
- package/src/utilities/isFabricInstalled.ts +9 -0
- package/src/utilities/logger.ts +55 -0
- package/src/utilities/noop.ts +7 -0
- package/src/utilities/normalizeSnapPoint.ts +17 -0
- package/src/utilities/snapPoint.ts +11 -0
- package/src/utilities/validateSnapPoint.ts +20 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import React, { memo, useCallback, useMemo, useRef } from 'react';
|
|
2
|
+
import type { LayoutChangeEvent, View } from 'react-native';
|
|
3
|
+
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
4
|
+
import Animated from 'react-native-reanimated';
|
|
5
|
+
import {
|
|
6
|
+
type BoundingClientRect,
|
|
7
|
+
useBottomSheetGestureHandlers,
|
|
8
|
+
useBottomSheetInternal,
|
|
9
|
+
useBoundingClientRect,
|
|
10
|
+
} from '../../hooks';
|
|
11
|
+
import { print } from '../../utilities';
|
|
12
|
+
import { DEFAULT_ENABLE_HANDLE_PANNING_GESTURE } from '../bottomSheet/constants';
|
|
13
|
+
import type { BottomSheetHandleContainerProps } from './types';
|
|
14
|
+
|
|
15
|
+
function BottomSheetHandleContainerComponent({
|
|
16
|
+
animatedIndex,
|
|
17
|
+
animatedPosition,
|
|
18
|
+
simultaneousHandlers: _internalSimultaneousHandlers,
|
|
19
|
+
enableHandlePanningGesture = DEFAULT_ENABLE_HANDLE_PANNING_GESTURE,
|
|
20
|
+
handleComponent: HandleComponent,
|
|
21
|
+
handleStyle: _providedHandleStyle,
|
|
22
|
+
handleIndicatorStyle: _providedIndicatorStyle,
|
|
23
|
+
}: BottomSheetHandleContainerProps) {
|
|
24
|
+
//#region refs
|
|
25
|
+
const ref = useRef<View>(null);
|
|
26
|
+
//#endregion
|
|
27
|
+
|
|
28
|
+
//#region hooks
|
|
29
|
+
const {
|
|
30
|
+
animatedLayoutState,
|
|
31
|
+
activeOffsetX,
|
|
32
|
+
activeOffsetY,
|
|
33
|
+
failOffsetX,
|
|
34
|
+
failOffsetY,
|
|
35
|
+
waitFor,
|
|
36
|
+
simultaneousHandlers: _providedSimultaneousHandlers,
|
|
37
|
+
} = useBottomSheetInternal();
|
|
38
|
+
const { handlePanGestureHandler } = useBottomSheetGestureHandlers();
|
|
39
|
+
//#endregion
|
|
40
|
+
|
|
41
|
+
//#region variables
|
|
42
|
+
const simultaneousHandlers = useMemo<unknown[]>(() => {
|
|
43
|
+
const refs = [];
|
|
44
|
+
|
|
45
|
+
if (_internalSimultaneousHandlers) {
|
|
46
|
+
refs.push(_internalSimultaneousHandlers);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (_providedSimultaneousHandlers) {
|
|
50
|
+
if (Array.isArray(_providedSimultaneousHandlers)) {
|
|
51
|
+
refs.push(..._providedSimultaneousHandlers);
|
|
52
|
+
} else {
|
|
53
|
+
refs.push(_providedSimultaneousHandlers);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return refs;
|
|
58
|
+
}, [_providedSimultaneousHandlers, _internalSimultaneousHandlers]);
|
|
59
|
+
const panGesture = useMemo(() => {
|
|
60
|
+
let gesture = Gesture.Pan()
|
|
61
|
+
.enabled(enableHandlePanningGesture)
|
|
62
|
+
.shouldCancelWhenOutside(false)
|
|
63
|
+
.runOnJS(false)
|
|
64
|
+
.onStart(handlePanGestureHandler.handleOnStart)
|
|
65
|
+
.onChange(handlePanGestureHandler.handleOnChange)
|
|
66
|
+
.onEnd(handlePanGestureHandler.handleOnEnd)
|
|
67
|
+
.onFinalize(handlePanGestureHandler.handleOnFinalize);
|
|
68
|
+
|
|
69
|
+
if (waitFor) {
|
|
70
|
+
gesture = gesture.requireExternalGestureToFail(waitFor);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (simultaneousHandlers) {
|
|
74
|
+
gesture = gesture.simultaneousWithExternalGesture(
|
|
75
|
+
simultaneousHandlers as never
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (activeOffsetX) {
|
|
80
|
+
gesture = gesture.activeOffsetX(activeOffsetX);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (activeOffsetY) {
|
|
84
|
+
gesture = gesture.activeOffsetY(activeOffsetY);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (failOffsetX) {
|
|
88
|
+
gesture = gesture.failOffsetX(failOffsetX);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (failOffsetY) {
|
|
92
|
+
gesture = gesture.failOffsetY(failOffsetY);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return gesture;
|
|
96
|
+
}, [
|
|
97
|
+
activeOffsetX,
|
|
98
|
+
activeOffsetY,
|
|
99
|
+
enableHandlePanningGesture,
|
|
100
|
+
failOffsetX,
|
|
101
|
+
failOffsetY,
|
|
102
|
+
simultaneousHandlers,
|
|
103
|
+
waitFor,
|
|
104
|
+
handlePanGestureHandler.handleOnChange,
|
|
105
|
+
handlePanGestureHandler.handleOnEnd,
|
|
106
|
+
handlePanGestureHandler.handleOnFinalize,
|
|
107
|
+
handlePanGestureHandler.handleOnStart,
|
|
108
|
+
]);
|
|
109
|
+
//#endregion
|
|
110
|
+
|
|
111
|
+
//#region callbacks
|
|
112
|
+
const handleContainerLayout = useCallback(
|
|
113
|
+
function handleContainerLayout({
|
|
114
|
+
nativeEvent: {
|
|
115
|
+
layout: { height },
|
|
116
|
+
},
|
|
117
|
+
}: LayoutChangeEvent) {
|
|
118
|
+
animatedLayoutState.modify(state => {
|
|
119
|
+
'worklet';
|
|
120
|
+
state.handleHeight = height;
|
|
121
|
+
return state;
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (__DEV__) {
|
|
125
|
+
print({
|
|
126
|
+
component: 'BottomSheetHandleContainer',
|
|
127
|
+
method: 'handleContainerLayout',
|
|
128
|
+
category: 'layout',
|
|
129
|
+
params: {
|
|
130
|
+
height,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
[animatedLayoutState]
|
|
136
|
+
);
|
|
137
|
+
const handleBoundingClientRect = useCallback(
|
|
138
|
+
({ height }: BoundingClientRect) => {
|
|
139
|
+
animatedLayoutState.modify(state => {
|
|
140
|
+
'worklet';
|
|
141
|
+
state.handleHeight = height;
|
|
142
|
+
return state;
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
if (__DEV__) {
|
|
146
|
+
print({
|
|
147
|
+
component: 'BottomSheetHandleContainer',
|
|
148
|
+
method: 'handleBoundingClientRect',
|
|
149
|
+
category: 'layout',
|
|
150
|
+
params: {
|
|
151
|
+
height,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
[animatedLayoutState]
|
|
157
|
+
);
|
|
158
|
+
//#endregion
|
|
159
|
+
|
|
160
|
+
//#region effects
|
|
161
|
+
useBoundingClientRect(ref, handleBoundingClientRect);
|
|
162
|
+
//#endregion
|
|
163
|
+
|
|
164
|
+
//#region renders
|
|
165
|
+
return (
|
|
166
|
+
<GestureDetector gesture={panGesture}>
|
|
167
|
+
<Animated.View
|
|
168
|
+
ref={ref}
|
|
169
|
+
onLayout={handleContainerLayout}
|
|
170
|
+
key="BottomSheetHandleContainer"
|
|
171
|
+
>
|
|
172
|
+
<HandleComponent
|
|
173
|
+
animatedIndex={animatedIndex}
|
|
174
|
+
animatedPosition={animatedPosition}
|
|
175
|
+
style={_providedHandleStyle}
|
|
176
|
+
indicatorStyle={_providedIndicatorStyle}
|
|
177
|
+
/>
|
|
178
|
+
</Animated.View>
|
|
179
|
+
</GestureDetector>
|
|
180
|
+
);
|
|
181
|
+
//#endregion
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const BottomSheetHandleContainer = memo(BottomSheetHandleContainerComponent);
|
|
185
|
+
BottomSheetHandleContainer.displayName = 'BottomSheetHandleContainer';
|
|
186
|
+
|
|
187
|
+
export default BottomSheetHandleContainer;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const DEFAULT_ACCESSIBLE = true;
|
|
2
|
+
const DEFAULT_ACCESSIBILITY_ROLE = 'adjustable';
|
|
3
|
+
const DEFAULT_ACCESSIBILITY_LABEL = 'Bottom sheet handle';
|
|
4
|
+
const DEFAULT_ACCESSIBILITY_HINT =
|
|
5
|
+
'Drag up or down to extend or minimize the bottom sheet';
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
DEFAULT_ACCESSIBLE,
|
|
9
|
+
DEFAULT_ACCESSIBILITY_ROLE,
|
|
10
|
+
DEFAULT_ACCESSIBILITY_LABEL,
|
|
11
|
+
DEFAULT_ACCESSIBILITY_HINT,
|
|
12
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Platform, StyleSheet } from 'react-native';
|
|
2
|
+
import { WINDOW_WIDTH } from '../../constants';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export const styles = StyleSheet.create({
|
|
6
|
+
container: {
|
|
7
|
+
padding: 10,
|
|
8
|
+
...Platform.select({
|
|
9
|
+
web: {
|
|
10
|
+
cursor: 'pointer' as const
|
|
11
|
+
},
|
|
12
|
+
default: {}
|
|
13
|
+
}),
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
indicator: {
|
|
17
|
+
alignSelf: 'center',
|
|
18
|
+
width: (7.5 * WINDOW_WIDTH) / 100,
|
|
19
|
+
height: 4,
|
|
20
|
+
borderRadius: 4,
|
|
21
|
+
backgroundColor: 'rgba(0, 0, 0, 0.75)',
|
|
22
|
+
},
|
|
23
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { View, ViewProps } from 'react-native';
|
|
3
|
+
import type { PanGestureHandlerProperties } from 'react-native-gesture-handler';
|
|
4
|
+
import type { AnimateProps, SharedValue } from 'react-native-reanimated';
|
|
5
|
+
import type { useInteractivePanGestureHandlerConfigs } from '../../hooks/useGestureHandler';
|
|
6
|
+
import type {
|
|
7
|
+
BottomSheetVariables,
|
|
8
|
+
NullableAccessibilityProps,
|
|
9
|
+
} from '../../types';
|
|
10
|
+
import type { BottomSheetProps } from '../bottomSheet';
|
|
11
|
+
|
|
12
|
+
export type BottomSheetHandleProps = BottomSheetVariables;
|
|
13
|
+
export interface BottomSheetDefaultHandleProps
|
|
14
|
+
extends BottomSheetHandleProps,
|
|
15
|
+
NullableAccessibilityProps {
|
|
16
|
+
/**
|
|
17
|
+
* View style to be applied to the handle container.
|
|
18
|
+
* @type ViewStyle
|
|
19
|
+
* @default undefined
|
|
20
|
+
*/
|
|
21
|
+
style?: ViewProps['style'];
|
|
22
|
+
/**
|
|
23
|
+
* View style to be applied to the handle indicator.
|
|
24
|
+
* @type ViewStyle
|
|
25
|
+
* @default undefined
|
|
26
|
+
*/
|
|
27
|
+
indicatorStyle?: ViewProps['style'];
|
|
28
|
+
/**
|
|
29
|
+
* Content to be added below the indicator.
|
|
30
|
+
* @type React.ReactNode | React.ReactNode[];
|
|
31
|
+
* @default undefined
|
|
32
|
+
*/
|
|
33
|
+
children?: React.ReactNode | React.ReactNode[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type BottomSheetHandleContainerProps = Pick<
|
|
37
|
+
PanGestureHandlerProperties,
|
|
38
|
+
'simultaneousHandlers'
|
|
39
|
+
> & {
|
|
40
|
+
handleComponent: React.FC<BottomSheetDefaultHandleProps>;
|
|
41
|
+
} & Pick<
|
|
42
|
+
BottomSheetProps,
|
|
43
|
+
'enableHandlePanningGesture' | 'handleIndicatorStyle' | 'handleStyle'
|
|
44
|
+
> &
|
|
45
|
+
Pick<
|
|
46
|
+
useInteractivePanGestureHandlerConfigs,
|
|
47
|
+
| 'enableOverDrag'
|
|
48
|
+
| 'enablePanDownToClose'
|
|
49
|
+
| 'overDragResistanceFactor'
|
|
50
|
+
| 'keyboardBehavior'
|
|
51
|
+
> &
|
|
52
|
+
BottomSheetHandleProps;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import React, { memo, useCallback, useMemo, useRef } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
type LayoutChangeEvent,
|
|
4
|
+
StatusBar,
|
|
5
|
+
type StyleProp,
|
|
6
|
+
View,
|
|
7
|
+
type ViewStyle,
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
import { WINDOW_HEIGHT } from '../../constants';
|
|
10
|
+
import { print } from '../../utilities';
|
|
11
|
+
import { styles } from './styles';
|
|
12
|
+
import type { BottomSheetHostingContainerProps } from './types';
|
|
13
|
+
|
|
14
|
+
function BottomSheetHostingContainerComponent({
|
|
15
|
+
containerLayoutState,
|
|
16
|
+
layoutState,
|
|
17
|
+
topInset = 0,
|
|
18
|
+
bottomInset = 0,
|
|
19
|
+
shouldCalculateHeight = true,
|
|
20
|
+
detached,
|
|
21
|
+
style,
|
|
22
|
+
children,
|
|
23
|
+
}: BottomSheetHostingContainerProps) {
|
|
24
|
+
//#region refs
|
|
25
|
+
const containerRef = useRef<View>(null);
|
|
26
|
+
//#endregion
|
|
27
|
+
|
|
28
|
+
//#region styles
|
|
29
|
+
const containerStyle = useMemo<StyleProp<ViewStyle>>(
|
|
30
|
+
() => [
|
|
31
|
+
style,
|
|
32
|
+
styles.container,
|
|
33
|
+
{
|
|
34
|
+
top: topInset,
|
|
35
|
+
bottom: bottomInset,
|
|
36
|
+
overflow: detached ? 'visible' : 'hidden',
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
[style, detached, topInset, bottomInset]
|
|
40
|
+
);
|
|
41
|
+
//#endregion
|
|
42
|
+
|
|
43
|
+
//#region callbacks
|
|
44
|
+
const handleLayoutEvent = useCallback(
|
|
45
|
+
function handleLayoutEvent({
|
|
46
|
+
nativeEvent: {
|
|
47
|
+
layout: { height },
|
|
48
|
+
},
|
|
49
|
+
}: LayoutChangeEvent) {
|
|
50
|
+
if (containerLayoutState) {
|
|
51
|
+
containerLayoutState.modify(state => {
|
|
52
|
+
'worklet';
|
|
53
|
+
state.height = height;
|
|
54
|
+
return state;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (layoutState) {
|
|
59
|
+
layoutState.modify(state => {
|
|
60
|
+
'worklet';
|
|
61
|
+
state.rawContainerHeight = height;
|
|
62
|
+
return state;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
containerRef.current?.measure(
|
|
67
|
+
(_x, _y, _width, _height, _pageX, pageY) => {
|
|
68
|
+
const offset = {
|
|
69
|
+
bottom: Math.max(
|
|
70
|
+
0,
|
|
71
|
+
WINDOW_HEIGHT -
|
|
72
|
+
((pageY ?? 0) + height + (StatusBar.currentHeight ?? 0))
|
|
73
|
+
),
|
|
74
|
+
top: pageY ?? 0,
|
|
75
|
+
left: 0,
|
|
76
|
+
right: 0,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
if (containerLayoutState) {
|
|
80
|
+
containerLayoutState.modify(state => {
|
|
81
|
+
'worklet';
|
|
82
|
+
state.offset = offset;
|
|
83
|
+
return state;
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (layoutState) {
|
|
88
|
+
layoutState.modify(state => {
|
|
89
|
+
'worklet';
|
|
90
|
+
state.containerOffset = offset;
|
|
91
|
+
return state;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
if (__DEV__) {
|
|
98
|
+
print({
|
|
99
|
+
component: 'BottomSheetHostingContainer',
|
|
100
|
+
method: 'handleLayoutEvent',
|
|
101
|
+
category: 'layout',
|
|
102
|
+
params: {
|
|
103
|
+
height,
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
[layoutState, containerLayoutState]
|
|
109
|
+
);
|
|
110
|
+
//#endregion
|
|
111
|
+
|
|
112
|
+
//#region render
|
|
113
|
+
return (
|
|
114
|
+
<View
|
|
115
|
+
ref={containerRef}
|
|
116
|
+
pointerEvents="box-none"
|
|
117
|
+
onLayout={shouldCalculateHeight ? handleLayoutEvent : undefined}
|
|
118
|
+
style={containerStyle}
|
|
119
|
+
collapsable={true}
|
|
120
|
+
>
|
|
121
|
+
{children}
|
|
122
|
+
</View>
|
|
123
|
+
);
|
|
124
|
+
//#endregion
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const BottomSheetHostingContainer = memo(
|
|
128
|
+
BottomSheetHostingContainerComponent
|
|
129
|
+
);
|
|
130
|
+
BottomSheetHostingContainer.displayName = 'BottomSheetHostingContainer';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { Insets, StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import type { SharedValue } from 'react-native-reanimated';
|
|
4
|
+
import type { ContainerLayoutState, LayoutState } from '../../types';
|
|
5
|
+
import type { BottomSheetProps } from '../bottomSheet/types';
|
|
6
|
+
|
|
7
|
+
export interface BottomSheetHostingContainerProps
|
|
8
|
+
extends Partial<
|
|
9
|
+
Pick<BottomSheetProps, 'topInset' | 'bottomInset' | 'detached'>
|
|
10
|
+
> {
|
|
11
|
+
containerLayoutState?: SharedValue<ContainerLayoutState>;
|
|
12
|
+
layoutState?: SharedValue<LayoutState>;
|
|
13
|
+
|
|
14
|
+
shouldCalculateHeight?: boolean;
|
|
15
|
+
style?: StyleProp<ViewStyle>;
|
|
16
|
+
children?: ReactNode;
|
|
17
|
+
}
|