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

Drawer scrollable with dynamic max height #1402

Closed

Conversation

ororsatti
Copy link

@ororsatti ororsatti commented Jun 14, 2023

Adding a hook to have a drawer with a max height that will dynamically change its height until reaching the limit, following this discussion of mine: #1363

Motivation

People are asking for this feature for a while now, and asked me in the discussion to share the code.
Closes: (#658 , #32)

Example:

Simulator.Screen.Recording.-.iPhone.13.-.2023-06-15.at.09.07.01.mp4

@ororsatti ororsatti changed the title Dynamically sized scrollable drawer Drawer scrollable with dynamic max height Jun 15, 2023
@donatoaguirre24
Copy link

@gorhom can you please review this PR 🙏🏻

@younes0
Copy link

younes0 commented Jul 5, 2023

code looks neat but have you tried with the v5 whici is still alpha?

@ororsatti
Copy link
Author

ororsatti commented Jul 5, 2023

code looks neat but have you tried with the v5 whici is still alpha?

4.4.5 is the latest version I tested this on.

@natealmeida185
Copy link

Will this help fix issues with horizontal scrolling within a ScrollView or FlatList? I have tried using both of these components imported from React Native and react-native-gesture-handler. I am unable to get either one of them to scroll horizontally. Is there a CSS attribute that will work like flex but for width that will make the scrollview/flatlist take up the entire content width?

@ororsatti
Copy link
Author

ororsatti commented Jul 5, 2023

Will this help fix issues with horizontal scrolling within a ScrollView or FlatList? I have tried using both of these components imported from React Native and react-native-gesture-handler. I am unable to get either one of them to scroll horizontally. Is there a CSS attribute that will work like flex but for width that will make the scrollview/flatlist take up the entire content width?

This will not help with the issue you said,
I suspect you are just missing something on your end.

@younes0
Copy link

younes0 commented Jul 6, 2023

@ororsatti that's great, so with web support coming in v5, I would ditch https://github.com/ammarahm-ed/react-native-actions-sheet and use this library only

@ororsatti
Copy link
Author

@ororsatti that's great, so with web support coming in v5, I would ditch https://github.com/ammarahm-ed/react-native-actions-sheet and use this library only

Oh you come around to test this on v5?

@younes0
Copy link

younes0 commented Jul 6, 2023

not yet, will do as soon as v5 is stable.
v5 is still alpha so there's no point to test on something that might profoundly change.

@natealmeida185
Copy link

natealmeida185 commented Jul 6, 2023

@ororsatti @gorhom I am still having issues getting a ScrollView or FlatList to scroll horizontally within a BottomSheet component. I am currently using a ScrollView from 'react-native-gesture-handler'. I have tried using a ScrollView and FlatList from all recommended node modules (RNGH, RN, and BottomSheet). Touch events for ScrollView/FlatList components don't seem to be working if they are set to scroll horizontally.

export const BottomSheetDrawer = ({
  drawerRef,
  setIsDrawerHidden,
  children,
  snapPoints,
  paddingHorizontal,
  enablePanDownToClose,
  hasCloseIcon,
}) => (
  <View style={globalStyles.bottomSheetView}>
    <BottomSheet
      ref={drawerRef}
      index={1}
      enableContentPanningGesture={false}
      enablePanDownToClose={enablePanDownToClose !== false}
      onClose={() => setIsDrawerHidden(true)}
      snapPoints={snapPoints || ['25%', '60%']}>
      <View style={globalStyles.bottomSheetBody(paddingHorizontal)}>
        {hasCloseIcon !== false ? (
          <MaterialIcons
            name={'close'}
            color="#4B4B4B"
            size={20}
            style={{
              zIndex: 1,
              position: 'absolute',
              top: 0,
              right: 20,
              padding: 5,
            }}
            onPress={() => {
              if (drawerRef?.current?.close) {
                drawerRef.current.close();
              }
              setIsDrawerHidden(true);
            }}
          />
        ) : null}
        {children}
      </View>
    </BottomSheet>
  </View>
);
 <BottomSheetDrawer
              drawerRef={activityDrawerRef}
              setIsDrawerHidden={setIsActivityDrawerHidden}
              children={
                <CustomActivityCard
                  handleActivityButton={handleBeginActivityButton}
                  buttonText="Begin Walk"
                  localPlaces={localPlaces}
                />
              }
              paddingHorizontal={20}
              hasCloseIcon={false}
              enablePanDownToClose={false}
            />
export const CustomActivityCard = ({
  handleActivityButton,
  buttonText,
  localPlaces,
}) => {
  const currActivityInfo = useSelector(state => state.activityInfo);

  const {locationGeopoints = 0, locationDistance = 0} = currActivityInfo || {};

  return (
    <View style={activityStyles.activeLocationView}>
      {!locationDistance || !locationGeopoints || !localPlaces ? (
        <View style={activityStyles.loadingMapView}>
          <CustomActivityCardSkeleton />
        </View>
      ) : (
        <View>
          {localPlaces.length > 0 ? (
            <RNGHScrollView
              horizontal={true}
              contentContainerStyle={activityStyles.activityScrollView}>
              {localPlaces.map((localPlace, index) => (
                <Image
                  key={index}
                  style={activityStyles.activeScrollViewPhoto(
                    localPlaces.length === 1 ? '100%' : '90%',
                  )}
                  resizeMode="cover"
                  source={require('../Main/images/Geopet-Park.png')}
                />
              ))}
            </RNGHScrollView>
          ) : (
            <Image
              resizeMode="cover"
              style={activityStyles.activeLocationPhoto}
              source={require('../Main/images/Geopet-Park.png')}
            />
          )}
          <View style={activityStyles.activityHeaderView}>
            <View>
              <View style={activityStyles.activityGeopointsView}>
                <Text style={activityStyles.activityInfoText}>
                  {locationGeopoints}
                </Text>
                <Image
                  style={{width: 16, height: 16}}
                  source={require('../Main/images/Geopet-Logo.png')}
                />
              </View>
            </View>
            <Text
              numberOfLines={1}
              style={activityStyles.activeLocationDistance}>
              {locationDistance} mi
            </Text>
          </View>
          <TouchableWithoutFeedback onPress={() => handleActivityButton()}>
            <View style={globalStyles.submitButton('100%', 10, '#FFC76A')}>
              <Text style={globalStyles.submitButtonText('#374151')}>
                {buttonText}
              </Text>
            </View>
          </TouchableWithoutFeedback>
        </View>
      )}
    </View>
  );
};

@fwielstra
Copy link

@ororsatti Could you help out? I've used your fork for a project of ours and it seems to work mostly all right, but it doesn't seem to work right with a backdrop; the backdrop seems to break the auto adjustment.

I'm sure it's a matter of passing it the right number / property, but... I'm a bit lost on the subject.

@ororsatti
Copy link
Author

ororsatti commented Jul 21, 2023

@ororsatti Could you help out? I've used your fork for a project of ours and it seems to work mostly all right, but it doesn't seem to work right with a backdrop; the backdrop seems to break the auto adjustment.

I'm sure it's a matter of passing it the right number / property, but... I'm a bit lost on the subject.

Try this backdrop setup:
Screenshot 2023-07-21 at 14 59 42

@ororsatti
Copy link
Author

@fwielstra Looks to me that it works just fine.

Simulator.Screen.Recording.-.iPhone.14.-.2023-07-21.at.15.26.28.mp4

cfoster5 added a commit to cfoster5/lookforward that referenced this pull request Aug 17, 2023
@ororsatti
Copy link
Author

Any update on this? Is there a plan for this to be in for any upcoming releases? @ororsatti @gorhom

I hope, I tried contacting him on Twitter as well after I saw the excitement around this topic
I hope he'll come around to test this

@Eli-Nathan
Copy link

I found some problems when using this hook with dynamic content that changes before showing the bottom sheet.

The solution I opted for is:

// ....
const initialSnapPoints = useMemo(() => ["CONTENT_HEIGHT"], [])
const {
    animatedHandleHeight,
    animatedSnapPoints,
    animatedContentHeight,
    handleContentLayout,
} = useBottomSheetDynamicSnapPoints(initialSnapPoints)

const maxHeightStyle = useBottomSheetMaxHeight(maxHeight)

return (
    <BottomSheetModal
        // .... other props
        snapPoints={animatedSnapPoints as any}
        handleHeight={animatedHandleHeight}
        contentHeight={animatedContentHeight}
    >
        <BottomSheetScrollView
            onLayout={handleContentLayout}
            style={{
                maxHeight: maxHeightStyle,
            }}
        >
            {children}
        </BottomSheetScrollView>
    </BottomSheetModal>
)
// ...

With the custom useBottomSheetMaxHeight hook looking like this:

/*
    Designed to take the specified max height, take away top safe
    area inset and convert to a decimal
*/
import { useWindowDimensions } from "react-native"
import { useSafeAreaInsets } from "react-native-safe-area-context"

export const useBottomSheetMaxHeight = (maxHeight = "85%"): number => {
    const { height: deviceHeight } = useWindowDimensions()
    const maxHeightDecimal = parseFloat(`${maxHeight}`) / 100.0
    const { top: topSafeAreaInset } = useSafeAreaInsets()

    return (deviceHeight - topSafeAreaInset) * maxHeightDecimal
}

@gorhom
Copy link
Owner

gorhom commented Sep 10, 2023

closing this PR in favour of #1513, which it has been merged. Thanks @ororsatti

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants