react-native-bottom-sheet
react-native-bottom-sheet copied to clipboard
[v4] enableDynamicSizing prop does not work when BottomSheetView contains a single View wrapping children
Bug
The enableDynamicSize prop does not work when BottomSheetView contains a single View component with multiple children. I am seeing inconsistent behavior where most of the time, the bottom sheet has no height and no content. Very rarely it renders correctly (maybe 1 in 50 attempts?).
I was able to reproduce this using the example app on both Android & iOS (see repro steps below).
https://github.com/gorhom/react-native-bottom-sheet/assets/2507829/739ccb21-4bd4-4af7-9044-f27b46fe2b59
Environment info
Reproduced on latest master (65b5dc0).
| Library | Version |
|---|---|
| @gorhom/bottom-sheet | 4.5.1 |
| react-native | 0.62.2 |
| react-native-reanimated | 2.8.0 |
| react-native-gesture-handler | 1.10.3 |
Steps To Reproduce
- Run example app
- Scroll down and click Dynamic Sizing
Describe what you expected to happen:
- Bottom sheet should render with content
Reproducible sample code
Modify the render of example/app/src/screens/advanced/DynamicSnapPointExample.tsx to add a View that wraps all children of BottomSheetView
Here is a patch file to apply with the changes: repro.patch
diff --git a/example/app/src/screens/advanced/DynamicSnapPointExample.tsx b/example/app/src/screens/advanced/DynamicSnapPointExample.tsx
index 8c3e63e..a91855e 100644
--- a/example/app/src/screens/advanced/DynamicSnapPointExample.tsx
+++ b/example/app/src/screens/advanced/DynamicSnapPointExample.tsx
@@ -54,6 +54,7 @@ const DynamicSnapPointExample = () => {
animateOnMount={true}
>
<BottomSheetView style={contentContainerStyle}>
+ <View>
<Text style={styles.message}>
Could this sheet resize to its content height ?
</Text>
@@ -62,6 +63,7 @@ const DynamicSnapPointExample = () => {
</View>
<Button label="Yes" onPress={handleIncreaseContentPress} />
<Button label="Maybe" onPress={handleDecreaseContentPress} />
+ </View>
</BottomSheetView>
</BottomSheet>
</View>
Same here.
I set a minHeight in the style property of the BottomSheetView to ensure my app's functionality, but it doesn't dynamically define the height.
It apparently works normally with BottomSheetScrollView instead of BottomSheetView.
Some solution for this?
deleting flex: 1 from BottomSheetView fixed same problem don't forget r console
Having the same issue with BottomSheetView, replacing it with BottomSheetScrollView seems to work
Having the same issue with
BottomSheetView, replacing it withBottomSheetScrollViewseems to work
This seems to be a workaround but I can't get paddingBottom to work with it. How are you styling on devices with safe area bottom? I was giving paddingBottom as bottom from useSafeAreaInsets and giving a backgroundColor to BottomSheetView. That doesn't work anymore using enableDynamicSizing.
@gorhom Any idea on how to fix this?
Adding code below
const { top, bottom } = useSafeAreaInsets();
return (
<BottomSheetModal
ref={ref}
index={0}
enableDynamicSizing
enablePanDownToClose
backdropComponent={RenderBackdrop}
onDismiss={onDismiss}
onChange={setCurrentIndex}
name={name}
topInset={top}
keyboardBehavior={Platform.OS === 'android' ? 'extend' : 'interactive'}
keyboardBlurBehavior="restore"
handleComponent={handleComponent}
backgroundStyle={{
backgroundColor: colors.background[100],
}}>
<BottomSheetView
style={[themeStyle.contentContainer, { paddingBottom: bottom }]}>
{children}
</BottomSheetView>
</BottomSheetModal>
);
As others mentioned, disabling flex and adding a min height worked for me:
<BottomSheetView style={{ flex: 0, minHeight: 100 }}>{children}</BottomSheetView>
BottomSheetScrollView maybe does this too but I did not want the contents to be scrollable in my case.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
@gorhom Hey man. Thanks for all your hard work. Tagging you here as this is stopping me from upgrading. It would be amazing if you could look into it.
Has anyone a solution for this?
Has anyone a solution for this?
Good workaround is using BottomShitScrollView with scroll false prop
BottomShitScrollView
Lol worked like charm!
I had the same problem and this is how I solved it. Since <BottomSheetScrollView> is used to render dynamically, I put it in the main content section and made it work properly when I gave false to the scrollEnabled prop
<BottomSheetScrollView scrollEnabled={false} style={{height: '100%'}}>
<View style={styles.titleContainer}>
{rightIconName && (
<TouchableOpacity
style={reverseContent ? styles.leftIcon : styles.rightIcon}
onPress={() => bottomSheetModalRef.current?.close()}>
<Icon name={rightIconName} color={color} size={24} />
</TouchableOpacity>
)}
{leftIconName && (
<TouchableOpacity
style={reverseContent ? styles.rightIcon : styles.leftIcon}
onPress={() => {
if (leftFunction) {
leftFunction();
}
}}>
<Icon name={leftIconName} color={color} size={24} />
</TouchableOpacity>
)}
<Text style={styles.titleText}>{title}</Text>
</View>
<View style={{height: 'auto'}}>
<View style={styles.contentContainer}>
{typeof content === 'string' ? (
<Text>{content}</Text>
) : (
<>{content}</>
)}
</View>
</View>
{bottomButtonTitle && (
<View style={styles.bottomButtonContainer}>
<Button
onPress={() => {
navigation.navigate(bottomButtonLink);
bottomSheetModalRef.current?.close();
}}
title={bottomButtonTitle}
color="black"
/>
</View>
)}
</BottomSheetScrollView>
I had to go back to the deprecated dynamic snap points with the bottomsheetview hook as a workaround
This seems to be a workaround but I can't get paddingBottom to work with it. How are you styling on devices with safe area bottom? I was giving paddingBottom as bottom from useSafeAreaInsets and giving a backgroundColor to BottomSheetView. That doesn't work anymore using enableDynamicSizing.
@salman-ar-sar don't use paddingBottom -- use a View and give it height safeAreaInsets.bottom to take up that space instead
Dynamic sizing is working for me in version "4.6.1"
<BottomSheetModalProvider>
<View style={styles.container}>
<Button onPress={handlePresentModalPress} variant="outline" />
<BottomSheetModal enableDynamicSizing ref={bottomSheetModalRef}>
<BottomSheetView>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
<Text>Awesome π</Text>
</BottomSheetView>
</BottomSheetModal>
</View>
</BottomSheetModalProvider>
);
};
const styles = StyleSheet.create({
header: {
fontSize: styling.spacing.lg,
},
container: {
flex: 1,
padding: 24,
justifyContent: 'center',
backgroundColor: 'grey',
},
});
https://github.com/gorhom/react-native-bottom-sheet/assets/79057289/83a08db4-1c61-4b0a-8124-8c858219f4e9
Dynamic sizing is working for me in version "4.6.1"
it's not working for me.
The minHeight workaround is working.
enableDynamicSizing does not work if using BottomSheetFlatList inside
<BottomSheetModal
enableDynamicSizing
index={0}
onChange={handleSheetChanges}
ref={filterModalRef}
snapPoints={filterSnaps}
style={modalStyle.modal}
>
<BottomSheetFlatList />
</BottomSheetModal>
Facing the same issue.
Dependencies
react-native: 0.71.17
react-native-reanimated: 3.8.1
@gorhom/bottom-sheet: 5.0.0-alpha.9
Not sure how related is this, but this worked for me.
<BottomSheetModal
index={1}
ref={ref}
snapPoints={[1]} // ********* HERE, Add a default snapPoint 1
enableDynamicSizing // ********* HERE Enable to dynamic sizing
>
<BottomSheetView style={styles.container}> // ********* HERE { flex: 0, minHeight: 100 }
...dynmic content
</BottomSheetView>
</BottomSheetModal>
Alternative solution https://github.com/gorhom/react-native-bottom-sheet/pull/1513#issuecomment-1790589392
Also my issue, for me, nothing shows until I add flex: 0 in the view, also padding/margin bottom does nothing?
<BottomSheet
ref={bottomSheetRef}
enableDynamicSizing={true}
enableContentPanningGesture={false}
>
<BottomSheetView
style={{ flex: 0, minHeight: 120, paddingBottom: 6, }}
>
<WhereAreYouGoing
key='where-are-you-going'
onClose={showScheduledRideModal}
onSelect={openSearch}
/>
</BottomSheetView>
</BottomSheet>
Also, I used BottomSheetFlatList in another component and when thatβs shown only the first item is shown.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
I'm using version 4.6.3 and yet the enableDynamicSizing problem continues to affect my app. Has anyone found anything that might help? @gorhom
Please check this:
https://github.com/gorhom/react-native-bottom-sheet/pull/1513#issuecomment-2154433013
I am using version 4.6.3 and yet the enableDynamicSizing issue is still affecting my application unless I use one of these hacks, is there any idea when this bug will be solved?
@javigutierrezfer did you try this
https://github.com/gorhom/react-native-bottom-sheet/pull/1513#issuecomment-2154433013
For anyone who is struggling with the issue. I'm using version 4.6.3 and getting the dynamic sizing is working properly. Here is my code:
import { useCallback, useRef, useState } from 'react'
import { createContext } from 'react'
import {
BottomSheetBackdrop,
BottomSheetBackdropProps,
BottomSheetModal,
BottomSheetModalProvider,
BottomSheetProps,
BottomSheetView,
} from '@gorhom/bottom-sheet'
type BottomSheetOptions = {
children: React.ReactNode
} & Omit<BottomSheetProps, 'children'>
const DEFAULT_OPTIONS: BottomSheetOptions = {
index: -1,
children: null,
}
type BottomSheetProviderContext = {
children: React.ReactNode
}
export type BottomSheetContextValue = {
expand: (options: BottomSheetOptions) => void
collapse: () => void
}
export const BottomSheetContext = createContext<BottomSheetContextValue | undefined>(undefined)
export function BottomSheetProvider({ children }: BottomSheetProviderContext) {
const bottomSheetModalRef = useRef<BottomSheetModal>(null)
const [options, setOptions] = useState<BottomSheetOptions | null>(DEFAULT_OPTIONS)
const bottomSheetContext: BottomSheetContextValue = {
expand: (opts: BottomSheetOptions) => {
bottomSheetModalRef.current?.present()
setOptions({ ...DEFAULT_OPTIONS, ...opts })
},
collapse: () => {
bottomSheetModalRef.current?.dismiss()
},
}
const renderBackdrop = useCallback(
(props: BottomSheetBackdropProps) => <BottomSheetBackdrop {...props} appearsOnIndex={0} disappearsOnIndex={-1} />,
[],
)
return (
<BottomSheetContext.Provider value={bottomSheetContext}>
{children}
<BottomSheetModalProvider>
<BottomSheetModal
ref={bottomSheetModalRef}
snapPoints={options?.snapPoints}
enableDynamicSizing={options?.enableDynamicSizing}
backdropComponent={renderBackdrop}>
<BottomSheetView style={{ flex: 0, minHeight: 10 }}>{options?.children}</BottomSheetView>
</BottomSheetModal>
</BottomSheetModalProvider>
</BottomSheetContext.Provider>
)
}
Usage in a component:
const handleOpen = () => {
bottomSheet.expand({
enableDynamicSizing: true,
children: (
// bottom sheet content
),
})
}
https://github.com/gorhom/react-native-bottom-sheet/assets/72242664/c6e4d07c-c0f2-4066-ad1c-4053dab606db
snapPoints={[1]} and BottomSheetScrollView seem to be the only things that get it to work for me
As of today, the most reasonable workaround seems to be the BottomSheetScrollView:
export default function BottomSheetModalWithDynamicSizing() {
const { bottom } = useSafeAreaInsets();
// ...
return (
<BottomSheetModal enableDynamicSizing={true} ... >
<BottomSheetScrollView contentContainerStyle={{ paddingBottom: bottom }} scrollEnabled={false}>
{children}
</BottomSheetScrollView>
</BottomSheetModal>
);
}