osdnk / react-native-reanimated-bottom-sheet

Highly configurable bottom sheet component made with react-native-reanimated and react-native-gesture-handler
MIT License
3.32k stars 327 forks source link

Bottomsheet auto opens when screen load #243

Open burhanahmed92 opened 4 years ago

burhanahmed92 commented 4 years ago

I implemented the bottomsheet on my main screen but issue is that it auto opens whenever the main screen load. I don't want it to be like that. I want bottomsheet to be controlled. i aslo tried with initialSnap={0} but still its not working. Kindly guide me how to fix this

mrbrentkelly commented 4 years ago

I had a similar query. I solved it by wrapping the <BottomSheet/> in a <Modal/> (see https://github.com/react-native-community/react-native-modal). That way you can control the modal visibility directly using its isVisible prop 👍 .

import React from 'react';
import { View, StyleSheet, Text } from 'react-native';
import BottomSheet from 'reanimated-bottom-sheet';
import Modal from 'react-native-modal';

interface Props {
  isVisible: boolean;
  onDismiss: () => void;
}

export default function SheetModal({ isVisible, onDismiss }: Props): React.ReactElement | null {
  return (
    <Modal
      style={styles.modal}
      isVisible={isVisible}
      onDismiss={onDismiss}
      onBackdropPress={onDismiss}>
      <View style={styles.container} pointerEvents="box-none">
        <BottomSheet
          initialSnap={0}
          snapPoints={['50%', 0]}
          onCloseEnd={onDismiss}
          renderHeader={() => (
            <View style={styles.sheetHeader}>
              <View style={styles.panelHeader}>
                <View style={styles.panelHandle} />
              </View>
            </View>
          )}
          renderContent={() => (
            <View style={styles.sheetContent}>
              <View
                style={{
                  backgroundColor: 'red',
                  height: '100%',
                  justifyContent: 'center',
                  alignItems: 'center',
                }}>
                <Text>Some content here</Text>
              </View>
            </View>
          )}
        />
      </View>
    </Modal>
  );
}

const styles = StyleSheet.create({
  modal: {
    margin: 0,
  },
  container: {
    flex: 1,
  },
  sheetHeader: {
    backgroundColor: '#fff',
    paddingTop: 20,
    borderTopLeftRadius: 20,
    borderTopRightRadius: 20,
  },
  sheetContent: {
    backgroundColor: '#fff',
    padding: 15,
  },
  panelHeader: {
    alignItems: 'center',
  },
  panelHandle: {
    width: 40,
    height: 8,
    borderRadius: 4,
    backgroundColor: '#00000040',
    marginBottom: 10,
  },
});
dymank commented 4 years ago

If you have more that one snap point (and you probably have), then initialSnap={0} won't work, because you're snapping to wrong point. Let's say you have snap points like @mrbrentkelly ['50%', 0]. To prevent auto opening on load you need to have initialSnap={1} instead of {0}, because snap point 0, so closed bottom sheet, has index 1 in array of snap points.

bimalgrg519 commented 4 years ago

I am able to close BottomSheet initially by initialSnap={1}. My snapPoints are snapPoints={[450, 0]}. To close BottomSheet, I simply do sheetRef.current.snapTo(0);

ashumantoo commented 4 years ago

@bimalgrg519 can you attach you entire code. I am also tying to same as you but still I am facing the same issue. It's always gets open by default on first loading. Even If I am trying to use snapPoints={[450,0]} it's itself giving error.

newshow321 commented 4 years ago

Just set initialSnap to 2 .. its worked for me ... example: <BottomSheet ref={sheetRef} snapPoints={[450, 300, 0]} borderRadius={10} renderContent={renderContent} enabledContentTapInteraction={true} initialSnap={2} />

newshow321 commented 4 years ago

@burhanahmed92

Just set initialSnap to 2 .. its worked for me ... example: <BottomSheet ref={sheetRef} snapPoints={[450, 300, 0]} borderRadius={10} renderContent={renderContent} enabledContentTapInteraction={true} initialSnap={2} />

mustapha-ghlissi commented 3 years ago

Here is a complete example:

1) Sheet component

import React from 'react' import { View, Platform, TouchableNativeFeedback, TouchableOpacity } from 'react-native' import { Portal, Text } from 'react-native-paper'; import BottomSheet from 'reanimated-bottom-sheet'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import Animated from 'react-native-reanimated'; import styles from '../assets/styles';

const RecipeSheetOptions = ({close, sheetRef}) => {

const [height, setHeight] = React.useState('100%');

const renderInner = () => (
    <View style={styles.recipeSheetContainer}
        onLayout={({nativeEvent}) => {
            setHeight(nativeEvent.layout.height)
        }}
    >
        <View style={styles.header}>
            <View style={styles.headerTag}/>
        </View>
        {
               /* put you content here */
        }
    </View>    
)

const fall = new Animated.Value(1)

return (
    <Portal>
        <BottomSheet
            ref={sheetRef}
            snapPoints={[height , 0]}
            initialSnap={1}
            renderContent={renderInner}
            onCloseEnd={close}
            callbackNode={fall}
            enabledInnerScrolling={false}
        />
    </Portal>
)

}

export default RecipeSheetOptions;

2) Parent component

  In the parent component just import the previous component, then define your sheet Ref and a Close method

   import RecipeSheetOptions from './components/PublicRecipeSheet'

   <RecipeSheetOptions
        sheetRef={this.recipeSheetRef}
        close={closeSheet}
      />

That's all !

mohsinwajid commented 1 year ago

index={-1} Initial snap point index, provide -1 to initiate bottom sheet in closed state.