React Native Magic Sheet ✨

Overview

React Native Magic Sheet Cover

A Bottom Sheet library that can be called imperatively from anywhere!

React Native Magic Sheet

Inspired by react-native-magic-modal This library aims to solve the need to declaretively add bottom sheets to our screens by providing an imperative API that can be called from anywhere in the app (even outside of components) to show a fully customizeable bottom sheet with the ability to wait for it to resolve and get a response back.

This library relies on the modal component of @gorhom/bottom-sheet and accepts the same props and children.

Therefore the setup proccess of @gorhom/bottom-sheet should be followed in order for this to work

(ex: installing gesture handler, reanimated2, and @gorhom/bottom-sheet v4)

📸 Examples

IOS Android

🛠 Installation

yarn add react-native-magic-sheet

⚙️ Usage

First, insert a MagicSheetPortal in the top of the application and make sure the app is wrapped with GestureHandlerRootView & BottomSheetModalProvider.

You can add the default props and styles of type BottomSheetProps (optional as you can override the props when calling the sheet later).

import {GestureHandlerRootView} from 'react-native-gesture-handler';
import {BottomSheetModalProvider} from '@gorhom/bottom-sheet';
import {MagicSheetPortal} from 'react-native-magic-sheet';

export default function App() {
  return (
    <OtherProviders>
        <GestureHandlerRootView style={{flex: 1}}>
            <BottomSheetModalProvider>
                <MagicSheetPortal {...defaultProps}/>  // <-- On the top of the app component hierarchy
                <AppComponents /> // The rest of the app goes here
            </BottomSheetModalProvider>
        </GestureHandlerRootView>
    </OtherProviders>
  );
}

Then, you are free to use the magicSheet as shown from anywhere you want.

// This will hide the sheet, resolve the promise with the passed object Return user ); const handlePickUser = async () => { // We can call it with or without props, depending on the requirements. const result = await magicSheet.show(PickerSheet); //OR (with props) const result = await magicSheet.show(() => ); console.log(result) // will show {userName: "Rod", id:1}, or undefined if sheet is dismissed }; export const Screen = () => { return ( Show sheet ); };">
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { magicSheet } from 'react-native-magic-sheet';

const PickerSheet = (someProps) => (
  <View>
    <TouchableOpacity 
    onPress={() => {
        magicSheet.hide({userName: "Rod", id:1})
    }}> // This will hide the sheet, resolve the promise with the passed object
      <Text>Return user</Text>
    </TouchableOpacity>
  </View>
);

const handlePickUser = async () => {
  // We can call it with or without props, depending on the requirements.
  const result = await magicSheet.show(PickerSheet);

  //OR (with props)
  const result = await magicSheet.show(() => <PickerSheet {...someProps}/>);

  console.log(result) 
  // will show {userName: "Rod", id:1}, or undefined if sheet is dismissed
};

export const Screen = () => {
  return (
    <View>
      <TouchableOpacity onPress={handlePickUser}>
        <Text>Show sheet</Text>
      </TouchableOpacity>
    </View>
  );
};

Alternatively, if we don't care about waiting the resolved value of the promise we can just trigger some action instead.

Return user ); export const Screen = () => { const [user, setUser] = useState(); const handlePickUser = useCallback( () => { magicSheet.show( () => {setUser(value)}}/> ) } ,[]) return ( Show sheet ); };">
import React from 'react';
import {View, Text, TouchableOpacity} from 'react-native';
import {magicSheet} from 'react-native-magic-sheet';

const PickerSheet = (props) => (
  <View>
    <TouchableOpacity 
      onPress={() => {
        magicSheet.hide();
        props.onSelect({userName: "Rod", id:1})
      }}> 
      <Text>Return user</Text>
    </TouchableOpacity>
  </View>
);

export const Screen = () => {
  const [user, setUser] = useState();

  const handlePickUser = useCallback(
    () => {
      magicSheet.show(
        () => <PickerSheet onSelect={(value)=>{setUser(value)}}/>
      )
    }
  ,[])

  return (
    <View>
      <TouchableOpacity 
        onPress={handlePickUser}>
        <Text>Show sheet</Text>
      </TouchableOpacity>
    </View>
  );
};

magicSheet.show( ) can take another optional argument of type BottomSheetProps if we need to override the default props and style of the bottom sheet container

Example:

magicSheet.show(
    () => <SomeComponent {...someProps}>,
    {backgroundStyle: styles.bottomSheetContainer}
)

😬 Notes

Inner components

It's recommended to use the components provided by @gorhom/bottom-sheet inside of the bottom sheet as those components are made to adapt to the bottom sheet behavior, especially scrollables and text inputs.

Keyboard in android

If you face issues with android keyboard the easiest approach would be to replace android:windowSoftInputMode="adjustResize" with android:windowSoftInputMode="adjustPan" in the manifest file to mimic the behavior of ios, or use whatever keyboard handling solution you're comfortable with.

This limitation is not specific to this library.

👨‍🏫 Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

⚖️ License

MIT

You might also like...
Use the iOS and Android native Twitter and Facebook share popup with React Native https://github.com/doefler/react-native-social-share
Use the iOS and Android native Twitter and Facebook share popup with React Native https://github.com/doefler/react-native-social-share

React Native Social Share Use the built-in share view from iOS and Android to let the user share on Facebook and Twitter. It will use the user's exist

SVG library for React Native, React Native Web, and plain React web projects.
SVG library for React Native, React Native Web, and plain React web projects.

react-native-svg react-native-svg provides SVG support to React Native on iOS and Android, and a compatibility layer for the web. Check out the demo F

PicPay Application using React Native, Expo, @react-navigation/native, @react-navigation/bottom-tabs, expo-linear-gradient and styled-components
PicPay Application using React Native, Expo, @react-navigation/native, @react-navigation/bottom-tabs, expo-linear-gradient and styled-components

React Native - PicPay Aplicação PicPay usando React Native, Expo, @react-navigation/native, @react-navigation/bottom-tabs, expo-linear-gradient e styl

react-native-splashscreen ★358 - A splash screen for react-native
react-native-splashscreen ★358 - A splash screen for react-native

React Native SplashScreen (remobile) A splashscreen for react-native, hide when application loaded Installation npm install @remobile/react-native-spl

Beautifully crafted off canvas menu components for react native applications. Built on top of react-native's Animated library.
Beautifully crafted off canvas menu components for react native applications. Built on top of react-native's Animated library.

react-native-off-canvas-menu Beautifully crafted off canvas menu components for react native applications. Features - Gesture Support Orientation Comp

A QR Code generator for React Native based on react-native-svg and node-qrcode.
A QR Code generator for React Native based on react-native-svg and node-qrcode.

react-native-qrcode-svg A QR Code generator for React Native based on react-native-svg and javascript-qrcode. Discussion: https://discord.gg/RvFM97v F

react-native-egg make your react native app infinitely more fun !!

react-native-egg react-native-egg make your react native app infinitely more fun !! Implementation simple gestures detection achieve trigger easter eg

React Native Higher Order Component that adds advanced caching functionality to the react native Image component.

React Native Image Cache HOC React Native Higher Order Component that adds advanced caching functionality to the react native Image component. Feature

react-native-wheel-picker ★190 - React native cross platform picker.
react-native-wheel-picker ★190 - React native cross platform picker.

react-native-wheel-picker Introduction Cross platform Picker component based on React-native. Since picker is originally supported by ios while Androi

Releases(v0.2.4)
react-native-app-intro is a react native component implementing a parallax effect welcome page using base on react-native-swiper , similar to the one found in Google's app like Sheet, Drive, Docs...

react-native-app-intro react-native-app-intro is a react native component implementing a parallax effect welcome page using base on react-native-swipe

Shinix 62 Jul 15, 2022
React Native: Native Bottom Action Sheet

ReactNative: Native Bottom Action Sheet (Android/iOS) If this project has helped you out, please support us with a star ?? A simple library that crea

Pranav Raj Singh Chauhan 609 Sep 27, 2022
A performant customizable bottom sheet component made on top of wix react-native-navigation library.

?? React Native Navigation Bottom Sheet Extension A performant customizable bottom sheet component made on top of wix react-native-navigation library.

CursedWizard 45 Sep 21, 2022
React Native Actions Sheet Picker

React Native Actions Sheet Picker A React Native component that provides a filterable select dropdown/picker. Preview Installation Guide yarn add reac

Burak Alp 63 Sep 22, 2022
A image magic module for react native

react-native-imagewand React native image wand view for android. Enabling you to do instagram like effects to images Installation npm i --save react-n

Shao Hang, Weng 14 Mar 21, 2019
Bottom sheet navigator for React Navigation

@th3rdwave/react-navigation-bottom-sheet Bottom sheet navigator for React Navigation. Integrates @gorhom/bottom-sheet with React Navigation. Installat

Th3rdwave 275 Sep 28, 2022
React-magic-scroll - A react library for adding some effect you want when scroll

react-magic-scroll A react library for adding some effect you want when scroll.

diandian 3 May 13, 2022
A marquee label for react-native(if you use js pure marquee, use remobile/react-native-marquee[ https://github.com/remobile/react-native-marquee ])

React Native MarqueeLabel (remobile) A marquee label for react-native if you use js pure marquee, use remobile/react-native-marquee[ https://github.co

YunJiang.Fang 114 Jul 18, 2022
react-native-swiper2 ★86 - Swiper component for React Native. Supersede react-native-swiper

react-native-swiper2 react-native-swiper is now active again, so swiper2 will stop maintaining. Changelogs [v2.0.7] correct onPageChange index. https:

Sunny Luo 84 Feb 23, 2022
A React Native module that allows you to crop photos, built with react native Animated api and react-native-gesture-handler.

react-native-image-cropview A React Native module that allows you to crop photos, built with react native Animated api and react-native-gesture-handle

Cristian Tomescu 12 Aug 30, 2022