Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v3] Set height of BottomSheet to children height #341

Closed
mralj opened this issue Mar 11, 2021 · 5 comments
Closed

[v3] Set height of BottomSheet to children height #341

mralj opened this issue Mar 11, 2021 · 5 comments
Labels
no-issue-activity question Further information is requested

Comments

@mralj
Copy link

mralj commented Mar 11, 2021

Ask your Question

Hello,

I'm having trouble opening BottomSheet so its height is the same as the height of its children.

This is something simillar to the adjustToContentHeight which react-native-modalize has :)

Not sure am I missing something stupidly obvious or this isn't possible in V3.

I have tried something simillarto this issue, the app crashes if I don't add the key, here is rough example:

export const MadBottomSheet = forwardRef<MadBottomSheetRefProps, MadBottomSheetProps>(({ children }, ref) => {
  const bottomSheetModalRef = useRef<BottomSheetModal>(null);

  const [contentHeight, setContentHeight] = React.useState(-1);
  const snapPoints = React.useMemo(() => [contentHeight], [contentHeight]);

  const handleOnLayout = React.useCallback(({ nativeEvent }: LayoutChangeEvent) => {
    const { height } = nativeEvent.layout;
    setContentHeight(height);
  }, []);

  const openBottomSheet = () => {
    bottomSheetModalRef.current?.present();
  };

  const closeBottomSheet = () => {
    bottomSheetModalRef.current?.dismiss();
  };

  useImperativeHandle(ref, () => ({
    openBottomSheet,
    closeBottomSheet
  }));

  return (
    <BottomSheetModalProvider key={`Provider${contentHeight}`}>
      <BottomSheetModal
        waitFor
        simultaneousHandlers
        ref={bottomSheetModalRef}
        snapPoints={snapPoints}
        key={`Modal${contentHeight}`}
      >
        <BottomSheetView onLayout={handleOnLayout} key={`View${contentHeight}`}>
          {children}
        </BottomSheetView>
      </BottomSheetModal>
    </BottomSheetModalProvider>
  );
});

With the key prop it "almost" works, I have to tap twice on the button to open the modal.
The first time it just flashes and disappears, but after that everything is 👍
Ofc. this is not acceptable, but this is the furthest I got 😩

For V2 there was this issue, but as far as I can see, the prop shouldMeasureContentHeight doesn't exist in V3.

Could someone please help me out :), it would be very much appreciated 🙂?

P.S.
I know I could add useEffect to simulate/force the second click, but I am looking for less hacky solutions 🙂

@mralj mralj added the question Further information is requested label Mar 11, 2021
@github-actions
Copy link

github-actions bot commented Jul 5, 2021

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
Copy link

This issue was closed because it has been stalled for 5 days with no activity.

@fondakogb
Copy link

Maybe @mralj has already managed to solve the problem, but for those like me who haven't found in the v3 / v4 documentation what to use to create a BottomSheet (modal or not) with "height adjusted according to the height of its content", I followed issue #32 you linked and there I found a link to Dynamic Snap Point Example that met my simple needs via hook useBottomSheetDynamicSnapPoints.
This hook provides an "animated version" of handleHeight, snapPoints, contentHeight and contentLayout, so that the above code can be written as below:

import { BottomSheetModal, useBottomSheetDynamicSnapPoints, BottomSheetView } from '@gorhom/bottom-sheet';

export const MadBottomSheet = forwardRef<MadBottomSheetRefProps, MadBottomSheetProps>(({ children }, ref) => {
  const bottomSheetModalRef = useRef<BottomSheetModal>(null);

  // removed contentHeight state because of height calculated by library itself

  // Initial snapPoints modified using special string constant 'CONTENT_HEIGHT' that the hook below will interpret
  // the initial snapPoints could be ‘mixed’, eg. [0, ’30%’, 'CONTENT_HEIGHT’, ‘100%’]
  const snapPoints = React.useMemo(() => ['CONTENT_HEIGHT'], []);
  //removed handleOnLayout callback because of new-one returned by hook below
  const {
    animatedHandleHeight,
    animatedSnapPoints,
    animatedContentHeight,
    handleContentLayout,
  } = useBottomSheetDynamicSnapPoints(snapPoints); // <— this is the hook

  const openBottomSheet = () => {
    bottomSheetModalRef.current?.present();
  };

  const closeBottomSheet = () => {
    bottomSheetModalRef.current?.dismiss();
  };

  useImperativeHandle(ref, () => ({
    openBottomSheet,
    closeBottomSheet
  }));

  // removed both key props because not useful anymore for the purpose
  return (
    <BottomSheetModalProvider>
      <BottomSheetModal
        waitFor
        simultaneousHandlers
        ref={bottomSheetModalRef}
        snapPoints={animatedSnapPoints} // <-- modified
        handleHeight={animatedHandleHeight} // <-- added
        contentHeight={animatedContentHeight} // <-- added
        key={`Modal${contentHeight}`}
      >
        <BottomSheetView
          onLayout={handleContentLayout} // <-- modified
        >
          {children}
        </BottomSheetView>
      </BottomSheetModal>
    </BottomSheetModalProvider>
  );
});

@gorhom
Copy link
Owner

gorhom commented Aug 10, 2021

@fondakogb good finding, i am already working on documenting this part and will be release soon 👍

@ghulamhussainjoyo
Copy link

@fondakogb good finding, i am already working on documenting this part and will be release soon 👍

I am setting dynamic height of bottom sheet according to content but when I keep navigation inside BottomSheetView it does not works and shows error or does not display content of navigation

`type Props = {
onBottomsheetChange?: (index: number) => void;
} & colors;

type RefProps = BottomSheetModal;

const BottomSheetNavigationStack =
createNativeStackNavigator();

const CustomBottomsheet = forwardRef<RefProps, Props>(
({ onBottomsheetChange }, ref) => {
const { colors } = useThemeContext();
const snapPoints = React.useMemo(() => ["CONTENT_HEIGHT"], []);
const {
animatedHandleHeight,
animatedSnapPoints,
animatedContentHeight,
handleContentLayout,
} = useBottomSheetDynamicSnapPoints(snapPoints); // <— this is the hook

return (
  <BottomSheetModal
    enablePanDownToClose
    enableHandlePanningGesture
    ref={ref}
    // snapPoints={snapPoints}
    // index={-1}
    detached={false}
    onChange={onBottomsheetChange}
    snapPoints={animatedSnapPoints} // <-- modified
    handleHeight={animatedHandleHeight} // <-- added
    contentHeight={animatedContentHeight} // <-- added
    handleIndicatorStyle={{
      width: 64,
      height: 5,
      backgroundColor: colors.stroke.low,
    }}
  >
    <BottomSheetView
      style={{ flex: 1 }}
      onLayout={handleContentLayout} // <-- modified
    >
      <NavigationContainer independent={true}>
        <BottomSheetNavigationStack.Navigator
          screenOptions={{
            headerShown: false,
          }}
        >
          <BottomSheetNavigationStack.Screen
            name="filterReviews"
            component={FilterReviews}
          />
          <BottomSheetNavigationStack.Screen
            name="restaurantCuisine"
            component={RestaurantCuisine}
          />
        </BottomSheetNavigationStack.Navigator>
      </NavigationContainer>
    </BottomSheetView>
  </BottomSheetModal>
);

}
);
`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-issue-activity question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants