A smart and flexible bottom sheet with React Native
React Native Bottom Sheet π
The smart π, tiny π¦, and flexible π bottom sheet your app craves π
Web Preview
β¨Features
- π¦ Very tiny and lightweight
- 0οΈβ£ No dependency (yeah!, just plug and play π)
- β¨ Modal and standard (non-modal) bottom sheet support
- β¨ Smart & automatic keyboard and orientation handling for iOS & Android
- πͺ Imperative calls
- π Supports FlatList, SectionList, ScrollView & View scrolling interactions
- π Handles layout & orientation changes smartly
- π― Compatible with Expo
- π§ Flexible config
- π Supports props live update
- π Configurable animation
- π¨ Follows Material Design principles
- π Runs on the web
- β Written in TypeScript
π» Installation
npm install @devvie/bottom-sheet
or
yarn add @devvie/bottom-sheet
π± Minimal Usage
Opening and closing the bottom sheet is done imperatively, so just pass a ref
to the bottom sheet and call the open
or close
methods via the ref
instance to open and close the bottom sheet respectively.
Examples
Typescript
import React, { useRef } from 'react';
import BottomSheet, { BottomSheetMethods } from '@devvie/bottom-sheet';
import { Button } from 'react-native';
const App = () => {
const sheetRef = useRef<BottomSheetMethods>(null);
return (
<Button title="Open" onPress={() => sheetRef.current.open()} />
<BottomSheet ref={sheetRef}>
<Text>
The smart π, tiny π¦, and flexible π bottom sheet your app craves π
</Text>
</BottomSheet>
);
};
export default App;
Javascript
import React, { useRef } from 'react';
import BottomSheet, { BottomSheetMethods } from '@devvie/bottom-sheet';
import { Button } from 'react-native';
const App = () => {
const sheetRef = useRef(null);
return (
<Button title="Open" onPress={() => sheetRef.current.open()} />
<BottomSheet ref={sheetRef}>
<Text>
The smart π, tiny π¦, and flexible π bottom sheet your app craves π
</Text>
</BottomSheet>
);
};
β Warning
The bottom sheet component uses and handles pan gestures internally, so to avoid scroll/pan misbehavior with its container, DO NOT put it inside a container that supports panning e.g ScrollView
. You can always put it just next to the ScrollView
and use React Fragment
or a View
to wrap them and everything should be okay.
β Donβt do this
<ScrollView>
<BottomSheet>
...
</BottomSheet>
</ScrollView>
β Do this
<>
<ScrollView>
...
</ScrollView>
<BottomSheet>
...
</BottomSheet>
</>
π Props
The bottom sheet is highly configurable via props. All props works for both Android
and iOS
except those prefixed with android_
and ios_
, which works for only Android
and iOS
respectively.
Property | Type | Default | Description | Required |
---|---|---|---|---|
android_backdropMaskRippleColor |
string | OpaqueColorValue |
Color of the ripple effect when backdrop mask is pressed (Android Only). | No | |
android_closeOnBackPress |
boolean |
true |
Determines whether the sheet will close when the device back button is pressed (Android Only). | No |
animationType |
'slide' | 'spring' | 'fade' | ANIMATIONS |
'slide' |
Animation to use when opening and closing the bottom sheet. | No |
backdropMaskColor |
string | OpaqueColorValue |
'#00000052' |
Color of the scrim or backdrop mask. | No |
children |
ViewProps['children'] | React.FunctionComponent<{_animatedHeight: Animated.Value}> |
null |
Contents of the bottom sheet. | Yes |
closeDuration |
number |
500 |
Duration for sheet closing animation. | No |
closeOnBackdropPress |
boolean |
true |
Determines whether the bottom sheet will close when the scrim or backdrop mask is pressed. | No |
closeOnDragDown |
boolean |
true |
Determines whether the bottom sheet will close when dragged down. | No |
containerHeight |
ViewStyle['height'] |
DEVICE SCREEN HEIGHT |
Height of the bottom sheetβs overall container. | No |
customBackdropComponent |
React.FunctionComponent<{_animatedHeight: Animated.Value}> |
null |
Custom component for sheetβs scrim or backdrop mask. | No |
customBackdropPosition |
"top" | "behind" |
'behind' |
Determines the position of the custom scrim or backdrop component. 'behind' puts it behind the keyboard and `βtopββ puts it atop the keyboard. |
No |
customDragHandleComponent |
React.FC<{_animatedHeight: Animated.Value}> |
Custom drag handle component to replace the default bottom sheetβs drag handle. | No | |
customEasingFunction |
AnimationEasingFunction |
ANIMATIONS.SLIDE |
Custom easing function for driving sheetβs animation. | No |
disableBodyPanning |
boolean |
false |
Prevents the bottom sheet from being dragged/panned down on its body. | No |
disableDragHandlePanning |
boolean |
false |
Prevents the bottom sheet from being panned down by dragging its drag handle. | No |
dragHandleStyle |
ViewStyle |
Extra styles to apply to the drag handle. | No | |
height |
number | string |
'50%' |
Height of the bottom sheet when opened. Relative to containerHeight prop |
No |
hideDragHandle |
boolean |
false |
When true, hides the sheetβs drag handle. | No |
modal |
boolean |
true |
Determines whether the sheet is a modal. A modal sheet has a scrim or backdrop mask, while a standard (non-modal) sheet doesnβt. | No |
openDuration |
number |
500 |
Duration for sheet opening animation. | No |
style |
Omit<ViewStyle, 'height' | 'minHeight' | 'maxHeight' | 'transform:[{translateY}]'> |
Extra styles to apply to the bottom sheet. | No |
Examples
Flexibility is a focus for this bottom sheet, these few examples shows certain behaviors of the bottom sheet and what can be achieved by tweaking its props.
1οΈβ£ Smart response to keyboard pop ups and orientation changes (automatic behavior)
Android | iOS |
---|---|
2οΈβ£ Handles deeply nested list and scroll views interactions (automatic beavior)
Android | iOS |
---|---|
3οΈβ£ Auto adjusts layout when height
and containerHeight
props change (automatic behavior)
4οΈβ£ Extend sheet height when its content is scrolled
5οΈβ£ Use as SnackBar
6οΈβ£ Custom Drag Handle Animation Interpolation
7οΈβ£ Custom Scrim/Backdrop Mask
More Examples and code samples comign soonβ¦
Contributing
See the contributing guide to learn how to contribute to the repository and the development workflow.
License
MIT
see LICENSE
</> with π by Devvie β