GithubHelp home page GithubHelp logo

gorhom / react-native-bottom-sheet Goto Github PK

View Code? Open in Web Editor NEW
6.1K 31.0 703.0 29.37 MB

A performant interactive bottom sheet with fully configurable options ๐Ÿš€

Home Page: https://ui.gorhom.dev/components/bottom-sheet

License: MIT License

JavaScript 2.64% Java 4.42% TypeScript 86.68% Objective-C 0.11% Ruby 0.28% Handlebars 2.17% Makefile 0.43% C++ 1.99% Objective-C++ 1.27%
bottom-sheet bottomsheet sheet react-native reanimated modal

react-native-bottom-sheet's People

Contributors

alexey-yarmosh avatar allcontributors[bot] avatar andreicalazans avatar anhtrlive avatar beqramo avatar brianathere avatar christophby avatar david-gomes5 avatar ecklf avatar elan avatar emadhajjar avatar ferossgp avatar ghorbani-m avatar gkueny avatar gorhom avatar jakobo avatar jaworek avatar jcgertig avatar jembach avatar jsamr avatar koplyarov avatar likern avatar magrinj avatar mahmoud-sk avatar natew avatar nicolascavallin avatar osdnk avatar shywim avatar stropho avatar vonovak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-bottom-sheet's Issues

BottomSheetScrollView animation bug

Hi!

First of al; thanks for making this awesome package. It works very well.
Today I tried out the <BottomSheetScrollView /> component to enhance the scroll behavior in the bottom sheet.
I have 3 snap points, and if I scroll between snap points 1 and 2 everything works fine, but when I scroll to snap point 0 and then scroll back, the animation is not smooth anymore. It just snaps in to place. I made a video to clarify. You can see the animation is working properly untill I swipe the sheet to the bottom.

issue

Environment info

Library Version
"@gorhom/bottom-sheet": "^1.2.0",
"react-native": "0.63.0",
"react-native-reanimated": "^1.13.0",
"react-native-gesture-handler": "^1.7.0",

Reproducible sample code

This is the code for the bottom sheet

     const bottomSheetRef = useRef(null);
     const snapPoints = useMemo(() => ['5%', '65%', '80%'], []);
     ...
      <BottomSheet
        ref={bottomSheetRef}
        initialSnapIndex={1}
        snapPoints={snapPoints}
        handleComponent={() => <SheetHandle />}
      >
        <BottomSheetScrollView
          style={{ flex: 1, backgroundColor: 'white' }}
        >
          <View style={{ padding: 20, paddingTop: 0 }}>
            <Text>Lorem...</Text>
          </View>
        </BottomSheetScrollView>
      </BottomSheet>

Props color handle and handle container

Feature Request

Schermata 2020-11-20 alle 16 25 50

First Device Pixel 3a, Second Device 4xl.

Schermata 2020-11-20 alle 18 41 33

Why it is needed

Hi @gorhom ,

It would be possible to implement two props to be able to change the color of both the handle and the container that contains the handle.

I tried to create my own handle in order to do this but I realized that on two devices both android their display changes as you can see in the image above.
Instead using the normal non-customized one remains the same.

I don't know if I did something wrong, below is the code of the handle I use.

Code sample


indicator: {
    alignSelf: 'center',
    width: (8 * SCREEN_WIDTH) / 100,
    height: 5,
    borderRadius: 4,
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
  }

const handle = () => {
    return (
      <View
        style={{
          paddingHorizontal: 16,
          paddingVertical: 5,
          backgroundColor,
        }}>
        <View
          style={[
            styles.indicator,
            {
              backgroundColor:
                settings.item.colorScheme === 'light'
                  ? 'rgba(0, 0, 0, 0.25)'
                  : 'rgba(255, 255, 255, 0.25)',
            },
          ]}
        />
      </View>
    );
  };

Used context in bottom sheet in not updated on Android

Bug

Environment info

Library Version
@gorhom/bottom-sheet 1.4.1
react-native 0.63.3
react-native-reanimated 1.13.1
react-native-gesture-handler 1.8.0

Steps To Reproduce

I have created a context for filter options (filtering is selected in bottom sheet)

import React from 'react';

export type FilterContextValue = {
  filter?: 'DATE' | 'NAME';
  setFilter: (filter: FilterContextValue['filter']) => void;
};

export default React.createContext<FilterContextValue>({
  setFilter: () => {},
});

const FilterProvider = ({children}: {children: React.ReactNode}) => {
  const [filter, setFilter] = useState<FilterContextValue['filter']>();

  const value = useMemo(() => ({filter, setFilter}), [filter, setFilter]);

  return <FilterContext.Provider value={value}>{children}</FilterContext.Provider>;
};

export default FilterProvider;

 import {TouchableWithoutFeedback} from '@gorhom/bottom-sheet';

 ...

  const {setFilter} = useContext(FilterCtx);


  <BottomSheetView>
          <TouchableWithoutFeedback
            onPress={() => {
              setFilter('NAME');
            }}>
            <Text>By name</Text>
          </TouchableWithoutFeedback>
          <TouchableWithoutFeedback onPress={() => setFilter('NAME')}>
            <Text>By date</Text>
          </TouchableWithoutFeedback>
        </BottomSheetView>

Describe what you expected to happen:

I expect that pressing By name and By date, the setFilter method created in FilterProvider would be called. In fact, it is the default method (in React.createContext which is called)

I have tried to use setFilter elsewhere and it works fine (that's why I think it is related to bottom-sheets)

Reproducible sample code

I will create one later

gesture callback support

Feature Request

Hi @gorhom. I can't find any props relate with gestureStateChange. Can we have one?

Why it is needed

My case I have some conflict relate with React Native TabView. So I might need to disable the tabView while the bottom-sheet start drag up/down.

Possible implementation

It's good to have Handle State

https://docs.swmansion.com/react-native-gesture-handler/docs/state
There are six possible states for the handler:

UNDETERMINED
FAILED
BEGAN
CANCELLED
ACTIVE
END

Thanks

Android input issue where bottom sheet moves upon keyboard opening

Bug

Through these styles:
src/components/BottomSheet/styles.ts

  container: {
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 0,
  }

it happens that when opening the Keyboard on android (e.g. having a text input in the bottom sheet's content) the content gets pushed up:
BOTTOM

This is the default behaviour on android. Interestingly, this doesn't happen when changing the styles from bottom -> top.

  container: {
    position: 'absolute',
    left: 0,
    right: 0,
    top: 0,
  }

TOP

However, this breaks the BottomSheet, as all calculations are thought to be run from the bottom edge.
I am aware that it is possible to change on android the windowSoftInputMode, however, this is quite invasive and doesn't work with projects using react native navigation.

Environment info

Library Version
@gorhom/bottom-sheet 1.4.1
react-native 0.63.3
react-native-reanimated 2.0.0-alpha.8
react-native-gesture-handler 1.8.0

Reproducible sample code

Please tell me whether reproduction is necessary.

Cannot convert undefined value to object

Bug

I've tried to add the library two times and follow all the necessary instructions to make it run but I always got Cannot convert undefined value to object

What I did:

  • yarn add @gorhom/[email protected]
  • yarn add react-native-reanimated@alpha
  • yarn add react-native-gesture-handler
  • project.ext.react = [
    enableHermes: true, // clean and rebuild if changing
    ]
  • import com.facebook.react.bridge.JSIModulePackage;
  • import com.swmansion.reanimated.ReanimatedJSIModulePackage;
  • @OverRide
    protected JSIModulePackage getJSIModulePackage() {
    return new ReanimatedJSIModulePackage(); // <- add
    }

Captura de Pantalla 2020-10-05 a la(s) 09 51 39

Web support

Hey!

I just started using this, and so far it's great! Seems like the best bottom drawer out there

Feature Request

I'm currently trying to use this library with an Expo / React Native Web app. In order to get it working, I used patch-package to add a Touchables.web.js file and a ContentWrapper.web.js file that are exact replicas of their respective ios files. I was wondering if it would be possible to add these two files so patching isn't necessary to support web?

Thanks!

`onChange` is called on initial render in iOS

First of all thanks for creating this awesome library!

Bug

I have noticed that on iOS <BottomSheet/>'s onChange prop is being called when the component is mounted. I suspect this behavior also exists in useBottomSheetModal.

On Android, it is working as expected though. I am not sure, maybe I am doing something wrong.

Environment info

Library Version
@gorhom/bottom-sheet ^1.4.1
react-native ~0.62.2
react-native-reanimated ~1.9.0
react-native-gesture-handler ~1.6.0

Steps To Reproduce

I wanted to have 2 BottomSheets which I could "navigate" between them. When the second one is closed, the first one should be opened. But when I open the app on iPhone it expands the first BottomSheet immediately.

Initially, I used <BottomSheet/> (first one) and useBottomSheetModal(for the second one), but it didn't work as I expected, probably because of the same reason.

Reproducible sample code

export function HomeScreen() {
  const [isButtonVisible, setIsButtonVisible] = useState(true);
  const bottomSheetRef1 = useRef<BottomSheet>(null);
  const bottomSheetRef2 = useRef<BottomSheet>(null);

  return (
    <>
      <BottomSheet
        ref={bottomSheetRef1}
        snapPoints={["20%", "60%"]}
        onChange={() => {
          // For checking
          console.log("onChange is called in first BottomSheet");
        }}
      >
        <MyComponent1 />
      </BottomSheet>

      <BottomSheet
        ref={bottomSheetRef2}
        snapPoints={[0, "20%", "60%"]}
        onChange={(index) => {
          // For checking
          console.log("onChange is called in second BottomSheet");

          if (index === 0) {
            bottomSheetRef1.current?.expand();
            setIsButtonVisible(true);
          }
        }}
      >
        <MyComponent2 />
      </BottomSheet>

      {isButtonVisible && (
        <View>
          <Button
            onPress={() => {
              bottomSheetRef1.current?.close();
              bottomSheetRef2.current?.expand();
              setIsButtonVisible(false);
            }}
          >
            Open Second
          </Button>
        </View>
      )}
    </>
  );
}

/*  console output:

    onChange is called in second BottomSheet
    onChange is called in second BottomSheet
    onChange is called in first BottomSheet
*/

Failed to import Modal hooks and provider; TypeScript

Bug

Per the docs it should be possible to import Modal Provider like this:
import { BottomSheetModalProvider, useBottomSheetModal } from "@gorhom/bottom-sheet"; however this errors to:

Module '"../../node_modules/@gorhom/bottom-sheet/lib/typescript"' has no exported member 'BottomSheetModalProvider'. Did you mean to use 'import BottomSheetModalProvider from "../../node_modules/@gorhom/bottom-sheet/lib/typescript"' instead?

Environment info

Library Version
@gorhom/bottom-sheet 2.0.0-alpha.0
react-native 0.63.3
react-native-reanimated 2.0.0-alpha.8
react-native-gesture-handler 1.8.0

Steps To Reproduce

  1. add module with yarn add @gorhom/[email protected]
  2. attempt described import

Describe what you expected to happen:

  1. The module to import successfully

Reproducible sample code

import { BottomSheetModalProvider, useBottomSheetModal } from "@gorhom/bottom-sheet";

BottomSheet exceeds the maximum height when Keyboard is open on Android

Bug

I have a TextInput on top of the BottomSheet.
On Android, when the focus is on the TextInput, the keyboard is open and the top of the BottomSheet is no longer visible.
I try to solve the bug by removing the keyboard.height to the max snapPoint but then, the gestures on the BottomSheet are buggy.
When I look at the Map example, i can see in the AndroidManifest.xml android:windowSoftInputMode="adjustPan".
In my project I set windowSoftInputMode to adjustResize.
Any idea how can I prevent the BottomSheet to not exceed the maximum height ?

Without focus focus
Screenshot_20201110-125310 Screenshot_20201110-125317

Environment info

Library Version
@gorhom/bottom-sheet 1.4.1
react-native 0.62.2
react-native-reanimated 1.13.1
react-native-gesture-handler 1.8.0

Steps To Reproduce

  1. Focus an input on android inside a BottomSheet
  2. See how the keyboard put the content to the top of the screen

Describe what you expected to happen:

  1. improve the keyboard handling

Reproducible sample code

import * as React from 'react';

import BottomSheet, { BottomSheetOverlay, BottomSheetSectionList } from '@gorhom/bottom-sheet';
import { useFocusEffect } from '@react-navigation/native';
import { StackScreenProps, useHeaderHeight } from '@react-navigation/stack';
import { Dimensions, InteractionManager } from 'react-native';
import { Platform, StatusBar } from 'react-native';
import { TextInput } from 'react-native-gesture-handler';
import { Easing, Extrapolate, interpolate } from 'react-native-reanimated';
import { useValue } from 'react-native-redash/lib/module/v1';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import styled from 'styled-components/native';

import { MainStackParamList } from 'navigation/MainNavigator';

import BlurredBackground from './BlurredBackground';
import HomeMap from './HomeMap/HomeMap';

const { height: SCREEN_HEIGHT } = Dimensions.get('window');

const STATUS_BAR_HEIGHT = Platform.select({
  android: StatusBar.currentHeight || (Platform.Version < 23 ? 25 : 24),
  default: 0,
});

const Home: React.FC<StackScreenProps<MainStackParamList, 'Home'>> = ({}) => {
  const bottomSheetRef = React.useRef<BottomSheet>(null);
  const { top: topSafeArea, bottom: bottomSafeArea } = useSafeAreaInsets();

  const headerHeight = useHeaderHeight();

  const snapPoints = React.useMemo(() => [bottomSafeArea + 194, SCREEN_HEIGHT / 2, SCREEN_HEIGHT - STATUS_BAR_HEIGHT - headerHeight - topSafeArea], [
    bottomSafeArea,
    headerHeight,
    topSafeArea,
  ]);
  const animatedPosition = useValue<number>(0);
  const animatedPositionIndex = useValue<number>(0);
  const animatedOverlayOpacity = React.useMemo(
    () =>
      interpolate(animatedPosition, {
        inputRange: [snapPoints[1], snapPoints[2]],
        outputRange: [0, 0.25],
        extrapolate: Extrapolate.CLAMP,
      }),
    [animatedPosition, snapPoints],
  );

  const handleSheetChanges = React.useCallback((index: number) => {
    console.log('handleSheetChanges', index);
  }, []);

  const initBottomSheet = React.useCallback(() => {
    const task = InteractionManager.runAfterInteractions(() => {
      bottomSheetRef.current?.snapTo(1);
    });

    return () => task.cancel();
  }, []);

  useFocusEffect(initBottomSheet);

  return (
    <Container>
      <HomeMap />
      <BottomSheetOverlay pointerEvents="none" animatedOpacity={animatedOverlayOpacity} />
      <BottomSheet
        ref={bottomSheetRef}
        snapPoints={snapPoints}
        initialSnapIndex={0}
        topInset={topSafeArea}
        animatedPosition={animatedPosition}
        animatedPositionIndex={animatedPositionIndex}
        animationDuration={500}
        animationEasing={Easing.out(Easing.exp)}
        backgroundComponent={BlurredBackground}
        onChange={handleSheetChanges}>
        <BottomSheetScreen>
          <TextInput />
          <BottomSheetSectionList
            sections={data}
            keyExtractor={(item, index) => item.id + index}
            renderItem={renderItem}
            renderSectionHeader={renderSectionHeader}
            stickySectionHeadersEnabled={false}
            keyboardDismissMode="on-drag"
            keyboardShouldPersistTaps="handled"
          />
        </BottomSheetScreen>
      </BottomSheet>
    </Container>
  );
};
const Container = styled.View`
  position: relative;
  flex: 1;
`;
const BottomSheetScreen = styled.View`
  flex: 1;
`;

export default Home;

Pull to refresh

Feature Request

The ability to pull the bottom sheet down when it is in its default position and trigger reload of Flatlist/Sectionlist.

Why it is needed

Very common action to refresh a list by pulling the list down.

Code sample

I have tempted something like having three snap points, the lowest for the data fetching.

   const handleSheetChange = useCallback(async index => {
      if (index === 0) {
         // shows the ActivityIndicator and sets a state that is used to locking the bottom sheet
         setFetchingScreen(true);
  
       await fetchData()
  
       setFetchingScreen(false);

        // Move the sheet to original place when data has been fetched
         sheetRef.current?.snapTo(1);
      }
   }, []);

But it is slow and pretty buggy. Any suggestions of how it would be best to achieve this?

Best regards and thank you for a great library!

runOnJS Errors in Reanimated 2.0.0-alpha.8

Bug

Reanimated V2 just released 2.0.0-alpha.8. It offers lots of fixes over 2.0.0-alpha.7 and no longer requires turbo modules to be globally enables (no more AppDelegate setup). There is a breaking change in that you now must explicitly specify which thread you're running a function, either runOnJS or runOnUI. Functions must either runOnUI if they are to be sync or runOnJS if they are to be async. See here.

In iOS using the bottom sheet results in this error:

Simulator Screen Shot - iPhone 11 - 2020-11-01 at 23 09 38

Environment info

Library Version
@gorhom/bottom-sheet 2.0.0-alpha.0
react-native 0.63.2
react-native-reanimated 2.0.0-alpha.8
react-native-gesture-handler 1.7.0

Steps To Reproduce

Use bottom-sheet with Reanimated V2 2.0.0-alpha.8

Incompatible with Expo 38

Bug

The current Expo version (38) only supports react-native-reanimated 1.9. It looks this package is using useValue which was introduced in reanimated 1.10.

I'm not sure if there are other methods that this package depends that makes it incompatible with Expo 38.

import Animated, { useValue } from 'react-native-reanimated';

Environment info

Library Version
@gorhom/bottom-sheet 1.1.1
react-native 0.62 (Expo 38)
react-native-reanimated ~1.9
react-native-gesture-handler ~1.6.0

Steps To Reproduce

Render the component and get the following error:

(0, _reactNativeReanimated.useValue) is not a function. (In '(0, _reactNativeReanimated.useValue)(0)', '(0, _reactNativeReanimated.useValue)' is undefined)

Content is not intractable when providing one snap point

Bug

The bug appears for more than 1 spnap points.
Suppose you have a button on the sheet with a onPress event handler. The onPress event works only for the last snap point.
otherwise, it wont.

Environment info

Version V1

Reproducible sample code

<BottomSheet> ... <Button onPress={() => { alert();} }></Button> ... <BottomSheet/>

Does handle shadow comes out of the box?

Bug

Great library! thanks a lot. Does handle shadow comes out of the box? I am not seeing shadow on top of sheet. it would be great if you could provide some example that has shadow and if you have then apologies.

Environment info

Library Version
@gorhom/bottom-sheet ^1.4.1
react-native 0.62.2
react-native-reanimated ^1.8.0
react-native-gesture-handler ^1.6.1

Steps To Reproduce

  1. Open bottom sheet

Describe what you expected to happen:

  1. Open bottom sheet
  2. Shadow on top of handle should be displayed

Reproducible sample code

Possibility to disable gestures

Feature Request

Hey, I've been loving this library, great work! I've been missing an option to disable gestures on the bottomsheet so the user wouldn't be able to swipe it away

Why it is needed

In case you want to put something important in the bottomsheet, and want the user to not accidentally close it by swipining/scrolling around

Updating state causes methods on bottom sheet to stop working

Bug

I have some state updates I need to do in my component when I want my bottom sheet to be opened, however when I do this my call to bottomSheetRef.current?.snapTo(1) no longer works. If I comment out the state update then it starts working again. The order in which the state update and calling the snapTo method makes no difference either. I have also tried using bottomSheetRef.current?.expand() and it has the same issue.

Environment info

Library Version
@gorhom/bottom-sheet 1.2.0
react-native 0.63.2
react-native-reanimated 1.13.0
react-native-gesture-handler 1.8.0

Steps To Reproduce

  1. Add a function which updates some state on the component and then call one of the methods on the bottom sheet ref
  2. Trigger the function
  3. State is updated but the method on the bottom sheet is not called
  4. Comment out the state update and trigger the function
  5. The method on the bottom sheet now behaves as expected

Describe what you expected to happen:

  1. The method on the bottom sheet should be called regardless of component state update

Reproducible sample code

import BottomSheet from '@gorhom/bottom-sheet';
import React, {useMemo, useRef, useState} from 'react';
import {Button, StyleSheet, Text, View} from 'react-native';

const App = () => {
  const [counter, setCounter] = useState(0);
  const bottomSheetRef = useRef<BottomSheet>(null);
  const snapPoints = useMemo(() => [0, '90%'], []);

  const openBottomSheet = () => {
    // comment out setCounter and the bottom sheet opens as expected
    setCounter((prev) => prev + 1);
    bottomSheetRef.current?.snapTo(1);
  };

  return (
    <View style={styles.container}>
      <Button onPress={openBottomSheet} title="Open bottom sheet" />
      <BottomSheet ref={bottomSheetRef} snapPoints={snapPoints}>
        <Text>Hello</Text>
      </BottomSheet>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 24,
  },
});

export default App;

Is it possible to do Reddit like bottom sheet embedded in stack navigator?

Bug

WhatsApp Image 2020-10-03 at 12 46 09 PM
Is it possible to implement something like what reddit does? main screen of stack navigator will be a bottom sheet which will subsequently call other stack screens. Could you please point me to as how we can achieve this?

Environment info

Library Version
@gorhom/bottom-sheet ^1.4.1
react-native 0.62.2
react-native-reanimated ^1.8.0
react-native-gesture-handler ^1.6.1

Steps To Reproduce

  1. Click on one of the tab from Tab navigator (Each tab will have its own stack navigator)
  2. First screen on stack navigator is bottom sheet
  3. Open bottom sheet, Currently it opens and covers entire screen

Describe what you expected to happen:

  1. Click on one of the tab from Tab navigator (Each tab will have its own stack navigator)
  2. First screen on stack navigator is bottom sheet
  3. Open bottom sheet (refer to attached screen)

Reproducible sample code

Bug Opening dialog strange effect

Bug

Schermata 2020-11-20 alle 18 23 23

Registrazione schermo 2020-11-20 alle 18 20 24

Hi @gorhom ,

as you can see from the images when I open the dialog bottom sheet, that effect happens.
I could see that it happens both with short times and with long times as in the example in the gif.

Environment info

Library Version
@gorhom/bottom-sheet 1.4.1
react-native 0.63.3
react-native-reanimated 1.13.2
react-native-gesture-handler 1.8.0

Reproducible sample code

const bottomSheetLang = useCallback((newValue, id) => {
    present(
      <View style={{ flex: 1, backgroundColor }}>
        <Text>{settings.item.lang}</Text>
        <RadioButton.Group
          onValueChange={(newValue) => changeButtonLang(newValue)}
          value={settings.item.lang}>
          <View style={(Layout.row, Layout.rowHCenter)}>
            <RadioButton value="en" />
            <Text>En</Text>
          </View>
          <View style={(Layout.row, Layout.rowHCenter)}>
            <RadioButton value="fr" />
            <Text>Fr</Text>
          </View>
          <View style={(Layout.row, Layout.rowHCenter)}>
            <RadioButton value="it" />
            <Text>It</Text>
          </View>
        </RadioButton.Group>
      </View>,
      {
        snapPoints: ['50%'],
        animationDuration: 5000,
        overlayComponent: BottomSheetOverlay,
        overlayOpacity: 0.5,
        dismissOnOverlayPress: true,
        //handleComponent: handle,
        //backgroundComponent: BlurredBackground,
        //onChange: handleChange,
      }
    );
  }, [settings]);

Button / Pressable rendered inside Bottom Sheet are not clickable on Android device

Bug

Button / Pressable rendered inside Bottom Sheet are barely clickable on Android device.
It behaves differently than a normal Button/Preesable outside of bottom sheet.

Environment info

Library Version
@gorhom/bottom-sheet 2.0.0-alpha.0
react-native 0.63.2
react-native-reanimated 2.0.0-alpha.6
react-native-gesture-handler 1.7.0

Steps To Reproduce

Describe what you expected to happen:

  1. Press the "Press me" to see 'xxxxx' display in terminal

Reproducible sample code

 <View style={styles.container}>
      <BottomSheet
        ref={bottomSheetRef}
        initialSnapIndex={1}
        snapPoints={snapPoints}
        onChange={handleSheetChanges}
      >
        <Pressable onPress={() => console.log('xxxxx')} style={{ backgroundColor: 'cyan', height: 100 }}>
            <Text>Press me</Text>
          </Pressable>
      </BottomSheet>
    </View>

Unexpected token at index.ts

Bug

Screenshot from 2020-09-16 14-46-26

Environment info

Library Version
@gorhom/bottom-sheet 1.2.2
react-native 0.61.4
react-native-reanimated 1.13.0
react-native-gesture-handler 1.8.0

i got this error when i want to run the app. I'm using JS not TS

Incompatible with reanimated v2

Current Behavior

App crashes with the example usage from docs

  • What code are you running and what is happening?
    with the example usage from docs

Expected Behavior

Not to crash

How to reproduce

Run a simple example of the library using Reanimated 2

The reason I guess since I had faced it before is that it uses interpolate instead of interpolateNode since in reanimated 2 it should me imported as interpolateNode
one place I found that is using interpolate

Dynamic Bottom Sheet height based on Children height

Feature Request

It would be awesome if you add dynamic height feature based on the children height (and still able to define max height of the bottom sheet). Also the snapPoints prop should be relative to the total Bottom Sheet height, not the screen height.

Why it is needed

Sometimes we only need to render only a few items inside the bottom sheet. So there's no need to define the bottom sheet height. It should adjust itself according to the children height. And the snapPoints should be relative to the height of the bottom sheet, not the screen height like in the example.

BottomSheetScrollView gets stuck when sheet is expanded

Bug

When switching between BottomSheetScrollViews, if the sheet is in an expanded view then it gets stuck and the content won't scroll until you minimize the sheet and then expand it again. I'm using the focus hook from react navigation, and it's still not working.

Environment info

Library Version
@gorhom/bottom-sheet 1.2.2
react-native 0.63.2
react-native-reanimated 1.13.0
react-native-gesture-handler 1.8.0

Steps To Reproduce

  1. Have one bottom sheet, with two children views and as the top parent of each
  2. Switch from one to another while the sheet is expanded
  3. Attempt to scroll in the body

Describe what you expected to happen:

  1. Scrolling doesn't work, but should

Reproducible sample code

In progress

onChange index is NaN when snapPoints array is length 1

Bug

onChange index is NaN when snapPoints array is length 1 i.e const snapPoints = useMemo(() => ['80%'], []); then console.log('handleSheetChange', index); outputs handleSheetChange NaN

I am trying to implement an overlay behind my bottom sheet which displays when the bottom sheet is open but currently my onChange is only outputting NaN so I have no way of knowing whether the bottom sheet is open or closed.

Environment info

Library Version
@gorhom/bottom-sheet "2.0.0-alpha.0"
react-native "0.63.2"
react-native-reanimated "2.0.0-alpha.6"
react-native-gesture-handler "1.8.0"

Steps To Reproduce

  1. Add bottomSheet with only 1 snap point
  2. Listen to onChange events
  3. Call bsRef.current?.snapTo(0) to open and bsRef.current?.close() to open and close
  4. index parameter outputs NaN because currentPositionIndexRef.current is NaN

Describe what you expected to happen:

  1. When bsRef.current?.snapTo(0) is called. I would expect index = 0
  2. When bsRef.current?.close() is called. I would expect index = -1`

Reproducible sample code

Here is my component. Currently it sits in a private repo which I am not allowed to share but I can recreate the situation in isolation if you are having trouble recreating the bug

import React, {useCallback, useMemo, RefObject} from 'react';
import {TouchableOpacity, StyleSheet, ViewProps} from 'react-native';
import {Box, Text} from '@private-space/ui';
import BottomSheet, {BottomSheetView} from '@gorhom/bottom-sheet';
import Animated, {
  Easing,
  useAnimatedProps,
  useAnimatedStyle,
  withTiming,
} from 'react-native-reanimated';


interface Props {
  bsRef: RefObject<BottomSheet>;
  onClickItem: () => void;
}

export const WorkoutBottomSheet = ({
  bsRef,
  onClickItem,
}: Props) => {
  const snapPoints = useMemo(() => ['80%'], []);
  const [isOpen, setIsOpen] = React.useState(false);

  const handleSheetChange = useCallback((index: number) => {
    console.log('handleSheetChange', index);
    if (index > 0) {
      setIsOpen(true);
    }
  }, []);

  const handleClosePress = useCallback(() => {
    setIsOpen(false);
    bsRef.current?.close();
  }, []);


  const overlayStyle = useAnimatedStyle(() => {
    const toValue = isOpen ? 0.3 : 0;
    return {
      opacity: withTiming(toValue, {duration: 100, easing: Easing.linear}),
    };
  });

  const animatedProps = useAnimatedProps<ViewProps>(() => {
    return {
      pointerEvents: isOpen ? 'auto' : 'none',
    };
  });

  return (
    <>
      <Animated.View
        animatedProps={animatedProps}
        style={[
          {
            ...StyleSheet.absoluteFillObject,
            backgroundColor: '#000',
          },
          overlayStyle,
        ]}
      />
      <Box position="absolute" height={20} bottom={0} left={0} right={0}>
        <BottomSheet
          ref={bsRef}
          initialSnapIndex={-1}
          snapPoints={snapPoints}
          onChange={handleSheetChange}>
          <BottomSheetView>
            <Box
              justifyContent="flex-start"
              alignItems="center"
              backgroundColor="white"
              padding="m"
              flex={1}
              height={650}>
              <Box
                alignSelf="stretch"
                flexDirection="row"
                justifyContent="space-evenly"
                marginBottom="l">
                <Text variant="textPreset10" color="primary70">
                  Choose a workout
                </Text>
                <Box position="absolute" right={0}>
                  <TouchableOpacity
                    onPress={() => {
                      handleClosePress();
                      setIsOpen(false);
                    }}>
                    <Text color="primary100">Close</Text>
                  </TouchableOpacity>
                </Box>
              </Box>
              <Box alignSelf="stretch">
                {/*workoutTypes.map((type, index) => (
                  <WorkoutTypeItem
                    key={index}
                    type={type}
                    onPress={() => {
                      onClickItem(type);
                      handleClosePress();
                      setIsOpen(false);
                    }}
                    checked={type === selectedWorkoutType}
                  />
                  ))*/}
              </Box>
            </Box>
          </BottomSheetView>
        </BottomSheet>
      </Box>
    </>
  );
};

Add Modal Feature

Feature Request

Why it is needed

This will the library to behave like a Modal View.

Possible implementation

We could introduce:

  • BottomSheetContainerProvider: this will be responsible of:

    • holding the BottomSheet view.
    • mounting & unmount the BottomSheet when user trigger the modal.
    • exposing a new context for modal use.
  • useBottomSheetModal: this will expose:

    • present a method that will mount the bottom sheet with initial close position, then snap to a provided snap point.
    • dismiss a method that will close the bottom sheet then unmount it.
    • snapTo a method to snap to a certain point.

Code sample

BottomSheetContainerProvider

# to be add at the root
<BottomSheetContainerProvider>
  <App />
</BottomSheetContainerProvider>

# 
const { present } = useBottomSheetModal()

...

const handlePresetView = () => {
  present({
    snapPoints: [100, '50%', '90%'],
    children: /** BOTTOM SHEET CONTENT */
  })
}

useBottomSheetModal

interface BottomSheetModalContext {
  present: (configs: BottomSheetProps) => void
  dismiss: () => void
  snapTo: (index: number) => void
}

Error while updating property 'disableIntervalMomentum' of a view managed by: RCTScrollView ANDROID

Bug

Environment info

Library Version
@gorhom/bottom-sheet ^1.1.0
react-native 0.63.1
react-native-reanimated ^1.12.0
react-native-gesture-handler ^1.6.1

Reproducible sample code

                <BottomSheet2
                    // ref={bottomSheetRef}
                    initialSnapIndex={0}
                    snapPoints={[300, contentHeight]}
                // onChange={handleSheetChanges}
                >
                    <BottomSheetFlatList
                        data={this.state.dataProvider.length ? this.state.dataProvider : NOT_FOUND}
                        keyExtractor={item => item.id}
                        initialNumToRender={10}
                        windowSize={20}
                        maxToRenderPerBatch={5}
                        renderItem={this._rowRenderer}
                        // {...(header && {
                        //   stickyHeaderIndices: [0],
                        //   ListHeaderComponent: header,
                        // })}
                        contentContainerStyle={styles.listContainer}
                    // focusHook={useFocusEffect}
                    />
                </BottomSheet2>

1597291007908

My solution

in FlatList.tsx
change disableIntervalMomentum={disableIntervalMomentum} to disableIntervalMomentum={false} and it working

i try fix disableIntervalMomentum: Animated.Node<number>; to disableIntervalMomentum: Animated.Node<boolean>;but it not working

Error when list is empty

Bug

When using BottomSheetFlatList with an empty list you get the following error:
scrollToIndex out of range: requested index 0 but maximum is -1

IMG_0305

Environment info

Library Version
@gorhom/bottom-sheet 1.1.1
react-native 0.63.2
react-native-reanimated 1.12.0
react-native-gesture-handler 1.7.0

Steps To Reproduce

  1. Ensure the list is empty
  2. Open the bottom sheet
  3. Close the bottom sheet

Reproducible sample code

import { AppRegistry, LogBox } from 'react-native';
import BottomSheet, { BottomSheetFlatList } from '@gorhom/bottom-sheet';

const App = function App() {
    return (
        <BottomSheet snapPoints={[100, 600]}>
            <BottomSheetFlatList
                contentContainerStyle={{ flexGrow: 1, backgroundColor: '#fff' }}
                data={[]}
                renderItem={() => null}
            />
        </BottomSheet>
    );
};

AppRegistry.registerComponent('App', () => App);

Default backdrop

Feature Request

Provide a default backdrop/background component with a translucent background color.

Why it is needed

To distinguish that the bottom sheet is visible, or it pops out when the UI behind is mostly color white.

Possible implementation

backgroundComponent should have a default implementation, I'm thinking it is also useful to export that component as BottomSheetBackdrop so that users can provide custom styling.

noBackdrop prop will also help to disable the default backdrop component.

Code sample

import BottomSheet, {BottomSheetBackdrop} from '@gorhom/react-native-bottom-sheet`;

const MyBackdrop = () => <BottomSheetBackdrop style={{
	backgroundColor: 'red',
}}/>

<BottomSheet />
<BottomSheet noBackdrop/>
<BottomSheet backgroundComponent={MyBackdrop}/>

Snap point of '0%' throws error

Bug

Is having a bottom sheet completely hidden/off the screen against design guidelines, or simply missed?

Environment info

Library Version
@gorhom/bottom-sheet 2.0.0-alpha.0
react-native 0.63.3
react-native-reanimated 2.0.0-alpha.7
react-native-gesture-handler 1.8.0

Steps To Reproduce

  1. Set any bottom sheet with a snap point that contains '0%' (i.e. ['0%', '80%'])

Describe what you expected to happen:

  1. To allow the user to completely 'swipe away' the bottom sheet.

Reproducible sample code

<BottomSheet
  ref={bsRef}
  initialSnapIndex={-1}
  onChange={onBottomSheetChanged}
  animatedPositionIndex={position}
  snapPoints={['0%', '80%']}>
...
</BottomSheet>

Roadmap for v2 ( Reanimated v1 )

Bottom Sheet v2 ( Reanimated v1 )

These are the planned improvements and features for v2.

Improvements

  • Change the current v2 alpha release into v3.
  • Fix measuring bottom sheet container to use its actual size than window height. #77
  • [blocker] Extract BottomSheetModal into a separate repository and package, or refactor repository to become a monorepo.
  • [blocker] Add documentation site.

Features

  • Add animateOnMount prop to snap to the initial snap point index when the sheet is mounted. (#78)
  • Add dynamic snap points feature. #32
  • Add enableContentPanningGesture prop to allow panning sheet by its content view or scrollables. #55
  • [not blocker] Allow scrollables bouncing.
  • Refactor BottomSheetModal to make it declarative component, using @gorhom/portal.
  • [blocker] Add default backdrop #45.

Install Stable Release

yarn add @gorhom/bottom-sheet

also check out the new documents website ( still in progress ) ๐ŸŽ‰

Roadmap for v3 ( Reanimated v2 )

Bottom Sheet v3 ( Reanimated v2 )

These are the planned improvements and features for v3.

Improvements

  • Change the current v2 alpha release into v3.
  • Fix measuring bottom sheet container to use its actual size than window height.
  • Add documentation site.

Features

  • Add BottomSheetModal ๐Ÿ”ฅ
  • Add animateOnMount prop to snap to the initial snap point index when the sheet is mounted.
  • Add onAnimate callback
  • Add dynamic snap points feature.
  • Add enablePanningGesture prop to enable panning gesture of the sheet.
  • Add enableContentPanningGesture prop to allow panning sheet by its content view or scrollables.
  • Allow scrollables bouncing.
  • Add default backdrop #45.

Install Stable Release

yarn add @gorhom/bottom-sheet@3.0.0

also check out the new documents website ๐ŸŽ‰

useBottomSheetModal problem useCallback internal parameters that do not update

Bug

Registrazione schermo 2020-11-20 alle 14 47 55

Hi @gorhom , i am having the following problem, i am using present by useBottomSheetModal, as you can see from the image through the buttons i should change the theme.

The status is not updated internally, only when you reopen the BottomSheetModal the status is updated.

How can I solve?

Environment info

Library Version
@gorhom/bottom-sheet 1.4.1
react-native 0.63.3
react-native-reanimated 1.13.2
react-native-gesture-handler 1.8.0

Reproducible sample code

import React, {
  useState,
  useEffect,
  useCallback,
  useMemo,
  useRef,
} from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { View, StyleSheet, Image, Dimensions } from 'react-native';
import { Text, Button, RadioButton } from 'react-native-paper';
import {
  Common,
  Fonts,
  Gutters,
  Layout,
  Images,
  Colors,
  ColorsDarkMode,
} from '@/Theme';
import { useTranslation } from 'react-i18next';
import Settings from '@/Store/Settings/Init';
const { width: SCREEN_WIDTH } = Dimensions.get('screen');

import AppIntroSlider from 'react-native-app-intro-slider';

import {
  BottomSheetModalProvider,
  useBottomSheetModal,
  BottomSheetOverlay,
} from '@gorhom/bottom-sheet';
import withModalProvider from './withModalProvider';
import BlurredBackground from './BlurredBackground';

const styles = StyleSheet.create({
  slide: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  image: {
    width: 320,
    height: 320,
    marginVertical: 32,
    resizeMode: 'stretch',
  },
  text: {
    color: 'rgba(255, 255, 255, 0.8)',
    textAlign: 'center',
  },
  title: {
    fontSize: 22,
    color: 'white',
    textAlign: 'center',
  },
  blurView: {
    ...StyleSheet.absoluteFillObject,
  },
  container: {
    ...StyleSheet.absoluteFillObject,
    borderTopLeftRadius: 10,
    borderTopRightRadius: 10,
    overflow: 'hidden',
  },
  androidContainer: {
    backgroundColor: 'rgba(255,255,255, 0.95)',
  },
  indicator: {
    alignSelf: 'center',
    width: (8 * SCREEN_WIDTH) / 100,
    height: 5,
    borderRadius: 4,
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
  },
});

const IndexInstallationContainer = (props) => {
  const { t } = useTranslation();
  const dispatch = useDispatch();
  const settings = useSelector((state) => state.settings);
  const { present } = useBottomSheetModal();

  const handlePresentPress = useCallback(() => {
    present(
      <View style={{ flex: 1, backgroundColor }}>
        <Text>{settings.item.colorScheme}</Text>
        <RadioButton.Group
          onValueChange={(newValue) => changeButtonTheme(newValue)}
          value={settings.item.colorScheme}>
          <View style={(Layout.row, Layout.rowHCenter)}>
            <RadioButton value="light" />
            <Text>Light</Text>
          </View>
          <View style={(Layout.row, Layout.rowHCenter)}>
            <RadioButton value="dark" />
            <Text>Dark</Text>
          </View>
        </RadioButton.Group>
      </View>,
      {
        snapPoints: ['20%'],
        animationDuration: 300,
        overlayComponent: BottomSheetOverlay,
        overlayOpacity: 0.5,
        dismissOnOverlayPress: true,
        handleComponent: handle,
        //backgroundComponent: BlurredBackground,
        //onChange: handleChange,
      }
    );
  }, [present, dispatch, settings]);

  const slides = [
    {
      key: 'one',
      title: t('welcome'),
      text: '',
      image: Images.logo,
      backgroundColor: '#2196f3',
    },
    {
      key: 'two',
      title: t('change.language'),
      text: '',
      backgroundColor: '#ffc107',
    },
    {
      key: 'three',
      title: t('change.mode'),
      text: '',
      backgroundColor: '#4caf50',
    },
  ];

  const changeTheme = () => {
    dispatch(
      Settings.action({
        colorScheme: settings.item.colorScheme === 'dark' ? 'ligth' : 'dark',
      })
    );
  };

  const changeButtonTheme = (colorScheme) => {
    dispatch(Settings.action({ colorScheme }));
  };

  const openBottom = () => setState((prev) => ({ ...prev, open: !prev.open }));

  const b = (
    <Button
      style={[Gutters.largeHMargin, Gutters.largeBMargin]}
      raised
      mode="contained"
      onPress={handlePresentPress}>
      {t('actions.change')}
    </Button>
  );

  const _renderItem = ({ item }) => {
    return (
      <View style={[styles.slide, { backgroundColor: item.backgroundColor }]}>
        {item.image && <Image source={item.image} style={styles.image} />}
        <Text style={styles.title}>{item.title}</Text>
        {item.key === 'three' && b}
        <Text style={styles.text}>{item.text}</Text>
      </View>
    );
  };

  const _onDone = () => {
    //console.log(props)
    props.navigation.navigate('Login');
  };

  const [state, setState] = useState({
    open: false,
  });

  const { open } = state;

  const backgroundColor =
    settings.item.colorScheme === 'dark'
      ? ColorsDarkMode.backgroundPrimary
      : Colors.backgroundPrimary;

  const handle = () => {
    return (
      <View
        style={{
          paddingHorizontal: 16,
          paddingVertical: 5,
          backgroundColor,
        }}>
        <View
          style={[
            styles.indicator,
            {
              backgroundColor:
                settings.item.colorScheme === 'light'
                  ? 'rgba(0, 0, 0, 0.25)'
                  : 'rgba(255, 255, 255, 0.25)',
            },
          ]}
        />
      </View>
    );
  };

  return (
    <>
      <AppIntroSlider
        renderItem={_renderItem}
        data={slides}
        onDone={_onDone}
        nextLabel={t('next')}
        doneLabel={t('done')}
      />
    </>
  );
};

export default withModalProvider(IndexInstallationContainer);

Regular views in bottom sheet become unresponsive to gestures after list has been scrolled

Bug

Apologies for the rapid bug reports, loving the library!

When using a BottomSheetFlatList sandwiched between two views, the two view becomes unresponsive to gestures after the BottomSheetFlatList has been scrolled down and then up.

I've attached a gif to demonstrate, it shows 3 scenarios:

  1. Open bottom sheet, gesture down from blue area (works fine)
  2. Open bottom sheet, scroll list down, gesture down from blue area (works fine)
  3. Open bottom sheet, scroll list down, scroll list up slightly, gesture down from blue area (no movement)

As you can see, anything outside of the BottomSheetFlatList becomes unresponsive to gestures.
ezgif com-video-to-gif (2)

Environment info

Library Version
@gorhom/bottom-sheet 1.1.1
react-native 0.63.2
react-native-reanimated 1.12.0
react-native-gesture-handler 1.7.0

Steps To Reproduce

  1. Open bottom sheet
  2. Scroll down bottom sheet list
  3. Scroll up bottom sheet list (not to top)
  4. Attempt to swipe down to close bottom sheet

Reproducible sample code

import { AppRegistry, LogBox } from 'react-native';
import BottomSheet, { BottomSheetFlatList } from '@gorhom/bottom-sheet';

const App = function App() {
    return (
        <BottomSheet snapPoints={[100, 600]} handleComponent={() => null}>
            <View style={{ height: 100, backgroundColor: 'blue' }} />
            <BottomSheetFlatList
                contentContainerStyle={{ flexGrow: 1, backgroundColor: '#fff' }}
                data={[0, 1, 2, 3, 4, 5, 6, 7, 8]}
                renderItem={() => (
                    <View style={{ backgroundColor: 'red', height: 100, marginBottom: 20 }} />
                )}
            />
            <View style={{ height: 100, backgroundColor: 'green' }} />
        </BottomSheet>
    );
};

AppRegistry.registerComponent('App', () => App);

focusHook causes list to become unscrollable

Bug

There is an issue when using the focusHook prop on a BottomSheetFlatList. Opening the bottom sheet works fine and the list is scrollable, however when the BottomSheet component re-renders it locks the scrolling of the list.

Some investigation reveals that the re-rendering of BottomSheet causes ContentWrapper to also re-render, re-setting maxDeltaY.
I can see that without focusHook, the function refreshUIElements is usually called which sets the maxDeltaY to 0 and enables scrolling. For some reason this is not happening with focusHook.

Environment info

Both iOS and Android

Library Version
@gorhom/bottom-sheet 1.4.1
react-native 0.63.3
react-native-reanimated 2.0.0-alpha.7
react-native-gesture-handler 1.8.0

Steps To Reproduce

  1. Load the example
  2. Open the bottom sheet and scroll the list
  3. Tap on a list item which triggers a re-render of the parent component.
  4. Attempt to scroll the list

Reproducible sample code

import React from 'react';
import BottomSheet, { BottomSheetFlatList, TouchableOpacity } from '@gorhom/bottom-sheet';
import { useFocusEffect, NavigationContainer } from '@react-navigation/native';

import { View, AppRegistry, LogBox } from 'react-native';
import { useState } from 'react';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

function Test() {
    const [, reRender] = useState(-1);

    return (
        <SafeAreaProvider>
            <BottomSheet snapPoints={[100, 600]}>
                <NavigationContainer>
                    <Stack.Navigator>
                        <Stack.Screen name="List">
                            {(props) => (
                                <BottomSheetFlatList
                                    focusHook={useFocusEffect}
                                    data={[...new Array(20)]}
                                    keyExtractor={(_, i) => i.toString()}
                                    renderItem={({ index }) => (
                                        <TouchableOpacity onPress={() => reRender(index)}>
                                            <View
                                                style={{
                                                    backgroundColor: 'red',
                                                    height: 50,
                                                    marginTop: 10
                                                }}
                                            />
                                        </TouchableOpacity>
                                    )}
                                />
                            )}
                        </Stack.Screen>
                    </Stack.Navigator>
                </NavigationContainer>
            </BottomSheet>
        </SafeAreaProvider>
    );
}

AppRegistry.registerComponent('Test', () => Test);

Thanks!

Rewrite the library in Reanimated v2

Feature Request

Why it is needed

To utilise the power of Reanimated v2, this library will need to be partially re-written.

Possible implementation

  • Re-write useTransition.ts
  • Utilise the new native measure & scrollTo

Close Keyboard in sync with dismissing BottomSheet

Feature Request

Wondering if there is a way to close the keyboard in sync with the BottomSheet being dismissed via drag. I have it working nicely when you press the close button:

  const handleDismissPress = useCallback(() => {
    Keyboard.dismiss()
    dismiss()
  }, [dismiss])

Why it is needed

Seems janky to watch the BottomSheet dismiss fully and then watch the keyboard dismiss.

Possible implementation

I poked around for a couple min to see if I could do this easily on a ListView in the lib. Should be possible.

Tried to synchronously call function {assign} from a diffrent thread

Bug

Getting the following error when trying to use this package:

Tried to synchronously call function {assign} from a diffrent thread.
Solution is:
a) if you want to synchronously execute this method, mark it as a worklet
b) if you want to execute this method on the JS thread, wrap it using runOnJS

I've tracked the error message back to node_modules/react-native-reanimated/Common/cpp/SharedItems/ShareableValue.cpp line 15. And there is a thread on the issue here: software-mansion/react-native-reanimated#1347

Environment info

Library Version
@gorhom/bottom-sheet "2.0.0-alpha.0"
react-native "0.63.3"
react-native-reanimated "^2.0.0-alpha.8"
react-native-gesture-handler "^1.8.0"

Steps To Reproduce

  1. Installed "@gorhom/bottom-sheet": "2.0.0-alpha.0", "react-native-reanimated": "^2.0.0-alpha.8" (with all changes needed for the library) and "react-native-gesture-handler": "^1.8.0"`.
  2. Replace my App.tsx with the contents of any of the example docs, such as this.
  3. Error appears on render

Describe what you expected to happen:

  1. I'd expect no error and to see the sheet

BottomSheetFlatList is scrollable only when the bottomSheet is on the top level

Bug

Environment info

Library Version
@gorhom/bottom-sheet ^1.4.1
react-native "https://github.com/expo/react-native/archive/sdk-39.0.0.tar.gz"
react-native-gesture-handler ~1.7.0

Steps To Reproduce

1.scrolling up the bottomSheet
2.scroll horizontally images
3. scroll down 50% the bottomSheet
4.scroll horizontally images -> cannot.

Describe what you expected to happen:

1.i would like to be able to scroll the images horizontally also when the bottomSheet is not on the top level.

Reproducible sample code

import { BottomSheetFlatList } from '@gorhom/bottom-sheet'
import React from 'react'
import {View, Text, TouchableOpacity, Image, StyleSheet } from 'react-native'
import { ImagesSliderProps } from './ImagesSlider.d'

const ImagesSlider: React.FC<ImagesSliderProps> = ({title, images}) => {
  
 const renderImage = (itemData:any) => {  
  return (
      <TouchableOpacity activeOpacity={0.8} onPress={()=> console.log(itemData.item)}>
        <Image style={styles.image} source={{uri:itemData.item.key}}/>
      </TouchableOpacity>
    )
  }

  return (
   <View style={{flex:1}}>
    <Text>{title}</Text>
    <BottomSheetFlatList 
            showsHorizontalScrollIndicator={true} 
            initialNumToRender={2} 
            keyExtractor={(item, index) => index.toString()} 
            horizontal={true} 
            data={images} 
            renderItem={renderImage}/>
   </View>
 )
}

const styles = StyleSheet.create({
  image: {
    marginHorizontal: 5,
    width:200,
    height:150,
    resizeMode: 'stretch'
  }
})

export default ImagesSlider;

cannotscroll
scrollable

Tests

Hey, love the project. You up for adding some tests? I could start that for you.
jest + native-testing-library + react-hooks-testing-library?

snapPoints it differs a lot between operating systems

Bug

90%
Schermata 2020-11-20 alle 22 24 05

100%

Schermata 2020-11-20 alle 22 30 53

Hi @gorhom ,

I am using your component on different devices, I tried to put snapPoints = "90%".
I noticed that it differs a lot between the two, as can be seen from the image.

I tried with higher values (100%), it seems that on android it works fine but on ios it gives problems, it goes further.

Environment info

Library Version
@gorhom/bottom-sheet 1.4.1
react-native 0.63.3
react-native-reanimated 1.13.2
react-native-gesture-handler 1.8.0

Reproducible sample code

{
          snapPoints: ['90%'],
          animationDuration: 10,
          overlayComponent: BottomSheetOverlay,
          overlayOpacity: 0.5,
          dismissOnOverlayPress: true,
        }

dragFromHandleOnly

I used react-native-raw-bottom-sheet before and it has a prop dragFromTopOnly in which the bottom-sheet can only be close (when being drag) by the handle not by the entire bottom-sheet itself. I like this library compare to that because of performance. I hope you can add this, thanks

Can't pull sheet on Android

Bug

Hi, I don't seem to be able to pull on/move the sheet on Android at all, even with a very minimal example.

On iOS, it works just fine (excuse the crude example):

iospull

But on Android, it doesn't respond to interaction at all:

androidpull

I've tried this both in the simulator and on-device, with the same results.

Environment info

Library Version
@gorhom/bottom-sheet 1.4.1
react-native 0.63.3
react-native-reanimated 1.13.1
react-native-gesture-handler 1.8.0

Steps To Reproduce

  1. Create a file and place the minimal example code in its contents
  2. Mount the MinimalExample component in your app
  3. Attempt to pull on the sheet in Android

Describe what you expected to happen:

  1. The sheet moves/behaves like iOS

Reproducible sample code

import React from 'react'
import { View, Text } from 'react-native'
import BottomSheet from '@gorhom/bottom-sheet'

const MinimalExample = () => (
  <View style={{ flex: 1, backgroundColor: 'grey' }}>
    <BottomSheet snapPoints={[50, 200]}>
      <Text>Hello, world!</Text>
    </BottomSheet>
  </View>
)

export default MinimalExample

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.