UNPKG

react-morphing-modal

Version:

React morphing modal! The easiest way to be fancy!

552 lines (428 loc) 16.6 kB
# React-Morphing-Modal ![Travis (.org)](https://img.shields.io/travis/fkhadra/react-morphing-modal.svg?label=%F0%9F%9A%A7Build&style=for-the-badge) ![npm](https://img.shields.io/npm/dm/react-morphing-modal.svg?label=%E2%8F%ACdownloads&style=for-the-badge) ![npm](https://img.shields.io/npm/v/react-morphing-modal.svg?style=for-the-badge) ![NPM](https://img.shields.io/npm/l/react-morphing-modal.svg?label=%F0%9F%93%9Clicense&style=for-the-badge) ![Coveralls github](https://img.shields.io/coveralls/github/fkhadra/react-morphing-modal.svg?label=%E2%9B%B1coverage&style=for-the-badge) ![React Morphing Modal](https://user-images.githubusercontent.com/5574267/60773620-6bafbb80-a108-11e9-8644-fb6002ab6ffe.gif 'React Morphing Modal') - [React-Morphing-Modal](#React-Morphing-Modal) - [Demo](#Demo) - [Installation](#Installation) - [Features](#Features) - [Usage](#Usage) - [Basic example](#Basic-example) - [With a component](#With-a-component) - [Simple case](#Simple-case) - [Real app use case](#Real-app-use-case) - [Use different trigger for the same modal](#Use-different-trigger-for-the-same-modal) - [Attribute an id to the trigger](#Attribute-an-id-to-the-trigger) - [Define onOpen and onClose callback](#Define-onOpen-and-onClose-callback) - [Gloabaly](#Gloabaly) - [Per trigger](#Per-trigger) - [Define background](#Define-background) - [Gloabaly](#Gloabaly-1) - [Per trigger](#Per-trigger-1) - [Use another event to trigger the modal](#Use-another-event-to-trigger-the-modal) - [Gloabaly](#Gloabaly-2) - [Per trigger](#Per-trigger-2) - [Hide the close button](#Hide-the-close-button) - [Remove body padding](#Remove-body-padding) - [Api](#Api) - [useModal](#useModal) - [HookOptions](#HookOptions) - [open](#open) - [close](#close) - [activeModal](#activeModal) - [modalProps](#modalProps) - [getTriggerProps](#getTriggerProps) - [Modal Component](#Modal-Component) - [Browser Support](#Browser-Support) - [Release Notes](#Release-Notes) - [Contribute](#Contribute) - [License](#License) ## Demo [Demo time](https://fkhadra.github.io/react-morphing-modal/) ## Installation ``` $ npm install --save react-morphing-modal //or $ yarn add react-morphing-modal ``` ## Features - Easy to setup for real, you can make it work in less than 10sec! 🚀 - Super easy to customize 👌 - Fancy 😎 ## Usage > The library expose 2 ways to display the modal: `getTriggerProps` and `open`. For the basic use case `getTriggerProps` is fine. But for most of the cases > using `open` is the way to go. Please look at the api for more details. ### Basic example ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; function App() { const { modalProps, getTriggerProps } = useModal(); return ( <div> <button {...getTriggerProps()}>Show modal</button> <Modal {...modalProps}>Hello World</Modal> </div> ); } ``` ### With a component #### Simple case If you just want to open the modal you can stick with `getTriggerProps`. ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; const Button = props => ( <button {...props.getTriggerProps()}>Show modal</button> ); function App() { const { modalProps, getTriggerProps } = useModal(); return ( <div> <Button getTriggerProps={getTriggerProps} /> <Modal {...modalProps}>Hello World</Modal> </div> ); } ``` #### Real app use case Most of the time you need to perform different task when a user click a button like calling an api. In that case use the `open` method as follow. ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; const Button = ({ openModal }) => { const btnRef = useRef(null); function handleClick() { // do some complicated stuff openModal(btnRef); } return ( <button ref={btnRef} onClick={handleClick}> Show modal </button> ); }; function App() { const { modalProps, open } = useModal(); return ( <div> <Button openModal={open} /> <Modal {...modalProps}>Hello World</Modal> </div> ); } ``` ### Use different trigger for the same modal ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; function App() { const { modalProps, getTriggerProps, activeModal, open } = useModal(); const triggerRef = useRef(null); const handleTrigger3 = () => open(triggerRef); return ( <div> <button {...getTriggerProps()}>Trigger 1</button> <button {...getTriggerProps()}>Trigger 2</button> <button ref={triggerRef} onClick={handleTrigger3}> Trigger 3 </button> <Modal {...modalProps}>Hello World</Modal> </div> ); } ``` ### Attribute an id to the trigger ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; function App() { const { modalProps, getTriggerProps, activeModal } = useModal(); return ( <div> <button {...getTriggerProps('trigger1')}>Trigger 1</button> <button {...getTriggerProps('trigger2')}>Trigger 2</button> {/* You can also pass an object */} <button {...getTriggerProps({ id: 'trigger3' })}>Trigger 3</button> <span>{activeModal}</span> <Modal {...modalProps}>Hello World</Modal> </div> ); } ``` ### Define onOpen and onClose callback #### Gloabaly ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; function App() { const { modalProps, getTriggerProps, activeModal } = useModal({ onOpen() { console.log('onOpen'); }, onClose() { console.log('onClose'); }, }); return ( <div> <button {...getTriggerProps()}>Trigger</button> <Modal {...modalProps}>Hello World</Modal> </div> ); } ``` #### Per trigger ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; function App() { const { modalProps, getTriggerProps, activeModal } = useModal(); return ( <div> <button {...getTriggerProps({ onOpen: () => console.log('open'), onClose: () => console.log('close'), })} > Trigger </button> <Modal {...modalProps}>Hello World</Modal> </div> ); } ``` ### Define background By default, the modal background is the same as the trigger one. However, you are free to define yours. #### Gloabaly ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; function App() { const { modalProps, getTriggerProps, activeModal } = useModal({ background: '#666', }); return ( <div> <button {...getTriggerProps()}>Trigger</button> <Modal {...modalProps}>Hello World</Modal> </div> ); } ``` #### Per trigger ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; function App() { const { modalProps, getTriggerProps, activeModal } = useModal(); return ( <div> <button {...getTriggerProps({ background: '#666', })} > Trigger </button> <Modal {...modalProps}>Hello World</Modal> </div> ); } ``` ### Use another event to trigger the modal By default, the `onClick` event is used on the trigger. #### Gloabaly ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; function App() { const { modalProps, getTriggerProps, activeModal } = useModal({ event: 'onDoubleClick', }); return ( <div> <button {...getTriggerProps()}>Trigger</button> <Modal {...modalProps}>Hello World</Modal> </div> ); } ``` #### Per trigger ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; function App() { const { modalProps, getTriggerProps, activeModal } = useModal(); return ( <div> <button {...getTriggerProps({ event: 'onDoubleClick', })} > Trigger </button> <Modal {...modalProps}>Hello World</Modal> </div> ); } ``` ### Hide the close button ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; function App() { const { modalProps, getTriggerProps, activeModal } = useModal(); return ( <div> <button {...getTriggerProps()}>Trigger</button> <Modal {...modalProps} closeButton={false}> Hello World </Modal> </div> ); } ``` ### Remove body padding ```javascript import React from 'react'; import { useModal, Modal } from 'react-morphing-modal'; import 'react-morphing-modal/dist/ReactMorphingModal.css'; function App() { const { modalProps, getTriggerProps, activeModal } = useModal(); return ( <div> <button {...getTriggerProps()}>Trigger</button> <Modal {...modalProps} padding={false}> Hello World </Modal> </div> ); } ``` ## Api ### useModal #### HookOptions ```js import { useModal } from 'react-morphing-modal'; const { open, close, activeModal, modalProps, getTriggerProps } = useModal({ event: 'onClick', onOpen: () => console.log('will open'), onClose: () => console.log('will close'), background: 'purple', }); ``` | Props | Type | Default | Description | | ---------- | -------- | ------- | --------------------------------------------------------- | | event | string | onClick | Any valid react dom event: onClick, onDoubleClick, etc... | | onOpen | function | - | A function to call when the modal will open | | onClose | function | - | A function to call when the modal will close | | background | string | - | Any valid css background: #fffff, rgb(1,1,1), etc | #### open `open` have 2 signatures ```js import { useModal } from 'react-morphing-modal'; const { open } = useModal(); // pass a ref to your trigger const myRef = React.useRef(null); //somewhere in your app <MyComponent ref={myRef} />; open(myRef, 'modalId'); open(myRef, { id: 'modalId', onOpen: () => console.log('will open'), onClose: () => console.log('will close'), background: 'purple', }); ``` | Props | Type | Default | Description | | ---------- | ---------------------------------- | ------- | -------------------------------------------------------- | | id | string \| number \| symbol \| null | - | Specify a modal id. It will be assigned to `activeModal` | | onOpen | function | - | A function to call when the modal will open | | onClose | function | - | A function to call when the modal will close | | background | string | - | Any valid css background: #fffff, rgb(1,1,1), etc | #### close `close` does not require any options. ```js import { useModal } from 'react-morphing-modal'; const { close } = useModal(); close(); ``` #### activeModal `activeModal` hold the displayed modalId. `activeModal` is set to `null` if not id has been used. ```js import { useModal } from 'react-morphing-modal'; const { open, activeModal } = useModal(); open(triggerRef, 'modalId'); console, log(activeModal); // print modalId ``` #### modalProps `modalProps` hold the props that must be passed to the Modal component. ```js import { useModal, Modal } from 'react-morphing-modal'; const { modalProps } = useModal(); <Modal {...modalProps} />; ``` #### getTriggerProps `getTriggerProps` is a convenient method for the simple use case. Under the hood a ref is created and bound to `open`. `getTriggerProps` has also 2 signatures. ```js import { useModal } from 'react-morphing-modal'; const { getTriggerProps } = useModal(); <button {...trigger('modalId')}>trigger</button>; <button {...trigger({ id: 'modalId', event: 'onDoubleClcik' onOpen: () => console.log('will open'), onClose: () => console.log('will close'), background: 'purple' })}>trigger</button> ``` | Props | Type | Default | Description | | ---------- | ---------------------------------- | ------- | --------------------------------------------------------- | | id | string \| number \| symbol \| null | - | Specify a modal id. It will be assigned to `activeModal` | | event | string | onClick | Any valid react dom event: onClick, onDoubleClick, etc... | | onOpen | function | - | A function to call when the modal will open | | onClose | function | - | A function to call when the modal will close | | background | string | - | Any valid css background: #fffff, rgb(1,1,1), etc | ### Modal Component ```js import { Modal } from 'react-morphing-modal'; <Modal closeButton={true} padding={true}> hello </Modal>; ``` | Props | Type | Default | Description | | ----------- | ------- | ------- | ---------------------------------------------------------------- | | closeButton | boolean | true | Display a close button | | padding | boolean | true | Remove the default padding. Useful when doing some customisation | ## Browser Support | ![IE](https://cloud.githubusercontent.com/assets/398893/3528325/20373e76-078e-11e4-8e3a-1cb86cf506f0.png) | ![Chrome](https://cloud.githubusercontent.com/assets/398893/3528328/23bc7bc4-078e-11e4-8752-ba2809bf5cce.png) | ![Firefox](https://cloud.githubusercontent.com/assets/398893/3528329/26283ab0-078e-11e4-84d4-db2cf1009953.png) | ![Safari](https://cloud.githubusercontent.com/assets/398893/3528331/29df8618-078e-11e4-8e3e-ed8ac738693f.png) | ![Edge](https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png) | | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | | ❌ | ✅ | ✅ | ✅ | ✅ | ## Release Notes You can find the release note for the latest release [here](https://github.com/fkhadra/react-morphing-modal/releases/latest) You can browse them all [here](https://github.com/fkhadra/react-morphing-modal/releases) ## Contribute Show your ❤️ and support by giving a ⭐. Any suggestions are welcome ! Take a look at the contributing guide. You can also find me on [reactiflux](https://www.reactiflux.com/). My pseudo is Fadi. ## License Licensed under MIT