stream-chat-react-native-core 9.0.0-beta.27 → 9.0.0-beta.29
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/lib/commonjs/components/Attachment/Gallery.js +29 -9
- package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
- package/lib/commonjs/components/Attachment/Giphy/GiphyImage.js +4 -4
- package/lib/commonjs/components/Attachment/Giphy/GiphyImage.js.map +1 -1
- package/lib/commonjs/components/Attachment/ImageLoadingFailedIndicator.js +3 -3
- package/lib/commonjs/components/Attachment/ImageLoadingFailedIndicator.js.map +1 -1
- package/lib/commonjs/components/Attachment/ImageLoadingIndicator.js +1 -1
- package/lib/commonjs/components/Attachment/ImageLoadingIndicator.js.map +1 -1
- package/lib/commonjs/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentPickerItem.js +2 -2
- package/lib/commonjs/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentPickerItem.js.map +1 -1
- package/lib/commonjs/components/Channel/Channel.js +1 -1
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/ChannelList/Skeleton.js +1 -1
- package/lib/commonjs/components/ChannelList/Skeleton.js.map +1 -1
- package/lib/commonjs/components/ChannelList/hooks/useChannelActionItems.js +0 -15
- package/lib/commonjs/components/ChannelList/hooks/useChannelActionItems.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelDetailsBottomSheet.js +14 -12
- package/lib/commonjs/components/ChannelPreview/ChannelDetailsBottomSheet.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewView.js +1 -0
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewView.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelSwipableWrapper.js +11 -9
- package/lib/commonjs/components/ChannelPreview/ChannelSwipableWrapper.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/ImageGallery.js +3 -3
- package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/commonjs/components/Message/Message.js +2 -1
- package/lib/commonjs/components/Message/Message.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageItemView.js +7 -3
- package/lib/commonjs/components/Message/MessageItemView/MessageItemView.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js +3 -1
- package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js.map +1 -1
- package/lib/commonjs/components/MessageInput/components/AttachmentPreview/ImageAttachmentUploadPreview.js +1 -1
- package/lib/commonjs/components/MessageInput/components/AttachmentPreview/ImageAttachmentUploadPreview.js.map +1 -1
- package/lib/commonjs/components/MessageMenu/MessageUserReactions.js +0 -1
- package/lib/commonjs/components/MessageMenu/MessageUserReactions.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollInputDialog.js +1 -1
- package/lib/commonjs/components/Poll/components/PollInputDialog.js.map +1 -1
- package/lib/commonjs/components/Reply/Reply.js +2 -2
- package/lib/commonjs/components/Reply/Reply.js.map +1 -1
- package/lib/commonjs/components/ThreadList/ThreadListItemSkeleton.js +1 -1
- package/lib/commonjs/components/ThreadList/ThreadListItemSkeleton.js.map +1 -1
- package/lib/commonjs/components/UIComponents/BottomSheetModal.js +145 -44
- package/lib/commonjs/components/UIComponents/BottomSheetModal.js.map +1 -1
- package/lib/commonjs/components/UIComponents/BottomSheetModal.utils.js +53 -0
- package/lib/commonjs/components/UIComponents/BottomSheetModal.utils.js.map +1 -0
- package/lib/commonjs/components/UIComponents/StreamBottomSheetModalFlatList.js +9 -5
- package/lib/commonjs/components/UIComponents/StreamBottomSheetModalFlatList.js.map +1 -1
- package/lib/commonjs/components/ui/Avatar/ChannelAvatar.js +1 -1
- package/lib/commonjs/components/ui/Avatar/ChannelAvatar.js.map +1 -1
- package/lib/commonjs/contexts/bottomSheetContext/BottomSheetContext.js.map +1 -1
- package/lib/commonjs/contexts/messageComposerContext/MessageComposerContext.js +4 -4
- package/lib/commonjs/contexts/messageComposerContext/MessageComposerContext.js.map +1 -1
- package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
- package/lib/commonjs/contexts/overlayContext/ClosingPortalHostsLayer.js +10 -1
- package/lib/commonjs/contexts/overlayContext/ClosingPortalHostsLayer.js.map +1 -1
- package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js +16 -7
- package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
- package/lib/commonjs/hooks/messagePreview/useMessagePreviewText.js +4 -4
- package/lib/commonjs/hooks/messagePreview/useMessagePreviewText.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Attachment/Gallery.js +29 -9
- package/lib/module/components/Attachment/Gallery.js.map +1 -1
- package/lib/module/components/Attachment/Giphy/GiphyImage.js +4 -4
- package/lib/module/components/Attachment/Giphy/GiphyImage.js.map +1 -1
- package/lib/module/components/Attachment/ImageLoadingFailedIndicator.js +3 -3
- package/lib/module/components/Attachment/ImageLoadingFailedIndicator.js.map +1 -1
- package/lib/module/components/Attachment/ImageLoadingIndicator.js +1 -1
- package/lib/module/components/Attachment/ImageLoadingIndicator.js.map +1 -1
- package/lib/module/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentPickerItem.js +2 -2
- package/lib/module/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentPickerItem.js.map +1 -1
- package/lib/module/components/Channel/Channel.js +1 -1
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/ChannelList/Skeleton.js +1 -1
- package/lib/module/components/ChannelList/Skeleton.js.map +1 -1
- package/lib/module/components/ChannelList/hooks/useChannelActionItems.js +0 -15
- package/lib/module/components/ChannelList/hooks/useChannelActionItems.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelDetailsBottomSheet.js +14 -12
- package/lib/module/components/ChannelPreview/ChannelDetailsBottomSheet.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreviewView.js +1 -0
- package/lib/module/components/ChannelPreview/ChannelPreviewView.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelSwipableWrapper.js +11 -9
- package/lib/module/components/ChannelPreview/ChannelSwipableWrapper.js.map +1 -1
- package/lib/module/components/ImageGallery/ImageGallery.js +3 -3
- package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/module/components/Message/Message.js +2 -1
- package/lib/module/components/Message/Message.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageItemView.js +7 -3
- package/lib/module/components/Message/MessageItemView/MessageItemView.js.map +1 -1
- package/lib/module/components/Message/hooks/useCreateMessageContext.js +3 -1
- package/lib/module/components/Message/hooks/useCreateMessageContext.js.map +1 -1
- package/lib/module/components/MessageInput/components/AttachmentPreview/ImageAttachmentUploadPreview.js +1 -1
- package/lib/module/components/MessageInput/components/AttachmentPreview/ImageAttachmentUploadPreview.js.map +1 -1
- package/lib/module/components/MessageMenu/MessageUserReactions.js +0 -1
- package/lib/module/components/MessageMenu/MessageUserReactions.js.map +1 -1
- package/lib/module/components/Poll/components/PollInputDialog.js +1 -1
- package/lib/module/components/Poll/components/PollInputDialog.js.map +1 -1
- package/lib/module/components/Reply/Reply.js +2 -2
- package/lib/module/components/Reply/Reply.js.map +1 -1
- package/lib/module/components/ThreadList/ThreadListItemSkeleton.js +1 -1
- package/lib/module/components/ThreadList/ThreadListItemSkeleton.js.map +1 -1
- package/lib/module/components/UIComponents/BottomSheetModal.js +145 -44
- package/lib/module/components/UIComponents/BottomSheetModal.js.map +1 -1
- package/lib/module/components/UIComponents/BottomSheetModal.utils.js +53 -0
- package/lib/module/components/UIComponents/BottomSheetModal.utils.js.map +1 -0
- package/lib/module/components/UIComponents/StreamBottomSheetModalFlatList.js +9 -5
- package/lib/module/components/UIComponents/StreamBottomSheetModalFlatList.js.map +1 -1
- package/lib/module/components/ui/Avatar/ChannelAvatar.js +1 -1
- package/lib/module/components/ui/Avatar/ChannelAvatar.js.map +1 -1
- package/lib/module/contexts/bottomSheetContext/BottomSheetContext.js.map +1 -1
- package/lib/module/contexts/messageComposerContext/MessageComposerContext.js +4 -4
- package/lib/module/contexts/messageComposerContext/MessageComposerContext.js.map +1 -1
- package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
- package/lib/module/contexts/overlayContext/ClosingPortalHostsLayer.js +10 -1
- package/lib/module/contexts/overlayContext/ClosingPortalHostsLayer.js.map +1 -1
- package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js +16 -7
- package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
- package/lib/module/hooks/messagePreview/useMessagePreviewText.js +4 -4
- package/lib/module/hooks/messagePreview/useMessagePreviewText.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Attachment/Giphy/GiphyImage.d.ts.map +1 -1
- package/lib/typescript/components/ChannelList/hooks/useChannelActionItems.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelDetailsBottomSheet.d.ts +2 -2
- package/lib/typescript/components/ChannelPreview/ChannelDetailsBottomSheet.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelPreviewStatus.d.ts +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelPreviewStatus.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelPreviewView.d.ts +2 -2
- package/lib/typescript/components/ChannelPreview/ChannelPreviewView.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelSwipableWrapper.d.ts +3 -3
- package/lib/typescript/components/ChannelPreview/ChannelSwipableWrapper.d.ts.map +1 -1
- package/lib/typescript/components/Message/Message.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageItemView.d.ts +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageItemView.d.ts.map +1 -1
- package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts +1 -1
- package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts.map +1 -1
- package/lib/typescript/components/MessageMenu/MessageUserReactions.d.ts.map +1 -1
- package/lib/typescript/components/UIComponents/BottomSheetModal.d.ts +5 -1
- package/lib/typescript/components/UIComponents/BottomSheetModal.d.ts.map +1 -1
- package/lib/typescript/components/UIComponents/BottomSheetModal.utils.d.ts +28 -0
- package/lib/typescript/components/UIComponents/BottomSheetModal.utils.d.ts.map +1 -0
- package/lib/typescript/components/UIComponents/StreamBottomSheetModalFlatList.d.ts.map +1 -1
- package/lib/typescript/components/ui/Avatar/ChannelAvatar.d.ts.map +1 -1
- package/lib/typescript/contexts/bottomSheetContext/BottomSheetContext.d.ts +1 -0
- package/lib/typescript/contexts/bottomSheetContext/BottomSheetContext.d.ts.map +1 -1
- package/lib/typescript/contexts/messageContext/MessageContext.d.ts +4 -2
- package/lib/typescript/contexts/messageContext/MessageContext.d.ts.map +1 -1
- package/lib/typescript/contexts/overlayContext/MessageOverlayHostLayer.d.ts.map +1 -1
- package/lib/typescript/hooks/messagePreview/useMessagePreviewText.d.ts.map +1 -1
- package/package.json +2 -4
- package/src/components/Attachment/Gallery.tsx +21 -5
- package/src/components/Attachment/Giphy/GiphyImage.tsx +6 -3
- package/src/components/Attachment/ImageLoadingFailedIndicator.tsx +1 -2
- package/src/components/Attachment/ImageLoadingIndicator.tsx +1 -1
- package/src/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentPickerItem.tsx +2 -2
- package/src/components/Channel/Channel.tsx +1 -1
- package/src/components/ChannelList/Skeleton.tsx +1 -1
- package/src/components/ChannelList/hooks/__tests__/useChannelActionItems.test.tsx +12 -45
- package/src/components/ChannelList/hooks/useChannelActionItems.tsx +1 -19
- package/src/components/ChannelPreview/ChannelDetailsBottomSheet.tsx +9 -7
- package/src/components/ChannelPreview/ChannelPreviewStatus.tsx +1 -1
- package/src/components/ChannelPreview/ChannelPreviewView.tsx +3 -2
- package/src/components/ChannelPreview/ChannelSwipableWrapper.tsx +8 -7
- package/src/components/ChannelPreview/__tests__/ChannelDetailsBottomSheet.test.tsx +1 -1
- package/src/components/ChannelPreview/__tests__/ChannelLastMessagePreview.test.tsx +32 -0
- package/src/components/ChannelPreview/__tests__/ChannelSwipableWrapper.test.tsx +5 -2
- package/src/components/ImageGallery/ImageGallery.tsx +3 -3
- package/src/components/Message/Message.tsx +2 -1
- package/src/components/Message/MessageItemView/MessageItemView.tsx +8 -3
- package/src/components/Message/MessageItemView/__tests__/MessageContent.test.js +28 -0
- package/src/components/Message/MessageItemView/__tests__/MessageItemView.test.js +32 -1
- package/src/components/Message/hooks/useCreateMessageContext.ts +3 -0
- package/src/components/MessageInput/components/AttachmentPreview/ImageAttachmentUploadPreview.tsx +1 -1
- package/src/components/MessageMenu/MessageUserReactions.tsx +1 -5
- package/src/components/Poll/components/PollInputDialog.tsx +1 -1
- package/src/components/Reply/Reply.tsx +2 -2
- package/src/components/ThreadList/ThreadListItemSkeleton.tsx +1 -1
- package/src/components/UIComponents/BottomSheetModal.tsx +242 -56
- package/src/components/UIComponents/BottomSheetModal.utils.ts +82 -0
- package/src/components/UIComponents/StreamBottomSheetModalFlatList.tsx +14 -5
- package/src/components/UIComponents/__tests__/BottomSheetModal.utils.test.ts +111 -0
- package/src/components/ui/Avatar/ChannelAvatar.tsx +5 -1
- package/src/contexts/bottomSheetContext/BottomSheetContext.tsx +1 -0
- package/src/contexts/messageComposerContext/MessageComposerContext.tsx +1 -1
- package/src/contexts/messageContext/MessageContext.tsx +4 -2
- package/src/contexts/overlayContext/ClosingPortalHostsLayer.tsx +11 -1
- package/src/contexts/overlayContext/MessageOverlayHostLayer.tsx +17 -10
- package/src/hooks/messagePreview/useMessagePreviewText.tsx +5 -6
- package/src/version.json +1 -1
- package/bin/patch-bottom-sheet-5.1.8-pr-2561.js +0 -246
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
EventSubscription,
|
|
11
11
|
Keyboard,
|
|
12
12
|
KeyboardEvent,
|
|
13
|
+
LayoutChangeEvent,
|
|
13
14
|
Modal,
|
|
14
15
|
Platform,
|
|
15
16
|
Pressable,
|
|
@@ -23,12 +24,20 @@ import Animated, {
|
|
|
23
24
|
Easing,
|
|
24
25
|
FadeIn,
|
|
25
26
|
runOnJS,
|
|
27
|
+
useAnimatedReaction,
|
|
26
28
|
useAnimatedStyle,
|
|
29
|
+
useDerivedValue,
|
|
27
30
|
useSharedValue,
|
|
28
31
|
withTiming,
|
|
29
32
|
} from 'react-native-reanimated';
|
|
30
33
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
31
34
|
|
|
35
|
+
import {
|
|
36
|
+
getBottomSheetBaseHeight,
|
|
37
|
+
getBottomSheetSnapPointTranslateY,
|
|
38
|
+
getBottomSheetTopSnapIndex,
|
|
39
|
+
} from './BottomSheetModal.utils';
|
|
40
|
+
|
|
32
41
|
import { BottomSheetProvider } from '../../contexts/bottomSheetContext/BottomSheetContext';
|
|
33
42
|
import { useTheme } from '../../contexts/themeContext/ThemeContext';
|
|
34
43
|
import { useStableCallback } from '../../hooks';
|
|
@@ -49,6 +58,10 @@ export type BottomSheetModalProps = {
|
|
|
49
58
|
* The height of the modal.
|
|
50
59
|
*/
|
|
51
60
|
height?: number;
|
|
61
|
+
/**
|
|
62
|
+
* Whether the sheet should wrap its content up to the provided `height`.
|
|
63
|
+
*/
|
|
64
|
+
enableDynamicSizing?: boolean;
|
|
52
65
|
/**
|
|
53
66
|
* Whether the sheet content should be lazy loaded or not. Particularly
|
|
54
67
|
* useful when the content is something heavy and we don't want to disrupt
|
|
@@ -57,10 +70,17 @@ export type BottomSheetModalProps = {
|
|
|
57
70
|
lazy?: boolean;
|
|
58
71
|
};
|
|
59
72
|
|
|
60
|
-
|
|
73
|
+
const BottomSheetModalInner = (props: PropsWithChildren<BottomSheetModalProps>) => {
|
|
61
74
|
const { height: windowHeight } = useWindowDimensions();
|
|
62
75
|
const { top: topInset, bottom: bottomInset } = useSafeAreaInsets();
|
|
63
|
-
const {
|
|
76
|
+
const {
|
|
77
|
+
children,
|
|
78
|
+
enableDynamicSizing = false,
|
|
79
|
+
height = windowHeight / 2,
|
|
80
|
+
onClose,
|
|
81
|
+
visible,
|
|
82
|
+
lazy = false,
|
|
83
|
+
} = props;
|
|
64
84
|
|
|
65
85
|
const {
|
|
66
86
|
theme: {
|
|
@@ -73,12 +93,26 @@ export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>
|
|
|
73
93
|
0,
|
|
74
94
|
windowHeight - topInset - (Platform.OS === 'android' ? bottomInset + 16 : 0),
|
|
75
95
|
);
|
|
96
|
+
const fixedBaseHeight = Math.min(height, maxHeight);
|
|
76
97
|
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
98
|
+
const contentHeight = useSharedValue<number | undefined>(undefined);
|
|
99
|
+
const baseHeight = useDerivedValue(
|
|
100
|
+
() =>
|
|
101
|
+
getBottomSheetBaseHeight({
|
|
102
|
+
contentHeight: contentHeight.value,
|
|
103
|
+
enableDynamicSizing,
|
|
104
|
+
height,
|
|
105
|
+
maxHeight,
|
|
106
|
+
}),
|
|
107
|
+
[contentHeight, enableDynamicSizing, height, maxHeight],
|
|
108
|
+
);
|
|
109
|
+
const topSnapIndex = useDerivedValue<number>(
|
|
110
|
+
() =>
|
|
111
|
+
getBottomSheetTopSnapIndex({
|
|
112
|
+
baseHeight: baseHeight.value,
|
|
113
|
+
maxHeight,
|
|
114
|
+
}),
|
|
115
|
+
[baseHeight, maxHeight],
|
|
82
116
|
);
|
|
83
117
|
|
|
84
118
|
const sheetTranslateY = useSharedValue(maxHeight);
|
|
@@ -100,6 +134,36 @@ export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>
|
|
|
100
134
|
}
|
|
101
135
|
});
|
|
102
136
|
|
|
137
|
+
const handleDynamicContentLayout = useStableCallback((event: LayoutChangeEvent) => {
|
|
138
|
+
if (!enableDynamicSizing) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const nextContentHeight = Math.ceil(event.nativeEvent.layout.height);
|
|
143
|
+
|
|
144
|
+
if (contentHeight.value === nextContentHeight) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
contentHeight.value = nextContentHeight;
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const open = useStableCallback((shouldShowContentAfterOpen = true) => {
|
|
152
|
+
sheetTranslateY.value = withTiming(
|
|
153
|
+
maxHeight - fixedBaseHeight,
|
|
154
|
+
{ duration: 250, easing: Easing.out(Easing.cubic) },
|
|
155
|
+
(finished) => {
|
|
156
|
+
if (!finished) return;
|
|
157
|
+
|
|
158
|
+
isOpening.value = false;
|
|
159
|
+
|
|
160
|
+
if (shouldShowContentAfterOpen) {
|
|
161
|
+
runOnJS(showContent)();
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
);
|
|
165
|
+
});
|
|
166
|
+
|
|
103
167
|
const finishClose = useStableCallback((closeAnimationFinishedCallback?: () => void) => {
|
|
104
168
|
onClose();
|
|
105
169
|
if (closeAnimationFinishedCallback) {
|
|
@@ -161,27 +225,66 @@ export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>
|
|
|
161
225
|
currentSnapIndex.value = 0;
|
|
162
226
|
sheetTranslateY.value = maxHeight;
|
|
163
227
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if (!finished) return;
|
|
228
|
+
if (enableDynamicSizing) {
|
|
229
|
+
setRenderContent(true);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
169
232
|
|
|
170
|
-
|
|
171
|
-
runOnJS(showContent)();
|
|
172
|
-
},
|
|
173
|
-
);
|
|
233
|
+
open();
|
|
174
234
|
}, [
|
|
235
|
+
enableDynamicSizing,
|
|
175
236
|
visible,
|
|
176
237
|
isOpen,
|
|
177
238
|
isOpening,
|
|
178
239
|
maxHeight,
|
|
179
|
-
|
|
240
|
+
open,
|
|
180
241
|
sheetTranslateY,
|
|
181
242
|
currentSnapIndex,
|
|
182
|
-
snapPointsTranslateY,
|
|
183
243
|
]);
|
|
184
244
|
|
|
245
|
+
useAnimatedReaction(
|
|
246
|
+
() => {
|
|
247
|
+
if (
|
|
248
|
+
!visible ||
|
|
249
|
+
!enableDynamicSizing ||
|
|
250
|
+
!isOpening.value ||
|
|
251
|
+
contentHeight.value === undefined
|
|
252
|
+
) {
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return getBottomSheetSnapPointTranslateY({
|
|
257
|
+
baseHeight: baseHeight.value,
|
|
258
|
+
maxHeight,
|
|
259
|
+
snapIndex: 0,
|
|
260
|
+
});
|
|
261
|
+
},
|
|
262
|
+
(nextTranslateY, prevTranslateY) => {
|
|
263
|
+
if (nextTranslateY === undefined || nextTranslateY === prevTranslateY) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
sheetTranslateY.value = withTiming(
|
|
268
|
+
nextTranslateY,
|
|
269
|
+
{ duration: 250, easing: Easing.out(Easing.cubic) },
|
|
270
|
+
(finished) => {
|
|
271
|
+
if (finished) {
|
|
272
|
+
isOpening.value = false;
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
);
|
|
276
|
+
},
|
|
277
|
+
[
|
|
278
|
+
baseHeight,
|
|
279
|
+
contentHeight,
|
|
280
|
+
enableDynamicSizing,
|
|
281
|
+
isOpening,
|
|
282
|
+
maxHeight,
|
|
283
|
+
sheetTranslateY,
|
|
284
|
+
visible,
|
|
285
|
+
],
|
|
286
|
+
);
|
|
287
|
+
|
|
185
288
|
// if `visible` gets hard changed, we force a cleanup
|
|
186
289
|
useEffect(() => {
|
|
187
290
|
if (visible) return;
|
|
@@ -191,8 +294,10 @@ export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>
|
|
|
191
294
|
keyboardOffset.value = 0;
|
|
192
295
|
currentSnapIndex.value = 0;
|
|
193
296
|
sheetTranslateY.value = maxHeight;
|
|
297
|
+
contentHeight.value = undefined;
|
|
194
298
|
setRenderContent(!lazy);
|
|
195
299
|
}, [
|
|
300
|
+
contentHeight,
|
|
196
301
|
visible,
|
|
197
302
|
lazy,
|
|
198
303
|
isOpen,
|
|
@@ -204,16 +309,52 @@ export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>
|
|
|
204
309
|
]);
|
|
205
310
|
|
|
206
311
|
// Keep the sheet aligned with the active snap if dimensions change while visible.
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
312
|
+
useAnimatedReaction(
|
|
313
|
+
() => {
|
|
314
|
+
if (!visible || !isOpen.value || isOpening.value) {
|
|
315
|
+
return undefined;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const clampedSnapIndex = Math.min(currentSnapIndex.value, topSnapIndex.value);
|
|
319
|
+
|
|
320
|
+
return {
|
|
321
|
+
snapIndex: clampedSnapIndex,
|
|
322
|
+
translateY: getBottomSheetSnapPointTranslateY({
|
|
323
|
+
baseHeight: baseHeight.value,
|
|
324
|
+
maxHeight,
|
|
325
|
+
snapIndex: clampedSnapIndex,
|
|
326
|
+
}),
|
|
327
|
+
};
|
|
328
|
+
},
|
|
329
|
+
(nextTarget) => {
|
|
330
|
+
if (!nextTarget) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (currentSnapIndex.value !== nextTarget.snapIndex) {
|
|
335
|
+
currentSnapIndex.value = nextTarget.snapIndex;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (Math.abs(sheetTranslateY.value - nextTarget.translateY) < 1) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
sheetTranslateY.value = withTiming(nextTarget.translateY, {
|
|
343
|
+
duration: 250,
|
|
344
|
+
easing: Easing.inOut(Easing.ease),
|
|
345
|
+
});
|
|
346
|
+
},
|
|
347
|
+
[
|
|
348
|
+
baseHeight,
|
|
349
|
+
currentSnapIndex,
|
|
350
|
+
isOpen,
|
|
351
|
+
isOpening,
|
|
352
|
+
maxHeight,
|
|
353
|
+
sheetTranslateY,
|
|
354
|
+
topSnapIndex,
|
|
355
|
+
visible,
|
|
356
|
+
],
|
|
357
|
+
);
|
|
217
358
|
|
|
218
359
|
const animateKeyboardOffset = useStableCallback((offset: number) => {
|
|
219
360
|
keyboardOffset.value = withTiming(offset, {
|
|
@@ -258,10 +399,10 @@ export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>
|
|
|
258
399
|
|
|
259
400
|
const overlayAnimatedStyle = useAnimatedStyle(() => {
|
|
260
401
|
const visibleHeight = Math.max(0, maxHeight - sheetTranslateY.value);
|
|
261
|
-
const threshold = Math.max(1, Math.min(baseHeight, maxHeight));
|
|
402
|
+
const threshold = Math.max(1, Math.min(baseHeight.value, maxHeight));
|
|
262
403
|
const progress = Math.min(1, visibleHeight / threshold);
|
|
263
404
|
return { opacity: progress };
|
|
264
|
-
});
|
|
405
|
+
}, [baseHeight, maxHeight]);
|
|
265
406
|
|
|
266
407
|
const panGesture = useMemo(
|
|
267
408
|
() =>
|
|
@@ -275,11 +416,24 @@ export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>
|
|
|
275
416
|
sheetTranslateY.value = Math.min(Math.max(nextTranslateY, 0), maxHeight);
|
|
276
417
|
})
|
|
277
418
|
.onEnd((event) => {
|
|
278
|
-
const openTranslateY =
|
|
419
|
+
const openTranslateY = getBottomSheetSnapPointTranslateY({
|
|
420
|
+
baseHeight: baseHeight.value,
|
|
421
|
+
maxHeight,
|
|
422
|
+
snapIndex: currentSnapIndex.value,
|
|
423
|
+
});
|
|
279
424
|
const draggedDown = Math.max(sheetTranslateY.value - openTranslateY, 0);
|
|
280
|
-
const
|
|
281
|
-
const isAtTopSnap = currentSnapIndex.value === topSnapIndex;
|
|
282
|
-
const snap0TranslateY =
|
|
425
|
+
const hasMultipleSnapPoints = topSnapIndex.value > 0;
|
|
426
|
+
const isAtTopSnap = currentSnapIndex.value === topSnapIndex.value;
|
|
427
|
+
const snap0TranslateY = getBottomSheetSnapPointTranslateY({
|
|
428
|
+
baseHeight: baseHeight.value,
|
|
429
|
+
maxHeight,
|
|
430
|
+
snapIndex: 0,
|
|
431
|
+
});
|
|
432
|
+
const topSnapTranslateY = getBottomSheetSnapPointTranslateY({
|
|
433
|
+
baseHeight: baseHeight.value,
|
|
434
|
+
maxHeight,
|
|
435
|
+
snapIndex: topSnapIndex.value,
|
|
436
|
+
});
|
|
283
437
|
const projectedTranslateY = sheetTranslateY.value + event.velocityY * 0.2;
|
|
284
438
|
|
|
285
439
|
const shouldCloseFromLowerSnap = event.velocityY > 500 || draggedDown > maxHeight / 2;
|
|
@@ -287,49 +441,61 @@ export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>
|
|
|
287
441
|
event.velocityY > 2200 ||
|
|
288
442
|
projectedTranslateY > snap0TranslateY + (maxHeight - snap0TranslateY) * 0.96;
|
|
289
443
|
|
|
290
|
-
const shouldClose =
|
|
444
|
+
const shouldClose = !hasMultipleSnapPoints
|
|
445
|
+
? shouldCloseFromLowerSnap
|
|
446
|
+
: isAtTopSnap
|
|
447
|
+
? shouldCloseFromTopSnap
|
|
448
|
+
: shouldCloseFromLowerSnap;
|
|
291
449
|
|
|
292
450
|
if (shouldClose) {
|
|
293
451
|
runOnJS(closeFromGesture)();
|
|
294
452
|
} else {
|
|
295
453
|
isOpen.value = true;
|
|
296
454
|
let nearestIndex = 0;
|
|
297
|
-
let minDistance =
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const
|
|
301
|
-
if (
|
|
302
|
-
minDistance =
|
|
303
|
-
nearestIndex =
|
|
455
|
+
let minDistance = Math.abs(sheetTranslateY.value - snap0TranslateY);
|
|
456
|
+
|
|
457
|
+
if (hasMultipleSnapPoints) {
|
|
458
|
+
const topDistance = Math.abs(sheetTranslateY.value - topSnapTranslateY);
|
|
459
|
+
if (topDistance < minDistance) {
|
|
460
|
+
minDistance = topDistance;
|
|
461
|
+
nearestIndex = topSnapIndex.value;
|
|
304
462
|
}
|
|
305
463
|
}
|
|
464
|
+
|
|
306
465
|
// velocity-based snapping, fast upward swipe goes to top snap point
|
|
307
|
-
if (event.velocityY < -800) {
|
|
308
|
-
nearestIndex =
|
|
466
|
+
if (hasMultipleSnapPoints && event.velocityY < -800) {
|
|
467
|
+
nearestIndex = topSnapIndex.value;
|
|
309
468
|
}
|
|
310
469
|
// From top snap, a gentle downward flick should settle to snap 0
|
|
311
470
|
// without requiring a large drag distance.
|
|
312
|
-
if (isAtTopSnap && event.velocityY > 120) {
|
|
471
|
+
if (hasMultipleSnapPoints && isAtTopSnap && event.velocityY > 120) {
|
|
313
472
|
nearestIndex = 0;
|
|
314
473
|
}
|
|
315
474
|
|
|
316
475
|
currentSnapIndex.value = nearestIndex;
|
|
317
|
-
sheetTranslateY.value = withTiming(
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
476
|
+
sheetTranslateY.value = withTiming(
|
|
477
|
+
getBottomSheetSnapPointTranslateY({
|
|
478
|
+
baseHeight: baseHeight.value,
|
|
479
|
+
maxHeight,
|
|
480
|
+
snapIndex: nearestIndex,
|
|
481
|
+
}),
|
|
482
|
+
{
|
|
483
|
+
duration: 250,
|
|
484
|
+
easing: Easing.inOut(Easing.ease),
|
|
485
|
+
},
|
|
486
|
+
);
|
|
321
487
|
}
|
|
322
488
|
}),
|
|
323
489
|
[
|
|
490
|
+
baseHeight,
|
|
324
491
|
currentSnapIndex,
|
|
325
492
|
isOpen,
|
|
326
493
|
maxHeight,
|
|
327
494
|
closeFromGesture,
|
|
328
495
|
panStartTranslateY,
|
|
329
496
|
renderContent,
|
|
330
|
-
snapPoints,
|
|
331
|
-
snapPointsTranslateY,
|
|
332
497
|
sheetTranslateY,
|
|
498
|
+
topSnapIndex,
|
|
333
499
|
],
|
|
334
500
|
);
|
|
335
501
|
|
|
@@ -339,16 +505,20 @@ export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>
|
|
|
339
505
|
() => ({
|
|
340
506
|
close,
|
|
341
507
|
currentSnapIndex,
|
|
508
|
+
topSnapIndex,
|
|
342
509
|
}),
|
|
343
|
-
[close, currentSnapIndex],
|
|
510
|
+
[close, currentSnapIndex, topSnapIndex],
|
|
344
511
|
);
|
|
345
512
|
|
|
346
513
|
return (
|
|
347
514
|
<Modal onRequestClose={onClose} transparent visible={visible}>
|
|
348
515
|
<GestureHandlerRootView style={styles.sheetContentContainer}>
|
|
349
516
|
<View style={[styles.overlay, overlayTheme]}>
|
|
350
|
-
<Animated.View
|
|
351
|
-
|
|
517
|
+
<Animated.View
|
|
518
|
+
pointerEvents='none'
|
|
519
|
+
style={[StyleSheet.absoluteFill, styles.backdrop, overlayAnimatedStyle]}
|
|
520
|
+
/>
|
|
521
|
+
<Pressable onPress={onBackdropPress} style={StyleSheet.absoluteFill} />
|
|
352
522
|
|
|
353
523
|
<Animated.View
|
|
354
524
|
pointerEvents='box-none'
|
|
@@ -364,7 +534,16 @@ export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>
|
|
|
364
534
|
entering={FadeIn.duration(250)}
|
|
365
535
|
style={styles.sheetContentContainer}
|
|
366
536
|
>
|
|
367
|
-
{
|
|
537
|
+
{enableDynamicSizing ? (
|
|
538
|
+
<View
|
|
539
|
+
onLayout={handleDynamicContentLayout}
|
|
540
|
+
style={{ paddingBottom: bottomInset }}
|
|
541
|
+
>
|
|
542
|
+
{children}
|
|
543
|
+
</View>
|
|
544
|
+
) : (
|
|
545
|
+
children
|
|
546
|
+
)}
|
|
368
547
|
</Animated.View>
|
|
369
548
|
</BottomSheetProvider>
|
|
370
549
|
) : null}
|
|
@@ -378,6 +557,14 @@ export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>
|
|
|
378
557
|
);
|
|
379
558
|
};
|
|
380
559
|
|
|
560
|
+
export const BottomSheetModal = (props: PropsWithChildren<BottomSheetModalProps>) => {
|
|
561
|
+
if (!props.visible) {
|
|
562
|
+
return null;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
return <BottomSheetModalInner {...props} />;
|
|
566
|
+
};
|
|
567
|
+
|
|
381
568
|
const useStyles = () => {
|
|
382
569
|
const {
|
|
383
570
|
theme: { semantics },
|
|
@@ -406,7 +593,6 @@ const useStyles = () => {
|
|
|
406
593
|
justifyContent: 'flex-end',
|
|
407
594
|
},
|
|
408
595
|
backdrop: {
|
|
409
|
-
...StyleSheet.absoluteFillObject,
|
|
410
596
|
backgroundColor: semantics.backgroundCoreScrim,
|
|
411
597
|
},
|
|
412
598
|
sheetContentContainer: {
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export const BOTTOM_SHEET_HANDLE_HEIGHT = 4;
|
|
2
|
+
export const BOTTOM_SHEET_HANDLE_MARGIN_VERTICAL = 8;
|
|
3
|
+
export const BOTTOM_SHEET_HANDLE_TOTAL_HEIGHT =
|
|
4
|
+
BOTTOM_SHEET_HANDLE_HEIGHT + BOTTOM_SHEET_HANDLE_MARGIN_VERTICAL * 2;
|
|
5
|
+
|
|
6
|
+
type GetBottomSheetBaseHeightParams = {
|
|
7
|
+
contentHeight: number | undefined;
|
|
8
|
+
enableDynamicSizing: boolean;
|
|
9
|
+
height: number;
|
|
10
|
+
maxHeight: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const getBottomSheetBaseHeight = ({
|
|
14
|
+
contentHeight,
|
|
15
|
+
enableDynamicSizing,
|
|
16
|
+
height,
|
|
17
|
+
maxHeight,
|
|
18
|
+
}: GetBottomSheetBaseHeightParams) => {
|
|
19
|
+
'worklet';
|
|
20
|
+
|
|
21
|
+
const cappedHeight = Math.min(height, maxHeight);
|
|
22
|
+
|
|
23
|
+
if (!enableDynamicSizing || contentHeight === undefined) {
|
|
24
|
+
return cappedHeight;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const measuredHeight = Math.max(0, contentHeight) + BOTTOM_SHEET_HANDLE_TOTAL_HEIGHT;
|
|
28
|
+
|
|
29
|
+
return Math.min(measuredHeight, cappedHeight);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type GetBottomSheetSnapPointsParams = {
|
|
33
|
+
baseHeight: number;
|
|
34
|
+
maxHeight: number;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const getBottomSheetSnapPoints = ({
|
|
38
|
+
baseHeight,
|
|
39
|
+
maxHeight,
|
|
40
|
+
}: GetBottomSheetSnapPointsParams) => {
|
|
41
|
+
'worklet';
|
|
42
|
+
|
|
43
|
+
if (baseHeight === maxHeight) {
|
|
44
|
+
return [baseHeight];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return [baseHeight, maxHeight];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type GetBottomSheetTopSnapIndexParams = {
|
|
51
|
+
baseHeight: number;
|
|
52
|
+
maxHeight: number;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const getBottomSheetTopSnapIndex = ({
|
|
56
|
+
baseHeight,
|
|
57
|
+
maxHeight,
|
|
58
|
+
}: GetBottomSheetTopSnapIndexParams) => {
|
|
59
|
+
'worklet';
|
|
60
|
+
|
|
61
|
+
return baseHeight === maxHeight ? 0 : 1;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
type GetBottomSheetSnapPointTranslateYParams = {
|
|
65
|
+
baseHeight: number;
|
|
66
|
+
maxHeight: number;
|
|
67
|
+
snapIndex: number;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const getBottomSheetSnapPointTranslateY = ({
|
|
71
|
+
baseHeight,
|
|
72
|
+
maxHeight,
|
|
73
|
+
snapIndex,
|
|
74
|
+
}: GetBottomSheetSnapPointTranslateYParams) => {
|
|
75
|
+
'worklet';
|
|
76
|
+
|
|
77
|
+
if (getBottomSheetTopSnapIndex({ baseHeight, maxHeight }) === 0) {
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return snapIndex <= 0 ? maxHeight - baseHeight : 0;
|
|
82
|
+
};
|
|
@@ -12,7 +12,7 @@ export const StreamBottomSheetModalFlatList = <ItemT,>({
|
|
|
12
12
|
scrollEnabled: scrollEnabledProp,
|
|
13
13
|
...props
|
|
14
14
|
}: StreamBottomSheetModalFlatListProps<ItemT>) => {
|
|
15
|
-
const { currentSnapIndex } = useBottomSheetContext();
|
|
15
|
+
const { currentSnapIndex, topSnapIndex } = useBottomSheetContext();
|
|
16
16
|
const listRef = useRef<FlatList<ItemT>>(null);
|
|
17
17
|
|
|
18
18
|
const setNativeScrollEnabled = useStableCallback((value: boolean) =>
|
|
@@ -20,14 +20,23 @@ export const StreamBottomSheetModalFlatList = <ItemT,>({
|
|
|
20
20
|
);
|
|
21
21
|
|
|
22
22
|
useAnimatedReaction(
|
|
23
|
-
() =>
|
|
23
|
+
() => ({
|
|
24
|
+
currentSnapIndex: currentSnapIndex.value,
|
|
25
|
+
topSnapIndex: topSnapIndex.value,
|
|
26
|
+
}),
|
|
24
27
|
(value, prev) => {
|
|
25
|
-
if (
|
|
28
|
+
if (
|
|
29
|
+
scrollEnabledProp !== undefined ||
|
|
30
|
+
(prev &&
|
|
31
|
+
value.currentSnapIndex === prev.currentSnapIndex &&
|
|
32
|
+
value.topSnapIndex === prev.topSnapIndex)
|
|
33
|
+
) {
|
|
26
34
|
return;
|
|
27
35
|
}
|
|
28
|
-
|
|
36
|
+
|
|
37
|
+
runOnJS(setNativeScrollEnabled)(value.currentSnapIndex === value.topSnapIndex);
|
|
29
38
|
},
|
|
30
|
-
[currentSnapIndex],
|
|
39
|
+
[currentSnapIndex, topSnapIndex],
|
|
31
40
|
);
|
|
32
41
|
|
|
33
42
|
return <FlatList ref={listRef} {...props} scrollEnabled={false} />;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BOTTOM_SHEET_HANDLE_TOTAL_HEIGHT,
|
|
3
|
+
getBottomSheetBaseHeight,
|
|
4
|
+
getBottomSheetSnapPointTranslateY,
|
|
5
|
+
getBottomSheetSnapPoints,
|
|
6
|
+
getBottomSheetTopSnapIndex,
|
|
7
|
+
} from '../BottomSheetModal.utils';
|
|
8
|
+
|
|
9
|
+
describe('BottomSheetModal.utils', () => {
|
|
10
|
+
it('caps fixed bottom sheet height by maxHeight', () => {
|
|
11
|
+
expect(
|
|
12
|
+
getBottomSheetBaseHeight({
|
|
13
|
+
contentHeight: undefined,
|
|
14
|
+
enableDynamicSizing: false,
|
|
15
|
+
height: 500,
|
|
16
|
+
maxHeight: 420,
|
|
17
|
+
}),
|
|
18
|
+
).toBe(420);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('uses measured content height plus handle and safe area when dynamic sizing is enabled', () => {
|
|
22
|
+
expect(
|
|
23
|
+
getBottomSheetBaseHeight({
|
|
24
|
+
contentHeight: 120,
|
|
25
|
+
enableDynamicSizing: true,
|
|
26
|
+
height: 400,
|
|
27
|
+
maxHeight: 500,
|
|
28
|
+
}),
|
|
29
|
+
).toBe(120 + BOTTOM_SHEET_HANDLE_TOTAL_HEIGHT);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('caps dynamic content height by the provided height', () => {
|
|
33
|
+
expect(
|
|
34
|
+
getBottomSheetBaseHeight({
|
|
35
|
+
contentHeight: 500,
|
|
36
|
+
enableDynamicSizing: true,
|
|
37
|
+
height: 300,
|
|
38
|
+
maxHeight: 600,
|
|
39
|
+
}),
|
|
40
|
+
).toBe(300);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('keeps the expanded snap point when the sheet is shorter than maxHeight', () => {
|
|
44
|
+
expect(
|
|
45
|
+
getBottomSheetSnapPoints({
|
|
46
|
+
baseHeight: 280,
|
|
47
|
+
maxHeight: 640,
|
|
48
|
+
}),
|
|
49
|
+
).toEqual([280, 640]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('returns two snap points for fixed sizing when maxHeight exceeds baseHeight', () => {
|
|
53
|
+
expect(
|
|
54
|
+
getBottomSheetSnapPoints({
|
|
55
|
+
baseHeight: 280,
|
|
56
|
+
maxHeight: 640,
|
|
57
|
+
}),
|
|
58
|
+
).toEqual([280, 640]);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('returns a single snap point when the sheet is already at maxHeight', () => {
|
|
62
|
+
expect(
|
|
63
|
+
getBottomSheetSnapPoints({
|
|
64
|
+
baseHeight: 640,
|
|
65
|
+
maxHeight: 640,
|
|
66
|
+
}),
|
|
67
|
+
).toEqual([640]);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('returns the correct top snap index', () => {
|
|
71
|
+
expect(
|
|
72
|
+
getBottomSheetTopSnapIndex({
|
|
73
|
+
baseHeight: 280,
|
|
74
|
+
maxHeight: 640,
|
|
75
|
+
}),
|
|
76
|
+
).toBe(1);
|
|
77
|
+
|
|
78
|
+
expect(
|
|
79
|
+
getBottomSheetTopSnapIndex({
|
|
80
|
+
baseHeight: 640,
|
|
81
|
+
maxHeight: 640,
|
|
82
|
+
}),
|
|
83
|
+
).toBe(0);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('returns the correct translateY for each snap point', () => {
|
|
87
|
+
expect(
|
|
88
|
+
getBottomSheetSnapPointTranslateY({
|
|
89
|
+
baseHeight: 280,
|
|
90
|
+
maxHeight: 640,
|
|
91
|
+
snapIndex: 0,
|
|
92
|
+
}),
|
|
93
|
+
).toBe(360);
|
|
94
|
+
|
|
95
|
+
expect(
|
|
96
|
+
getBottomSheetSnapPointTranslateY({
|
|
97
|
+
baseHeight: 280,
|
|
98
|
+
maxHeight: 640,
|
|
99
|
+
snapIndex: 1,
|
|
100
|
+
}),
|
|
101
|
+
).toBe(0);
|
|
102
|
+
|
|
103
|
+
expect(
|
|
104
|
+
getBottomSheetSnapPointTranslateY({
|
|
105
|
+
baseHeight: 640,
|
|
106
|
+
maxHeight: 640,
|
|
107
|
+
snapIndex: 0,
|
|
108
|
+
}),
|
|
109
|
+
).toBe(0);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -58,7 +58,11 @@ export const ChannelAvatar = (props: ChannelAvatarProps) => {
|
|
|
58
58
|
|
|
59
59
|
if (usersWithoutSelf.length > 1) {
|
|
60
60
|
return (
|
|
61
|
-
<UserAvatarGroup
|
|
61
|
+
<UserAvatarGroup
|
|
62
|
+
size={size}
|
|
63
|
+
users={usersForGroup}
|
|
64
|
+
showOnlineIndicator={showOnlineIndicator}
|
|
65
|
+
/>
|
|
62
66
|
);
|
|
63
67
|
} else {
|
|
64
68
|
return (
|