Skip to content

Commit

Permalink
feat: introduce bottom sheet modal 🔥 (#37)
Browse files Browse the repository at this point in the history
* chore: update example dependencies

* chore: install nanoid

* chore: added modal/provider implementation

* chore: updated examples

* chore: updated example screens titles

* chore: remove default handle shadow

* chore: added dismissOnScrollDown feature

* chore: reset app entry screen

* chore: stablize animated values and nodes

* chore: updated scrollables style type

* chore: added pointerEvents to overlay

* chore: added allowTouchThroughOverlay to modal

* fix: patch react-native on ios 14

* chore: updated examples!

* docs: updated readme and add modal document

* docs: updated readme and add modal document

* chore: updated preview image

* chore: updated map example

* chore: renamed stack modals example
  • Loading branch information
gorhom authored Sep 30, 2020
1 parent d70c08d commit 49064d9
Show file tree
Hide file tree
Showing 77 changed files with 2,386 additions and 548 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ A performant interactive bottom sheet with fully configurable options 🚀
- [Version 1](#version-v1)
- [Version 2](#version-v2)
3. [Usage](#usage)
- 🌟 [Bottom Sheet Modal](./docs/modal.md)
- [Custom Handle](./docs/custom-handle.md)
- [React Navigation Integration](./docs/react-navigation.md)
- [Touchables](./docs/touchables.md)
Expand All @@ -38,6 +39,7 @@ A performant interactive bottom sheet with fully configurable options 🚀

## Features

- 🌟 Modal presentation view, [Bottom Sheet Modal](./docs/modal.md).
- Smooth interactions & snapping animations.
- Support `FlatList`, `SectionList`, `ScrollView` & `View` scrolling interactions.
- Support `React Navigation` Integration.
Expand All @@ -62,7 +64,7 @@ npm install @gorhom/bottom-sheet
> ⚠️ You need to install [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated) & [react-native-gesture-handler](https://github.com/software-mansion/react-native-gesture-handler) and follow their installation instructions.

### Version v2
### Version v2 ( Alpha )

[Link to version 2 branch](https://github.com/gorhom/react-native-bottom-sheet/tree/feature/rewrite-in-reanimated-v2)

Expand Down Expand Up @@ -193,7 +195,7 @@ Callback when sheet position changed to a provided point.

A scrollable node or normal view.

> `required:` YES | `type:` React.ReactNode[] | React.ReactNode
> `required:` YES | `type:` () => React.ReactNode | React.ReactNode[] | React.ReactNode
## Methods

Expand Down Expand Up @@ -240,8 +242,9 @@ This library provides a pre-integrated views that utilise an internal functional

## To Do

- [ ] Add tablets support.
- [x] Add Reanimated v2 support.
- [ ] Add tablets support.
- [ ] Add Bounce support.

## FAQ

Expand Down
146 changes: 146 additions & 0 deletions docs/modal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Bottom Sheet Modal

With the release of the library, support for stack sheet modals were something planned ahead to provide the a native feel & and experience to users.

The implementation of this feature was inspired by Apple Maps sheet modals ❤️, [check out the Apple Map sheet modals clone](../example/src/screens/advanced/MapExample.tsx).

## Features

- Smooth interaction and mounting animation.
- Support stack sheet modals.

## Hooks

### `useBottomSheetModal`

This hook to provides the bottom sheet modal:

#### `present`

Present a scrollable view that it will be wrapped with Bottom Sheet, and provide the bottom sheet view & modal props in the configs parameter.

> `type:` (content: ReactNode, configs: [BottomSheetModalConfigs](#bottom-sheet-modal-configs)) => void
#### `dismiss`

Dismiss the presented sheet modal.

> `type:` () => void
#### `dismissAll`

Dismiss all presented sheet modals.

> `type:` () => void
#### `snapTo`

Snap to one of the provided points from `snapPoints`.

> `type:` (index: number) => void
#### `expand`

Snap to the maximum provided point from `snapPoints`.

> `type:` () => void
#### `collapse`

Snap to the minimum provided point from `snapPoints`.

> `type:` () => void
## Bottom Sheet Modal Configs

This will also include [BottomSheetProps](../README.md#props).

#### `allowTouchThroughOverlay`

Allow touch through overlay component.

> `required:` NO | `type:` boolean | `default:` false
#### `overlayComponent`

Overlay component.

> `required:` NO | `type:` React.FC<[BottomSheetOverlayProps](../src/components/overlay/types.d.ts)>
#### `overlayOpacity`

Overlay opacity.

> `required:` NO | `type:` number | `default:` 0.5
#### `dismissOnOverlayPress`

Dismiss modal when press on overlay.

> `required:` NO | `type:` boolean | `default:` true
#### `dismissOnScrollDown`

Dismiss modal when scroll down.

> `required:` NO | `type:` boolean | `default:` true
## Example

```tsx
import React, { useCallback, useMemo, useRef } from 'react';
import { View, StyleSheet, Button } from 'react-native';
import {
BottomSheetModalProvider,
useBottomSheetModal,
} from '@gorhom/bottom-sheet';

const App = () => {
// hooks
const { present, dismiss } = useBottomSheetModal();

// variables
const snapPoints = useMemo(() => ['25%', '50%', '90%'], []);

// callbacks
const handleSheetChanges = useCallback((index: number) => {
console.log('handleSheetChanges', index);
}, []);
const handlePresentPress = useCallback(() => {
present(
{
/* INSERT A SCROLLABLE HERE */
},
{
snapPoints: snapPoints,
onChange: handleSheetChanges,
}
);
}, [present, snapPoints, handleSheetChanges]);

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

// renders
return (
<View style={styles.container}>
<Button onPress={handlePresentPress} title="Present Modal" />
<Button onPress={handleDismissPress} title="Dismiss Modal" />
</View>
);
};

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

export default () => (
<BottomSheetModalProvider>
<App />
</BottomSheetModalProvider>
);
```
4 changes: 4 additions & 0 deletions example/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import 'react-native-gesture-handler';
import { AppRegistry } from 'react-native';
import { enableScreens } from 'react-native-screens';
import App from './src/App';
import { name as appName } from './app.json';

console.disableYellowBox = true;
enableScreens(true);

AppRegistry.registerComponent(appName, () => App);
12 changes: 6 additions & 6 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,11 @@ PODS:
- ReactCommon/callinvoker (= 0.62.2)
- RNCMaskedView (0.1.10):
- React
- RNGestureHandler (1.7.0):
- RNGestureHandler (1.8.0):
- React
- RNReanimated (1.12.0):
- RNReanimated (1.13.1):
- React
- RNScreens (2.10.1):
- RNScreens (2.11.0):
- React
- Yoga (1.14.0)
- YogaKit (1.18.1):
Expand Down Expand Up @@ -473,9 +473,9 @@ SPEC CHECKSUMS:
React-RCTVibration: 4356114dbcba4ce66991096e51a66e61eda51256
ReactCommon: ed4e11d27609d571e7eee8b65548efc191116eb3
RNCMaskedView: 5a8ec07677aa885546a0d98da336457e2bea557f
RNGestureHandler: b6b359bb800ae399a9c8b27032bdbf7c18f08a08
RNReanimated: 9c475f9b272232351d94a1a781e8b7580bac1ff4
RNScreens: b748efec66e095134c7166ca333b628cd7e6f3e2
RNGestureHandler: 7a5833d0f788dbd107fbb913e09aa0c1ff333c39
RNReanimated: dd8c286ab5dd4ba36d3a7fef8bff7e08711b5476
RNScreens: 0e91da98ab26d5d04c7b59a9b6bd694124caf88c
Yoga: 3ebccbdd559724312790e7742142d062476b698e
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a

Expand Down
10 changes: 6 additions & 4 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"start": "react-native start"
},
"dependencies": {
"@gorhom/showcase-template": "^0.3.1",
"@gorhom/showcase-template": "^1.0.2",
"@react-native-community/blur": "^3.6.0",
"@react-native-community/masked-view": "0.1.10",
"@react-navigation/native": "^5.7.3",
Expand All @@ -18,12 +18,12 @@
"lodash.isequal": "^4.5.0",
"react": "16.11.0",
"react-native": "0.62.2",
"react-native-gesture-handler": "^1.7.0",
"react-native-gesture-handler": "^1.8.0",
"react-native-maps": "^0.27.1",
"react-native-reanimated": "^1.12.0",
"react-native-reanimated": "^1.13.1",
"react-native-redash": "^14.2.3",
"react-native-safe-area-context": "0.7.3",
"react-native-screens": "^2.9.0"
"react-native-screens": "^2.11.0"
},
"devDependencies": {
"@babel/core": "^7.9.6",
Expand All @@ -32,6 +32,8 @@
"@types/react": "^16.9.23",
"@types/react-native": "^0.61.17",
"metro-react-native-babel-preset": "^0.59.0",
"nanoid": "^3.1.12",
"patch-package": "^6.2.2",
"typescript": "^3.9.7"
}
}
21 changes: 21 additions & 0 deletions example/patches/react-native+0.62.2.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
diff --git a/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m b/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m
index 21f1a06..2444713 100644
--- a/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m
+++ b/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m
@@ -272,6 +272,9 @@ - (void)displayDidRefresh:(CADisplayLink *)displayLink

- (void)displayLayer:(CALayer *)layer
{
+ if (!_currentFrame) {
+ _currentFrame = self.image;
+ }
if (_currentFrame) {
layer.contentsScale = self.animatedImageScale;
layer.contents = (__bridge id)_currentFrame.CGImage;
diff --git a/node_modules/react-native/scripts/.packager.env b/node_modules/react-native/scripts/.packager.env
new file mode 100644
index 0000000..361f5fb
--- /dev/null
+++ b/node_modules/react-native/scripts/.packager.env
@@ -0,0 +1 @@
+export RCT_METRO_PORT=8081
Loading

0 comments on commit 49064d9

Please sign in to comment.