Promise-based utility to control modal states in React
Zero-dependency library that easily integrates with your existing UI components and allows you to naturally use modals in React

Quick Features

  • Promise based: open your modal with a simple function call and await for the result.
  • Uncontrolled: open/close your modal from anywhere in the code (even inside the modal itself).
  • Decoupled: no need to import a modal component to use it. Modals can be managed by ID.
  • Tiny: zero-dependency to keep your bundle size under control: ~1.5kB.
  • Easy integration: easily integrate with any UI library.
  • Lazy-loading: delay the rendering of your modal component until it’s open.

Examples

Try it on CodeSandbox or browse the examples folder.

Unmodal Examples

Basic Usage

import Unmodal from 'react-unmodal'
import MyModal from './MyModal'

// ...
const result = await Unmodal.open(MyModal, { myModalProp: 'value' })
// Do something with result

Use-Case: Confirmation Modal

/**
 * confirm.js
 */
import { Unmodal, useModal } from 'react-unmodal'

// Register your Confirm modal wrapping it with `Unmodal.create`
const Confirm = Unmodal.create(
  ({ title = 'Confirmation', message = 'Do you confirm this action?' }) => {
    // useModal hook to control UI components
    const modal = useModal()

    // Once resolved, automatically close the modal
    const resolve = value => () => {
      modal.resolve(value)
      modal.close()
    }

    // "title" and "message" are props sent with "modal.open()"
    return (
      <Modal open={modal.isOpen} onClose={modal.close} onExited={modal.remove}>
        <div>{title}</div>
        <div>{body}</div>
        <Button onClick={resolve(true)}>Yes</Button>
        <Button onClick={resolve(false)}>No</Button>
      </Modal>
    )
  }
)

// Create a custom confirm function
export const confirm = props => Unmodal.open(Confirm, props)

/**
 * page.js
 */
import { confirm } from './confirm'

export const Page = () => {
  const handleClick = async () => {
    const confirmed = await confirm({
      title: 'Are you sure?',
      message: 'This action is irreversible',
    })
    console.log(confirmed)
  }

  return <Button onClick={handleClick}>Action</Button>
}

/**
 * app.js
 */
import { Unmodal } from 'react-unmodal'

function App() {
  // Remember to wrap your app with Unmodal.Provider
  return (
    <Unmodal.Provider>
      <Page />
    </Unmodal.Provider>
  )
}

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Thiago Zanivan

💻

This project follows the all-contributors specification. Contributions of any kind welcome!

GitHub

View Github