react-native-bottom-sheet icon indicating copy to clipboard operation
react-native-bottom-sheet copied to clipboard

[v4] enableDynamicSizing prop does not work when BottomSheetView contains a single View wrapping children

Open gotcha84 opened this issue 2 years ago β€’ 35 comments

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

  1. Run example app
  2. Scroll down and click Dynamic Sizing

Describe what you expected to happen:

  1. 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>

gotcha84 avatar Oct 11 '23 03:10 gotcha84

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?

erickcrus avatar Oct 11 '23 18:10 erickcrus

deleting flex: 1 from BottomSheetView fixed same problem don't forget r console

fendermany avatar Oct 13 '23 10:10 fendermany

Having the same issue with BottomSheetView, replacing it with BottomSheetScrollView seems to work

FredrikErikJohansson avatar Oct 18 '23 11:10 FredrikErikJohansson

Having the same issue with BottomSheetView, replacing it with BottomSheetScrollView seems 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>
);

salman-ar-sar avatar Oct 20 '23 07:10 salman-ar-sar

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.

kaceycleveland avatar Nov 10 '23 17:11 kaceycleveland

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.

github-actions[bot] avatar Dec 11 '23 09:12 github-actions[bot]

@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.

salman-ar-sar avatar Dec 11 '23 09:12 salman-ar-sar

Has anyone a solution for this?

hosseinmd avatar Dec 23 '23 17:12 hosseinmd

Has anyone a solution for this?

Good workaround is using BottomShitScrollView with scroll false prop

fendermany avatar Dec 24 '23 10:12 fendermany

BottomShitScrollView

Lol worked like charm!

fukemy avatar Jan 24 '24 04:01 fukemy

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>

m3tinbekar avatar Feb 16 '24 20:02 m3tinbekar

I had to go back to the deprecated dynamic snap points with the bottomsheetview hook as a workaround

shamilovtim avatar Feb 19 '24 18:02 shamilovtim

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

giaset avatar Mar 14 '24 16:03 giaset

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

JamesDavis7 avatar Mar 21 '24 11:03 JamesDavis7

Dynamic sizing is working for me in version "4.6.1"

it's not working for me. The minHeight workaround is working.

ericksprengel avatar Mar 27 '24 18:03 ericksprengel

enableDynamicSizing does not work if using BottomSheetFlatList inside

<BottomSheetModal
      enableDynamicSizing
      index={0}
      onChange={handleSheetChanges}
      ref={filterModalRef}
      snapPoints={filterSnaps}
      style={modalStyle.modal}
    >
    <BottomSheetFlatList />
</BottomSheetModal>

lucksp avatar Mar 31 '24 16:03 lucksp

Facing the same issue.

Dependencies

react-native: 0.71.17 react-native-reanimated: 3.8.1 @gorhom/bottom-sheet: 5.0.0-alpha.9

JJSLIoT avatar Apr 02 '24 09:04 JJSLIoT

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>

shuhelkhan114 avatar Apr 03 '24 08:04 shuhelkhan114

Alternative solution https://github.com/gorhom/react-native-bottom-sheet/pull/1513#issuecomment-1790589392

badalsaibo avatar Apr 24 '24 11:04 badalsaibo

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.

karimcambridge avatar May 02 '24 04:05 karimcambridge

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.

github-actions[bot] avatar Jun 01 '24 09:06 github-actions[bot]

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

samuellima99 avatar Jun 04 '24 01:06 samuellima99

Please check this:

https://github.com/gorhom/react-native-bottom-sheet/pull/1513#issuecomment-2154433013

mustapha-ghlissi avatar Jun 07 '24 16:06 mustapha-ghlissi

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 avatar Jun 27 '24 08:06 javigutierrezfer

@javigutierrezfer did you try this

https://github.com/gorhom/react-native-bottom-sheet/pull/1513#issuecomment-2154433013

mustapha-ghlissi avatar Jun 27 '24 10:06 mustapha-ghlissi

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

tatthien avatar Jul 05 '24 01:07 tatthien

snapPoints={[1]} and BottomSheetScrollView seem to be the only things that get it to work for me

avivash avatar Jul 17 '24 19:07 avivash

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>
  );
}

fabriziocucci avatar Jul 27 '24 20:07 fabriziocucci