@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,211 @@
|
|
|
1
|
+
import { PortalProvider } from '@gorhom/portal';
|
|
2
|
+
import React, { useCallback, useMemo, useRef } from 'react';
|
|
3
|
+
import { useSharedValue } from 'react-native-reanimated';
|
|
4
|
+
import {
|
|
5
|
+
INITIAL_CONTAINER_LAYOUT,
|
|
6
|
+
MODAL_STACK_BEHAVIOR,
|
|
7
|
+
} from '../../constants';
|
|
8
|
+
import {
|
|
9
|
+
BottomSheetModalInternalProvider,
|
|
10
|
+
BottomSheetModalProvider,
|
|
11
|
+
} from '../../contexts';
|
|
12
|
+
import type { ContainerLayoutState } from '../../types';
|
|
13
|
+
import { id } from '../../utilities/id';
|
|
14
|
+
import { BottomSheetHostingContainer } from '../bottomSheetHostingContainer';
|
|
15
|
+
import type {
|
|
16
|
+
BottomSheetModalPrivateMethods,
|
|
17
|
+
BottomSheetModalStackBehavior,
|
|
18
|
+
} from '../bottomSheetModal';
|
|
19
|
+
import type {
|
|
20
|
+
BottomSheetModalProviderProps,
|
|
21
|
+
BottomSheetModalRef,
|
|
22
|
+
} from './types';
|
|
23
|
+
|
|
24
|
+
const BottomSheetModalProviderWrapper = ({
|
|
25
|
+
children,
|
|
26
|
+
}: BottomSheetModalProviderProps) => {
|
|
27
|
+
//#region layout variables
|
|
28
|
+
const animatedContainerLayoutState = useSharedValue<ContainerLayoutState>(
|
|
29
|
+
INITIAL_CONTAINER_LAYOUT
|
|
30
|
+
);
|
|
31
|
+
//#endregion
|
|
32
|
+
|
|
33
|
+
//#region variables
|
|
34
|
+
const hostName = useMemo(() => `bottom-sheet-portal-${id()}`, []);
|
|
35
|
+
const sheetsQueueRef = useRef<BottomSheetModalRef[]>([]);
|
|
36
|
+
//#endregion
|
|
37
|
+
|
|
38
|
+
//#region private methods
|
|
39
|
+
const handleMountSheet = useCallback(
|
|
40
|
+
(
|
|
41
|
+
key: string,
|
|
42
|
+
ref: React.RefObject<BottomSheetModalPrivateMethods>,
|
|
43
|
+
stackBehavior: BottomSheetModalStackBehavior
|
|
44
|
+
) => {
|
|
45
|
+
const _sheetsQueue = sheetsQueueRef.current.slice();
|
|
46
|
+
const sheetIndex = _sheetsQueue.findIndex(item => item.key === key);
|
|
47
|
+
const sheetOnTop = sheetIndex === _sheetsQueue.length - 1;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Exit the method, if sheet is already presented
|
|
51
|
+
* and at the top.
|
|
52
|
+
*/
|
|
53
|
+
if (sheetIndex !== -1 && sheetOnTop) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Minimize the current sheet if:
|
|
59
|
+
* - it exists.
|
|
60
|
+
* - it is not unmounting.
|
|
61
|
+
* - stack behavior is 'replace'.
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Handle switch or replace stack behaviors, if:
|
|
66
|
+
* - a modal is currently presented.
|
|
67
|
+
* - it is not unmounting
|
|
68
|
+
*/
|
|
69
|
+
const currentMountedSheet = _sheetsQueue[_sheetsQueue.length - 1];
|
|
70
|
+
if (currentMountedSheet && !currentMountedSheet.willUnmount) {
|
|
71
|
+
if (stackBehavior === MODAL_STACK_BEHAVIOR.replace) {
|
|
72
|
+
currentMountedSheet.ref?.current?.dismiss();
|
|
73
|
+
} else if (stackBehavior === MODAL_STACK_BEHAVIOR.switch) {
|
|
74
|
+
currentMountedSheet.ref?.current?.minimize();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Restore and remove incoming sheet from the queue,
|
|
80
|
+
* if it was registered.
|
|
81
|
+
*/
|
|
82
|
+
if (sheetIndex !== -1) {
|
|
83
|
+
_sheetsQueue.splice(sheetIndex, 1);
|
|
84
|
+
ref?.current?.restore();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
_sheetsQueue.push({
|
|
88
|
+
key,
|
|
89
|
+
ref,
|
|
90
|
+
willUnmount: false,
|
|
91
|
+
});
|
|
92
|
+
sheetsQueueRef.current = _sheetsQueue;
|
|
93
|
+
},
|
|
94
|
+
[]
|
|
95
|
+
);
|
|
96
|
+
const handleUnmountSheet = useCallback((key: string) => {
|
|
97
|
+
const _sheetsQueue = sheetsQueueRef.current.slice();
|
|
98
|
+
const sheetIndex = _sheetsQueue.findIndex(item => item.key === key);
|
|
99
|
+
const sheetOnTop = sheetIndex === _sheetsQueue.length - 1;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Here we remove the unmounted sheet and update
|
|
103
|
+
* the sheets queue.
|
|
104
|
+
*/
|
|
105
|
+
_sheetsQueue.splice(sheetIndex, 1);
|
|
106
|
+
sheetsQueueRef.current = _sheetsQueue;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Here we try to restore previous sheet position if unmounted
|
|
110
|
+
* sheet was on top. This is needed when user dismiss
|
|
111
|
+
* the modal by panning down.
|
|
112
|
+
*/
|
|
113
|
+
const hasMinimizedSheet = sheetsQueueRef.current.length > 0;
|
|
114
|
+
const minimizedSheet =
|
|
115
|
+
sheetsQueueRef.current[sheetsQueueRef.current.length - 1];
|
|
116
|
+
if (
|
|
117
|
+
sheetOnTop &&
|
|
118
|
+
hasMinimizedSheet &&
|
|
119
|
+
minimizedSheet &&
|
|
120
|
+
!minimizedSheet.willUnmount
|
|
121
|
+
) {
|
|
122
|
+
sheetsQueueRef.current[
|
|
123
|
+
sheetsQueueRef.current.length - 1
|
|
124
|
+
].ref?.current?.restore();
|
|
125
|
+
}
|
|
126
|
+
}, []);
|
|
127
|
+
const handleWillUnmountSheet = useCallback((key: string) => {
|
|
128
|
+
const _sheetsQueue = sheetsQueueRef.current.slice();
|
|
129
|
+
const sheetIndex = _sheetsQueue.findIndex(item => item.key === key);
|
|
130
|
+
const sheetOnTop = sheetIndex === _sheetsQueue.length - 1;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Here we mark the sheet that will unmount,
|
|
134
|
+
* so it won't be restored.
|
|
135
|
+
*/
|
|
136
|
+
if (sheetIndex !== -1) {
|
|
137
|
+
_sheetsQueue[sheetIndex].willUnmount = true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Here we try to restore previous sheet position,
|
|
142
|
+
* This is needed when user dismiss the modal by fire the dismiss action.
|
|
143
|
+
*/
|
|
144
|
+
const hasMinimizedSheet = _sheetsQueue.length > 1;
|
|
145
|
+
if (sheetOnTop && hasMinimizedSheet) {
|
|
146
|
+
_sheetsQueue[_sheetsQueue.length - 2].ref?.current?.restore();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
sheetsQueueRef.current = _sheetsQueue;
|
|
150
|
+
}, []);
|
|
151
|
+
//#endregion
|
|
152
|
+
|
|
153
|
+
//#region public methods
|
|
154
|
+
const handleDismiss = useCallback((key?: string) => {
|
|
155
|
+
const sheetToBeDismissed = key
|
|
156
|
+
? sheetsQueueRef.current.find(item => item.key === key)
|
|
157
|
+
: sheetsQueueRef.current[sheetsQueueRef.current.length - 1];
|
|
158
|
+
if (sheetToBeDismissed) {
|
|
159
|
+
sheetToBeDismissed.ref?.current?.dismiss();
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
}, []);
|
|
164
|
+
const handleDismissAll = useCallback(() => {
|
|
165
|
+
sheetsQueueRef.current.map(item => {
|
|
166
|
+
item.ref?.current?.dismiss();
|
|
167
|
+
});
|
|
168
|
+
}, []);
|
|
169
|
+
//#endregion
|
|
170
|
+
|
|
171
|
+
//#region context variables
|
|
172
|
+
const externalContextVariables = useMemo(
|
|
173
|
+
() => ({
|
|
174
|
+
dismiss: handleDismiss,
|
|
175
|
+
dismissAll: handleDismissAll,
|
|
176
|
+
}),
|
|
177
|
+
[handleDismiss, handleDismissAll]
|
|
178
|
+
);
|
|
179
|
+
const internalContextVariables = useMemo(
|
|
180
|
+
() => ({
|
|
181
|
+
hostName,
|
|
182
|
+
containerLayoutState: animatedContainerLayoutState,
|
|
183
|
+
mountSheet: handleMountSheet,
|
|
184
|
+
unmountSheet: handleUnmountSheet,
|
|
185
|
+
willUnmountSheet: handleWillUnmountSheet,
|
|
186
|
+
}),
|
|
187
|
+
[
|
|
188
|
+
hostName,
|
|
189
|
+
animatedContainerLayoutState,
|
|
190
|
+
handleMountSheet,
|
|
191
|
+
handleUnmountSheet,
|
|
192
|
+
handleWillUnmountSheet,
|
|
193
|
+
]
|
|
194
|
+
);
|
|
195
|
+
//#endregion
|
|
196
|
+
|
|
197
|
+
//#region renders
|
|
198
|
+
return (
|
|
199
|
+
<BottomSheetModalProvider value={externalContextVariables}>
|
|
200
|
+
<BottomSheetModalInternalProvider value={internalContextVariables}>
|
|
201
|
+
<BottomSheetHostingContainer
|
|
202
|
+
containerLayoutState={animatedContainerLayoutState}
|
|
203
|
+
/>
|
|
204
|
+
<PortalProvider rootHostName={hostName}>{children}</PortalProvider>
|
|
205
|
+
</BottomSheetModalInternalProvider>
|
|
206
|
+
</BottomSheetModalProvider>
|
|
207
|
+
);
|
|
208
|
+
//#endregion
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
export default BottomSheetModalProviderWrapper;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './BottomSheetModalProvider';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode, RefObject } from 'react';
|
|
2
|
+
import type { BottomSheetModalPrivateMethods } from '../bottomSheetModal';
|
|
3
|
+
|
|
4
|
+
export interface BottomSheetModalRef {
|
|
5
|
+
key: string;
|
|
6
|
+
ref: RefObject<BottomSheetModalPrivateMethods>;
|
|
7
|
+
willUnmount: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface BottomSheetModalProviderProps {
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React, { memo, useContext, useMemo } from 'react';
|
|
2
|
+
import { RefreshControl, type RefreshControlProps } from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
Gesture,
|
|
5
|
+
GestureDetector,
|
|
6
|
+
type SimultaneousGesture,
|
|
7
|
+
} from 'react-native-gesture-handler';
|
|
8
|
+
import Animated, { useAnimatedProps } from 'react-native-reanimated';
|
|
9
|
+
import { SCROLLABLE_STATUS } from '../../constants';
|
|
10
|
+
import { BottomSheetDraggableContext } from '../../contexts/gesture';
|
|
11
|
+
import { useBottomSheetInternal } from '../../hooks';
|
|
12
|
+
|
|
13
|
+
const AnimatedRefreshControl = Animated.createAnimatedComponent(RefreshControl);
|
|
14
|
+
|
|
15
|
+
interface BottomSheetRefreshControlProps extends RefreshControlProps {
|
|
16
|
+
scrollableGesture: SimultaneousGesture;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function BottomSheetRefreshControlComponent({
|
|
20
|
+
onRefresh,
|
|
21
|
+
scrollableGesture,
|
|
22
|
+
...rest
|
|
23
|
+
}: BottomSheetRefreshControlProps) {
|
|
24
|
+
//#region hooks
|
|
25
|
+
const draggableGesture = useContext(BottomSheetDraggableContext);
|
|
26
|
+
const {
|
|
27
|
+
animatedScrollableStatus: animatedScrollableState,
|
|
28
|
+
enableContentPanningGesture,
|
|
29
|
+
} = useBottomSheetInternal();
|
|
30
|
+
//#endregion
|
|
31
|
+
|
|
32
|
+
if (!draggableGesture && enableContentPanningGesture) {
|
|
33
|
+
throw "'BottomSheetRefreshControl' cannot be used out of the BottomSheet!";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//#region variables
|
|
37
|
+
const animatedProps = useAnimatedProps(
|
|
38
|
+
() => ({
|
|
39
|
+
enabled: animatedScrollableState.value === SCROLLABLE_STATUS.UNLOCKED,
|
|
40
|
+
}),
|
|
41
|
+
[animatedScrollableState.value]
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const gesture = useMemo(
|
|
45
|
+
() =>
|
|
46
|
+
draggableGesture
|
|
47
|
+
? Gesture.Native()
|
|
48
|
+
// @ts-ignore
|
|
49
|
+
.simultaneousWithExternalGesture(
|
|
50
|
+
...draggableGesture.toGestureArray(),
|
|
51
|
+
...scrollableGesture.toGestureArray()
|
|
52
|
+
)
|
|
53
|
+
.shouldCancelWhenOutside(true)
|
|
54
|
+
: undefined,
|
|
55
|
+
[draggableGesture, scrollableGesture]
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
|
|
60
|
+
// render
|
|
61
|
+
if (gesture) {
|
|
62
|
+
return (
|
|
63
|
+
<GestureDetector gesture={gesture}>
|
|
64
|
+
<AnimatedRefreshControl
|
|
65
|
+
{...rest}
|
|
66
|
+
onRefresh={onRefresh}
|
|
67
|
+
animatedProps={animatedProps}
|
|
68
|
+
/>
|
|
69
|
+
</GestureDetector>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
return (
|
|
73
|
+
<AnimatedRefreshControl
|
|
74
|
+
{...rest}
|
|
75
|
+
onRefresh={onRefresh}
|
|
76
|
+
animatedProps={animatedProps}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const BottomSheetRefreshControl = memo(BottomSheetRefreshControlComponent);
|
|
82
|
+
BottomSheetRefreshControl.displayName = 'BottomSheetRefreshControl';
|
|
83
|
+
|
|
84
|
+
export default BottomSheetRefreshControl;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default () => null;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { RefreshControlProps } from 'react-native';
|
|
3
|
+
import type {
|
|
4
|
+
NativeViewGestureHandlerProps,
|
|
5
|
+
SimultaneousGesture,
|
|
6
|
+
} from 'react-native-gesture-handler';
|
|
7
|
+
import BottomSheetRefreshControl from './BottomSheetRefreshControl';
|
|
8
|
+
|
|
9
|
+
export default BottomSheetRefreshControl as never as React.MemoExoticComponent<
|
|
10
|
+
React.ForwardRefExoticComponent<
|
|
11
|
+
RefreshControlProps & {
|
|
12
|
+
scrollableGesture: SimultaneousGesture;
|
|
13
|
+
children: React.ReactNode | React.ReactNode[];
|
|
14
|
+
} & React.RefAttributes<
|
|
15
|
+
React.ComponentType<
|
|
16
|
+
NativeViewGestureHandlerProps & React.RefAttributes<never>
|
|
17
|
+
>
|
|
18
|
+
>
|
|
19
|
+
>
|
|
20
|
+
>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
GestureDetector,
|
|
4
|
+
type SimultaneousGesture,
|
|
5
|
+
} from 'react-native-gesture-handler';
|
|
6
|
+
|
|
7
|
+
interface BottomSheetDraggableScrollableProps {
|
|
8
|
+
scrollableGesture?: SimultaneousGesture;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function BottomSheetDraggableScrollable({
|
|
13
|
+
scrollableGesture,
|
|
14
|
+
children,
|
|
15
|
+
}: BottomSheetDraggableScrollableProps) {
|
|
16
|
+
if (scrollableGesture) {
|
|
17
|
+
return (
|
|
18
|
+
<GestureDetector gesture={scrollableGesture}>{children}</GestureDetector>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return children;
|
|
23
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import type { FlashListProps } from '@shopify/flash-list';
|
|
3
|
+
import React, { forwardRef, memo, type Ref, useMemo } from 'react';
|
|
4
|
+
import type { ScrollViewProps } from 'react-native';
|
|
5
|
+
import type Animated from 'react-native-reanimated';
|
|
6
|
+
import BottomSheetScrollView from './BottomSheetScrollView';
|
|
7
|
+
import type {
|
|
8
|
+
BottomSheetScrollViewMethods,
|
|
9
|
+
BottomSheetScrollableProps,
|
|
10
|
+
} from './types';
|
|
11
|
+
|
|
12
|
+
let FlashList: {
|
|
13
|
+
FlashList: React.FC;
|
|
14
|
+
};
|
|
15
|
+
// since FlashList is not a dependency for the library
|
|
16
|
+
// we try to import it using metro optional import
|
|
17
|
+
try {
|
|
18
|
+
FlashList = require('@shopify/flash-list') as never;
|
|
19
|
+
} catch (_) {}
|
|
20
|
+
|
|
21
|
+
export type BottomSheetFlashListProps<T> = Omit<
|
|
22
|
+
Animated.AnimateProps<FlashListProps<T>>,
|
|
23
|
+
'decelerationRate' | 'onScroll' | 'scrollEventThrottle'
|
|
24
|
+
> &
|
|
25
|
+
BottomSheetScrollableProps & {
|
|
26
|
+
ref?: Ref<React.FC>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const BottomSheetFlashListComponent = forwardRef<
|
|
30
|
+
React.FC,
|
|
31
|
+
// biome-ignore lint/suspicious/noExplicitAny: to be addressed
|
|
32
|
+
BottomSheetFlashListProps<any>
|
|
33
|
+
>((props, ref) => {
|
|
34
|
+
//#region props
|
|
35
|
+
const {
|
|
36
|
+
focusHook,
|
|
37
|
+
scrollEventsHandlersHook,
|
|
38
|
+
enableFooterMarginAdjustment,
|
|
39
|
+
...rest
|
|
40
|
+
// biome-ignore lint: to be addressed!
|
|
41
|
+
}: any = props;
|
|
42
|
+
//#endregion
|
|
43
|
+
|
|
44
|
+
useMemo(() => {
|
|
45
|
+
if (!FlashList) {
|
|
46
|
+
throw 'You need to install FlashList first, `yarn install @shopify/flash-list`';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
console.warn(
|
|
50
|
+
'BottomSheetFlashList is deprecated, please use useBottomSheetScrollableCreator instead.'
|
|
51
|
+
);
|
|
52
|
+
}, []);
|
|
53
|
+
|
|
54
|
+
//#region render
|
|
55
|
+
const renderScrollComponent = useMemo(
|
|
56
|
+
() =>
|
|
57
|
+
forwardRef<BottomSheetScrollViewMethods, ScrollViewProps>(
|
|
58
|
+
// @ts-ignore
|
|
59
|
+
({ data, ...props }, ref) => {
|
|
60
|
+
return (
|
|
61
|
+
// @ts-ignore
|
|
62
|
+
<BottomSheetScrollView
|
|
63
|
+
ref={ref}
|
|
64
|
+
{...props}
|
|
65
|
+
focusHook={focusHook}
|
|
66
|
+
scrollEventsHandlersHook={scrollEventsHandlersHook}
|
|
67
|
+
enableFooterMarginAdjustment={enableFooterMarginAdjustment}
|
|
68
|
+
/>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
),
|
|
72
|
+
[focusHook, scrollEventsHandlersHook, enableFooterMarginAdjustment]
|
|
73
|
+
);
|
|
74
|
+
return (
|
|
75
|
+
<FlashList.FlashList
|
|
76
|
+
ref={ref}
|
|
77
|
+
renderScrollComponent={renderScrollComponent}
|
|
78
|
+
{...rest}
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
81
|
+
//#endregion
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export const BottomSheetFlashList = memo(BottomSheetFlashListComponent);
|
|
85
|
+
|
|
86
|
+
export default BottomSheetFlashList as <T>(
|
|
87
|
+
props: BottomSheetFlashListProps<T>
|
|
88
|
+
) => ReturnType<typeof BottomSheetFlashList>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default () => null;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ComponentProps, memo } from 'react';
|
|
2
|
+
import { FlatList as RNFlatList } from 'react-native';
|
|
3
|
+
import Animated from 'react-native-reanimated';
|
|
4
|
+
import { SCROLLABLE_TYPE } from '../../constants';
|
|
5
|
+
import { createBottomSheetScrollableComponent } from './createBottomSheetScrollableComponent';
|
|
6
|
+
import type {
|
|
7
|
+
BottomSheetFlatListMethods,
|
|
8
|
+
BottomSheetFlatListProps,
|
|
9
|
+
} from './types';
|
|
10
|
+
|
|
11
|
+
const AnimatedFlatList =
|
|
12
|
+
Animated.createAnimatedComponent<ComponentProps<typeof RNFlatList>>(
|
|
13
|
+
RNFlatList
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const BottomSheetFlatListComponent = createBottomSheetScrollableComponent<
|
|
17
|
+
BottomSheetFlatListMethods,
|
|
18
|
+
BottomSheetFlatListProps<never>
|
|
19
|
+
>(SCROLLABLE_TYPE.FLATLIST, AnimatedFlatList);
|
|
20
|
+
|
|
21
|
+
const BottomSheetFlatList = memo(BottomSheetFlatListComponent);
|
|
22
|
+
BottomSheetFlatList.displayName = 'BottomSheetFlatList';
|
|
23
|
+
|
|
24
|
+
export default BottomSheetFlatList as <T>(
|
|
25
|
+
props: BottomSheetFlatListProps<T>
|
|
26
|
+
) => ReturnType<typeof BottomSheetFlatList>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { memo } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
ScrollView as RNScrollView,
|
|
4
|
+
type ScrollViewProps as RNScrollViewProps,
|
|
5
|
+
} from 'react-native';
|
|
6
|
+
import Animated from 'react-native-reanimated';
|
|
7
|
+
import { SCROLLABLE_TYPE } from '../../constants';
|
|
8
|
+
import { createBottomSheetScrollableComponent } from './createBottomSheetScrollableComponent';
|
|
9
|
+
import type {
|
|
10
|
+
BottomSheetScrollViewMethods,
|
|
11
|
+
BottomSheetScrollViewProps,
|
|
12
|
+
} from './types';
|
|
13
|
+
|
|
14
|
+
const AnimatedScrollView =
|
|
15
|
+
Animated.createAnimatedComponent<RNScrollViewProps>(RNScrollView);
|
|
16
|
+
|
|
17
|
+
const BottomSheetScrollViewComponent = createBottomSheetScrollableComponent<
|
|
18
|
+
BottomSheetScrollViewMethods,
|
|
19
|
+
BottomSheetScrollViewProps
|
|
20
|
+
>(SCROLLABLE_TYPE.SCROLLVIEW, AnimatedScrollView);
|
|
21
|
+
|
|
22
|
+
const BottomSheetScrollView = memo(BottomSheetScrollViewComponent);
|
|
23
|
+
BottomSheetScrollView.displayName = 'BottomSheetScrollView';
|
|
24
|
+
|
|
25
|
+
export default BottomSheetScrollView as (
|
|
26
|
+
props: BottomSheetScrollViewProps
|
|
27
|
+
) => ReturnType<typeof BottomSheetScrollView>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ComponentProps, memo } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
type DefaultSectionT,
|
|
4
|
+
SectionList as RNSectionList,
|
|
5
|
+
} from 'react-native';
|
|
6
|
+
import Animated from 'react-native-reanimated';
|
|
7
|
+
import { SCROLLABLE_TYPE } from '../../constants';
|
|
8
|
+
import { createBottomSheetScrollableComponent } from './createBottomSheetScrollableComponent';
|
|
9
|
+
import type {
|
|
10
|
+
BottomSheetSectionListMethods,
|
|
11
|
+
BottomSheetSectionListProps,
|
|
12
|
+
} from './types';
|
|
13
|
+
|
|
14
|
+
const AnimatedSectionList =
|
|
15
|
+
Animated.createAnimatedComponent<ComponentProps<typeof RNSectionList>>(
|
|
16
|
+
RNSectionList
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const BottomSheetSectionListComponent = createBottomSheetScrollableComponent<
|
|
20
|
+
BottomSheetSectionListMethods,
|
|
21
|
+
BottomSheetSectionListProps<never, DefaultSectionT>
|
|
22
|
+
>(SCROLLABLE_TYPE.SECTIONLIST, AnimatedSectionList);
|
|
23
|
+
|
|
24
|
+
const BottomSheetSectionList = memo(BottomSheetSectionListComponent);
|
|
25
|
+
BottomSheetSectionList.displayName = 'BottomSheetSectionList';
|
|
26
|
+
|
|
27
|
+
export default BottomSheetSectionList as <ItemT, SectionT = DefaultSectionT>(
|
|
28
|
+
props: BottomSheetSectionListProps<ItemT, SectionT>
|
|
29
|
+
) => ReturnType<typeof BottomSheetSectionList>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ComponentProps, memo } from 'react';
|
|
2
|
+
import { VirtualizedList as RNVirtualizedList } from 'react-native';
|
|
3
|
+
import Animated from 'react-native-reanimated';
|
|
4
|
+
import { SCROLLABLE_TYPE } from '../../constants';
|
|
5
|
+
import { createBottomSheetScrollableComponent } from './createBottomSheetScrollableComponent';
|
|
6
|
+
import type {
|
|
7
|
+
BottomSheetVirtualizedListMethods,
|
|
8
|
+
BottomSheetVirtualizedListProps,
|
|
9
|
+
} from './types';
|
|
10
|
+
|
|
11
|
+
const AnimatedVirtualizedList =
|
|
12
|
+
Animated.createAnimatedComponent<ComponentProps<typeof RNVirtualizedList>>(
|
|
13
|
+
RNVirtualizedList
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const BottomSheetVirtualizedListComponent =
|
|
17
|
+
createBottomSheetScrollableComponent<
|
|
18
|
+
BottomSheetVirtualizedListMethods,
|
|
19
|
+
BottomSheetVirtualizedListProps<never>
|
|
20
|
+
>(SCROLLABLE_TYPE.VIRTUALIZEDLIST, AnimatedVirtualizedList);
|
|
21
|
+
|
|
22
|
+
const BottomSheetVirtualizedList = memo(BottomSheetVirtualizedListComponent);
|
|
23
|
+
BottomSheetVirtualizedList.displayName = 'BottomSheetVirtualizedList';
|
|
24
|
+
|
|
25
|
+
export default BottomSheetVirtualizedList as <T>(
|
|
26
|
+
props: BottomSheetVirtualizedListProps<T>
|
|
27
|
+
) => ReturnType<typeof BottomSheetVirtualizedList>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import type { SimultaneousGesture } from 'react-native-gesture-handler';
|
|
3
|
+
import BottomSheetRefreshControl from '../bottomSheetRefreshControl';
|
|
4
|
+
import { BottomSheetDraggableScrollable } from './BottomSheetDraggableScrollable';
|
|
5
|
+
import { styles } from './styles';
|
|
6
|
+
|
|
7
|
+
interface ScrollableContainerProps {
|
|
8
|
+
nativeGesture: SimultaneousGesture;
|
|
9
|
+
// biome-ignore lint: to be addressed
|
|
10
|
+
refreshControl: any;
|
|
11
|
+
// biome-ignore lint: to be addressed
|
|
12
|
+
progressViewOffset: any;
|
|
13
|
+
// biome-ignore lint: to be addressed
|
|
14
|
+
refreshing: any;
|
|
15
|
+
// biome-ignore lint: to be addressed
|
|
16
|
+
onRefresh: any;
|
|
17
|
+
// biome-ignore lint: to be addressed
|
|
18
|
+
ScrollableComponent: any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// biome-ignore lint: to be addressed
|
|
22
|
+
export const ScrollableContainer = forwardRef<any, ScrollableContainerProps>(
|
|
23
|
+
function ScrollableContainer(
|
|
24
|
+
{
|
|
25
|
+
nativeGesture,
|
|
26
|
+
refreshControl: _refreshControl,
|
|
27
|
+
refreshing,
|
|
28
|
+
progressViewOffset,
|
|
29
|
+
onRefresh,
|
|
30
|
+
ScrollableComponent,
|
|
31
|
+
...rest
|
|
32
|
+
},
|
|
33
|
+
ref
|
|
34
|
+
) {
|
|
35
|
+
const Scrollable = (
|
|
36
|
+
<BottomSheetDraggableScrollable scrollableGesture={nativeGesture}>
|
|
37
|
+
<ScrollableComponent ref={ref} {...rest} />
|
|
38
|
+
</BottomSheetDraggableScrollable>
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
return onRefresh ? (
|
|
42
|
+
<BottomSheetRefreshControl
|
|
43
|
+
scrollableGesture={nativeGesture}
|
|
44
|
+
refreshing={refreshing}
|
|
45
|
+
progressViewOffset={progressViewOffset}
|
|
46
|
+
onRefresh={onRefresh}
|
|
47
|
+
style={styles.container}
|
|
48
|
+
>
|
|
49
|
+
{Scrollable}
|
|
50
|
+
</BottomSheetRefreshControl>
|
|
51
|
+
) : (
|
|
52
|
+
Scrollable
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { type FC, forwardRef } from 'react';
|
|
2
|
+
import type { SimultaneousGesture } from 'react-native-gesture-handler';
|
|
3
|
+
import { BottomSheetDraggableScrollable } from './BottomSheetDraggableScrollable';
|
|
4
|
+
|
|
5
|
+
interface ScrollableContainerProps {
|
|
6
|
+
nativeGesture?: SimultaneousGesture;
|
|
7
|
+
// biome-ignore lint/suspicious/noExplicitAny: 🤷♂️
|
|
8
|
+
ScrollableComponent: FC<any>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const ScrollableContainer = forwardRef<never, ScrollableContainerProps>(
|
|
12
|
+
function ScrollableContainer(
|
|
13
|
+
{ nativeGesture, ScrollableComponent, ...rest },
|
|
14
|
+
ref
|
|
15
|
+
) {
|
|
16
|
+
return (
|
|
17
|
+
<BottomSheetDraggableScrollable scrollableGesture={nativeGesture}>
|
|
18
|
+
<ScrollableComponent ref={ref} {...rest} />
|
|
19
|
+
</BottomSheetDraggableScrollable>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
);
|