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

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...

A generative engine that takes various png layers on a sprite sheet format, combines them and then converts them into a .gif file

A generative engine that takes various png layers on a sprite sheet format, combines them and then converts them into a .gif file

Welcome to the Generative Animated Engine v3.0.1 🐤 [8 minute read] This repo used to be called jalagar/Generative_Gif_Engine but because it now suppo

May 24, 2022

375 DSA Tracker helps you build your confidence in solving any coding related question and helps you prepare for your placements. It is your personal web-based progress tracker based on 375 DSA Sheet by Aman Dhattarwal & Shradha Didi

375 DSA Tracker helps you build your confidence in solving any coding related question and helps you prepare for your placements. It is your personal web-based progress tracker based on 375 DSA Sheet by Aman Dhattarwal & Shradha Didi

375-DSA Tracker 👨‍💻 Me and my friend Abhilash Jena made a 375 DSA Tracker website based on 375 DSA Sheet by Aman Dhattarwal & Shradha Didi which hel

Nov 11, 2022

A JSON/ICS represenation of the Hack Club Assemble Run of Show Google Sheet

Assemble Calendar Assemble's Run of Show was planned on a Google Sheet. It's amazing for large-scale planning and visualizing everyone's schedules. Ho

Sep 25, 2022

A module for modifying sheet rolling functions on Foundry VTT Character sheets for D&D 5th Edition.

A module for modifying sheet rolling functions on Foundry VTT Character sheets for D&D 5th Edition.

Ready Set Roll for 5e - FoundryVTT Module Ready Set Roll is a Foundry VTT module that accelerates the built in rolling system of the Foundry DnD5e sys

Dec 12, 2022

npm i solid-sheet

Usage Those templates dependencies are maintained via pnpm via pnpm up -Lri. This is the reason you see a pnpm-lock.yaml. That being said, any package

Dec 22, 2022

JavaScript micro-library: pass in an element and a callback and this will trigger when you click anywhere other than the element

Add a click listener to fire a callback for everywhere on the window except your chosen element. Installation run npm install @lukeboyle/when-clicked-

May 13, 2021

Logs the output, time, arguments, and stacktrace of any function when it's called in a gorgeous way.

Function.prototype.log Logs the output, time, arguments, and stacktrace of any function when it's called. How to use: Like this: function yourFunction

Apr 9, 2022

An NODE Module For Getting Data From Discord API Called Discord Info

An NODE Module For Getting Data From Discord API Called Discord Info

An NODE Module For Getting Data From Discord API Called Discord Info

Jun 7, 2022

👕 The project is an E-Commerce called DevShop that simulates a sales site which has men's and women's clothing, jewelry and electronics.

👕 The project is an E-Commerce called DevShop that simulates a sales site which has men's and women's clothing, jewelry and electronics.

DEVSHOP • E-COMMERCE O projeto é um E-Commerce chamado DevShop que simula um site de vendas a qual possui roupas masculinas, femininas, joalherias e e

Sep 19, 2022
Releases(v0.2.4)
A native, pure and exquisite web components library which can be used anywhere.

What Is This ? This is a project on pure web components merely using native HTML、CSS and JavaScript technologies. It has features below: based on web

PARANOIA 14 Nov 16, 2022
A web applicaton called 'MOVTIME' where you can come to stream movies by consuming the TMDB movie API

End result Click here : https://movtime-movie-app.netlify.app/ Figma design File Click here: https://www.figma.com/file/4IbpmTU6jtpRKdpbFmt4i8/Web-Des

Eniola Odunmbaku 12 Nov 11, 2022
A full stack mern application called "memories" where users can post interesting events occurring in their life

Memories App ?? ?? ?? Live Demo ?? ?? ?? Full Stack "R"ERN Application - from start to finish. The App is called "Memories" and it is a simple social

Phenom 7 Sep 24, 2022
Visual scraper interface, exports to puppeteer script which you can run anywhere.

Jawa - Visual Scraper Visual scraper interface, exports to puppeteer script which you can run anywhere. You can try it out here https://jawa.kickass.c

Ante Barić 4 Nov 16, 2022
Sheetzapper imports your account value accross Zapper.fi supported wallets and dapps into a Google Sheet

Overview Sheetzapper imports your account value accross Zapper.fi supported wallets and dapps into a Google Sheet. This allows you to chart your net w

null 4 Nov 27, 2022
💰 Frontend for a Google Sheet I use to track my poker sessions.

Poker Tracker A frontend for a Google Sheet that I use to track my poker sessions. To better understand how React works under the hood, I built my own

Maros Hluska 2 Apr 30, 2022
This project is about a quiz website backend with google sheet.

This project is about a quiz website backend with google sheet. In this project we will fetch quiz data from google sheet to our quiz website, which is responsive & dynamic. Basically we use google sheet as our quiz database.This project is only possible for @Lsvekis .

Subhranshu Choudhury 2 Mar 28, 2022
Dynamic Striver's CP sheet

Dynamic CP Sheet Inspired by the dynamic a2oj ladder, I decided to make a similar thing for one of the best collections of CP problems. This is the dy

Sahil Saha 15 Jul 1, 2022
A generative engine that takes various png layers on a sprite sheet format, combines them and then converts them into a .gif file

Welcome to the Generative GIF Engine v2.0.4 ?? [8 minute read] This python and node app generates layered-based gifs to create NFT gif art! It is fast

Jalagar 112 Jan 2, 2023