jeremybarbet / react-native-modalize

A highly customizable modal/bottom sheet that loves scrolling content.
https://jeremybarbet.github.io/react-native-modalize
MIT License
2.84k stars 298 forks source link

Split into two modal and scrollview components #200

Open jacobp100 opened 4 years ago

jacobp100 commented 4 years ago

Is your feature request related to a problem? Please describe. I want to try and embed a stack navigator inside a modalize component (with react-native-screens). This pattern happens in Apple Maps

Describe the solution you'd like If we could split the modal component into a modal container and scroll view component, this would be possible

There could be a combined <ScrollableModal /> that has the stuff you couldn’t do by default with the two component setup like size to content

Describe alternatives you've considered None. I don’t think what I want to do is yet possible

jeremybarbet commented 4 years ago

Hi,

I'm not sure I understand your question. What do you mean by "split the modal component into a modal container and scroll view component".

Don't hesitate to attach gif/video of other apps to have some examples

jacobp100 commented 4 years ago

I mean have one <Modal> component that only does the modal part, and one <ScrollView> component that handles the gestures.

That way I can have a modal component, put a navigator inside (from react native screens), and then inside each screen, but a scrollview

jeremybarbet commented 4 years ago

Okay I got it now.

There is already a customRenderer props made for that. Except that the gesture props are applied to the first children, so it won’t be working in this context.

I could change this function to return as an argument the gesture props and then you could add the navigator as a first child, then the scroll view and pass the props down here.

Does it make sense?

jacobp100 commented 4 years ago

I couldn’t really comment on whether that would work or not until I try it.

But just to clarify, in the same modal, I’ll have multiple screens inside a UINavigationViewController, and each screen will have their own scrollviews and headers in, and all of the headers scrollviews should dismiss the modal.

What would be neat is if I could define something like this,

const Example = () => (
  <BottomModal>
    <Screens initialRoute={ExampleScreen} />
  </BottomModal>
)

const ExampleScreen = () => (
  <View> 
    <BottomModalHeader>
      <Text>Example</Text>
    </BottomModalHeader>
    <BottomModalScrollView>
      <Text>Example</Text>
    </BottomModalScrollView>
  </View>
)

Then I could make loads of screens following the same format

jeremybarbet commented 4 years ago

Based on your code example, it looks way more complicated to do, in fact, it would be a massive refactoring.

All the logics for the header/scrollview is inside the core of Modalize and taking it out would require some work.

It's definitely a good use case and supporting this would be a huge plus. I won't have time to work on it anytime soon, but if you have any chance to jump in the code, feel free to open a PR!

StarryFire commented 4 years ago

I want to use a normal View as the container of the content in modalize rather than a ScrollView, FlatList or SectionList so i can use my own FlatList along with react-navigation's tab navigator. This is giving me a the Cannot use Virtualized List inside scrollView warning otherwise.

Abdulrahman91kh commented 4 years ago

I want to use a normal View as the container of the content in modalize rather than a ScrollView, FlatList or SectionList so i can use my own FlatList along with react-navigation's tab navigator. This is giving me a the Cannot use Virtualized List inside scrollView warning otherwise.

According to the documentation, you can use "customRenderer"

Simply you can do something like ` const AnimatedComponent = ( <Animated.View style={{flex: 1}}> <FlatList .../>

        </Animated.View>

)`

Then you can do <Modalize ref={_modalRef} modalHeight={200} modalStyle={styles.modalStyle} overlayStyle={styles.overlayStyle} panGestureAnimatedValue={animated} customRenderer={AnimatedComponent} />

joeyfigaro commented 4 years ago

@Abdulrahman91kh currently trying exactly this, but the modal never renders. I'm using a component that's using FlatList for customRenderer and have tried wrapping the FlatList with Animated.View. I've also tried replacing FlatList with Animated.FlatList, but no dice.

It's unclear what you're passing to panGestureAnimatedValue in your snippet—where is that coming from? I tried passing the resulting value from new Animated.Value(0) to it, but to no avail.

I'd be happy to contribute an example of using customRenderer if I can manage to get it working. 🔥

joeyfigaro commented 4 years ago

...I managed to get the bottomsheet to finally render, but it throws an error every time.

and the return of my component:

const animated = React.useRef(new Animated.Value(0)).current

return (
    <Modalize
      ref={ref}
      panGestureAnimatedValue={animated}
      HeaderComponent={() => (
        <Header
          goBack={currentStep > 1}
          step={currentStepName}
          onGoBack={handleGoBack}
          onNext={handleNext}
        />
      )}
      customRenderer={<ContactsList contacts={device.contacts} />}
    />
  )

@jeremybarbet can you shed some light here?

WangHansen commented 3 years ago

...I managed to get the bottomsheet to finally render, but it throws an error every time.

and the return of my component:

const animated = React.useRef(new Animated.Value(0)).current

return (
    <Modalize
      ref={ref}
      panGestureAnimatedValue={animated}
      HeaderComponent={() => (
        <Header
          goBack={currentStep > 1}
          step={currentStepName}
          onGoBack={handleGoBack}
          onNext={handleNext}
        />
      )}
      customRenderer={<ContactsList contacts={device.contacts} />}
    />
  )

@jeremybarbet can you shed some light here?

@joeyfigaro How did you end up resolving this issue?