0.2.4 • Published 5 years ago

@slithy/modal v0.2.4

Weekly downloads
5
License
ISC
Repository
-
Last release
5 years ago

@slithy/modal

Context-based modals in React, using React Hooks.

Install w/ Dependencies

npm install @slithy/modal @slithy/portal react-spring

Setup

Wrap your application or component tree in the ModalProvider component.

...
import { ModalProvider } from '@slithy/modal'

const App = () => (
  <ModalProvider>
    {/*
      ... your application ...
    */}
  </ModalProvider>
)

Basic Usage

Import the Modal and ModalContext components.

import { Modal, ModalContext } from '@slithy/modal'

Create a component containing your modal definition. Be sure to spread props into the Modal component, as below.

const SimpleModal = (props) => {
  return (
    <Modal {...props}>
      <p>Hello, World. I am in a modal!</p>
    </Modal>
  )
}

In your view, use ModalContext, then create an event handler to use openModal.

import React, { useContext } from 'react'

const ExampleView = () => {
  const { openModal } = useContext(ModalContext)
  const handleOpeningModal = () => openModal(<SimpleModal />)
  return (
    <div>
      <p>Click this here button!</p>
      <button
        onClick={handleOpeningModal}
        type="button"
      >
        Open Modal
      </button>
    </div>
  )
}

API : ModalProvider

A provider component for ModalContext, it should wrap your App, or the component tree in which you will use modals.

solo

boolean, false

An optional prop. If true, allows only one modal to be open. If a new modal is opened, the current modal will be closed programmatically.

<ModalProvider solo> ... </ModalProvider>

transitions

object
An optional prop, allows you to redefine the react-spring transitions, using from, enter and leave.

Default:

<ModalProvider transitions={{
  from: { opacity: 0 },
  enter: { opacity: 1 },
  leave: { opacity: 0 },
}}>
  ...

API : ModalContext

Used with React's useContext.

const { openModal, closeModal, closeAllModals } = useContext(ModalContext)

openModal

method

A required method, use in an event handler to open a modal.

const handleOpeningModal = () => openModal(<SimpleModal />)

Optionally, you may provide a unique id as a separate argument. If omitted, the modal context will assign an id.

closeModal

method
An optional method, can be used to close a modal. Accepts an id argument.

closeAllModals

method
And optional method, can be used to close all modals.


API : Modal

The component that wraps whatever content you wish to appear in your modal. Always destructure props into the component, as below.

import { Modal } from '@slithy/modal'

const MyModal = (props) => (
  <Modal title="My Modal" {...props}>
    <div> ... Content ... </div>
  </Modal>
)

Here come the props, all optional.

actions

array

Accepts an array of JSX elements, and two special strings, 'cancel' and 'submit'.

If present, will create a modal footer containing the defined UI elements, left-to-right. The special strings will render as default modal buttons.

<Modal actions={['cancel', 'submit']}> ... </Modal>

backgroundStyle

object
A style object, applied to the .modal-background element, the semi-opaque overlay.

cardStyle

object
A style object, applied to the .modal-card element.

className

string
Apply a custom className to your modal.

closeButtonOutside

boolean
By default, the close button appears in the top-right corner of the modal card. If present, this prop moves the close button to the top-right corner of the viewport.

closeOnOutsideClick

boolean
If present, clicking the background overlay will close the modal.

onCancel

func
A callback function, executed when the Cancel button is clicked. See the actions prop for enabling the button.

After executing, the modal will close.

onCancelLabel

string
The label for the Cancel button, "Cancel" by default. See the actions prop for enabling the button.

onSubmit

func
A callback function, executed when the Submit button is clicked. See the actions prop for enabling the button.

After executing, the modal will close. To prevent closing, return false.

onSubmitLabel

string
The label for the Submit button, "Submit" by default. See the actions prop for enabling the button.

title

string
Text to display as title in the modal header.


Additionally, there are two read-only props passed into each modal by the context. These are as follows:

enqueuedToClose

boolean
Emitted as true to the modal when using closeAllModals or closeModal with the modal's id. When true, the modal will close, firing the beforeClose and afterClose event callbacks, described below.

id

string
A unique id, assigned to the modal by the context.


API : Modal Events

The modal also accepts a handful of events props, accepting callbacks that execute at defined moments in the modal's lifecycle.

There is no beforeOpen method. For such an effect, execute your code in your event handler, before the openModal method.

afterOpen

Fires immediately after the modal is opened.

beforeClose

On cancel or submit, fires before the closeModal method.

afterClose

On cancel or submit, fires after the closeModal method.


Examples

the Simplest Modal

This is as bare-bones as it gets.

const SimpleModal = (props) => (
  <Modal {...props}>
    <p>Hello, World. I am in a modal!</p>
  </Modal>
)

the Everything Modal

This modal uses every prop, and it opens and closes other modals.

const EverythingModal = (props) => {
  const { openModal, closeModal, closeAllModals } = useContext(ModalContext)

  const afterOpen = () => console.log(`${props.id} : fired afterOpen`)
  const beforeClose = () => console.log(`${props.id} : fired beforeClose`)
  const afterClose = () => console.log(`${props.id} : fired afterClose`)
  const onCancel = () => console.log(`${props.id} : canceled`)
  const onSubmit = () => console.log(`${props.id} : submitted`)

  const handleOpenNewModal = () => {
    // "beforeOpen"
    console.log('Opening a new modal!')

    // open a new, "child" modal;
    // passing the id of the parent, so that we can closeModal(props.parentId) if we want to close the parent programatically.
    return openModal(<NewModal parentId={props.id} />)
  }

  return (
    <Modal
      actions={[
        'cancel',
        props.parentId ? <button key="closeParent" onClick={() => closeModal(props.parentId)}>Close Parent</button> : null,
        <button key="closeAll" onClick={closeAllModals}>Close All</button>,
        'submit',
      ]}
      backgroundStyle={{
        backgroundColor: 'rgba(255, 0, 0, 0.2)',
      }}
      cardStyle={{
        fontSize: '0.625rem',
        width: 640,
      }}
      afterClose={afterClose}
      afterOpen={afterOpen}
      beforeClose={beforeClose}
      className="everything-modal"
      closeButtonOutside
      closeOnOutsideClick
      onCancel={onCancel}
      onCancelLabel="Close"
      onSubmit={onSubmit}
      onSubmitLabel="OK"
      title="The Everything Modal!"
      {...props}
    >
      <div>
        <p>This modal logs events to the browser console. Open your dev tools to observe.</p>
        <button onClick={handleOpenNewModal} type="button">Open New Modal</button>
      </div>
    </Modal>
  )
}

A Custom, Reusable Modal

By wrapping the Modal in a custom component, and passing through props, it's easy to create a custom variation for your own modals.

style.scss

.component-modal {
  &.oreo {
    .modal-card {
      .modal-header {
        background-color: #565656;
        color: #fff;	
      }

      .modal-main {
        margin: 12px 0;
      }
      
      .modal-footer {
        background-color: #565656;
        margin-bottom: 0;
  
        .modal-button--cancel {
          color: #fff;
        }	
      }

      .modal-button--close {
        color: #fff;
      }
    }
  }
}

OreoModal.js

import React from 'react'
import { Modal } from '@slithy/modal'
import './OreoModal.scss'

const OreoModal = ({ children, ...props }) => (
  <Modal className="oreo" {...props}>
    {children}
  </Modal>
)

export default OreoModal

0.2.4

5 years ago

0.2.3

5 years ago

0.2.2

5 years ago

0.2.1

5 years ago

0.2.0

5 years ago