th3rdwave / react-navigation-bottom-sheet

MIT License
423 stars 18 forks source link

Implement dynamic content snapPoints #7

Closed joseortiz9 closed 11 months ago

joseortiz9 commented 2 years ago

Is not an issue, but it would be amazing to implement this hook useBottomSheetDynamicSnapPoints out of the box, like a screenOptions property. I can contribute if is necessary. Or in case it would be hard we can make a little section in the README how to implemented with the current status of the package.

Shystee commented 2 years ago

Can you share the implementation? @joseortiz9

izakfilmalter commented 1 year ago

Ya would love to know what you did.

izakfilmalter commented 1 year ago

I have the following patch to BottomSheetView to get dynamic snap points working. I don't know if there are performance issues with this, but everything should work.

You will need a Provider to pass handleContentLayout to your modal

import { createContext } from 'react'
import { LayoutChangeEvent } from 'react-native'

export const NavigationContext = createContext<{
  handleContentLayout?: (event: LayoutChangeEvent) => void
}>({})

Patch:

patches/@th3rdwave+react-navigation-bottom-sheet+0.2.2.patch
diff --git a/node_modules/@th3rdwave/react-navigation-bottom-sheet/src/BottomSheetView.tsx b/node_modules/@th3rdwave/react-navigation-bottom-sheet/src/BottomSheetView.tsx
index a83edbe..d25e296 100644
--- a/node_modules/@th3rdwave/react-navigation-bottom-sheet/src/BottomSheetView.tsx
+++ b/node_modules/@th3rdwave/react-navigation-bottom-sheet/src/BottomSheetView.tsx
@@ -2,6 +2,7 @@ import {
   BottomSheetModal,
   BottomSheetModalProps,
   BottomSheetModalProvider,
+  useBottomSheetDynamicSnapPoints,
 } from '@gorhom/bottom-sheet';
 import { ParamListBase, useTheme } from '@react-navigation/native';
 import * as React from 'react';
@@ -12,6 +13,7 @@ import type {
   BottomSheetNavigationProp,
   BottomSheetNavigationState,
 } from './types';
+import { NavigationContext } from '@krewsocial/krew/Navigation/NavigationContext'

 type BottomSheetModalScreenProps = BottomSheetModalProps & {
   navigation: BottomSheetNavigationProp<ParamListBase>;
@@ -20,14 +22,24 @@ type BottomSheetModalScreenProps = BottomSheetModalProps & {
 function BottomSheetModalScreen({
   navigation,
   index,
+  snapPoints = DEFAULT_SNAP_POINTS,
+  children,
   ...props
 }: BottomSheetModalScreenProps) {
   const ref = React.useRef<BottomSheetModal>(null);
   const lastIndexRef = React.useRef(index);

+  const {
+    animatedHandleHeight,
+    animatedSnapPoints,
+    animatedContentHeight,
+    handleContentLayout,
+  } = useBottomSheetDynamicSnapPoints(snapPoints as Array<string | number>)
+
   // Present on mount.
   React.useEffect(() => {
     ref.current?.present();
+
   }, []);

   const isMounted = React.useRef(true);
@@ -62,13 +74,21 @@ function BottomSheetModalScreen({
   }, [navigation]);

   return (
-    <BottomSheetModal
-      ref={ref}
-      index={index}
-      onChange={onChange}
-      onDismiss={onDismiss}
-      {...props}
-    />
+
+      <BottomSheetModal
+        ref={ref}
+        index={index}
+        onChange={onChange}
+        onDismiss={onDismiss}
+        snapPoints={animatedSnapPoints}
+        handleHeight={animatedHandleHeight}
+        contentHeight={animatedContentHeight}
+        {...props}
+      >
+        <NavigationContext.Provider value={{handleContentLayout}}>
+          {children}
+        </NavigationContext.Provider>
+      </BottomSheetModal>
   );
 }

Modal:

export const Modal = () => {
  const { handleContentLayout } = useContext(NavigationContext)

  return (
    <BottomSheetView
      style={{ height: 100 }}
      onLayout={handleContentLayout}
    >
      <Content1>Hangout Feedback</Content1>
    </BottomSheetView>
  )
}
joseortiz9 commented 1 year ago

@izakfilmalter seems lit! we can refactor it to work with this library. I will try to create a PR soon, thanks!

joseortiz9 commented 11 months ago

thanks @mtzfactory for the fix!