Skip to content

Promise-based utility to control modal states in React

License

Notifications You must be signed in to change notification settings

thiagozf/demodal

Repository files navigation

Demodal Banner


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

GitHub Actions Coverage NPM bundle size Twitter Badge


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.

Demodal Examples

Basic Usage

import Demodal from 'demodal'
import MyModal from './MyModal'

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

Use-Case: Confirmation Modal

/**
 * confirm.js
 */
import { Demodal, useModal } from 'demodal'

// Register your Confirm modal wrapping it with `Demodal.create`
const Confirm = Demodal.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 => Demodal.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 { Demodal } from 'demodal'

function App() {
  // Remember to add a Demodal.Container to your app's root
  return (
    <>
      <Page />
      <Demodal.Container />
    </>
  )
}

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Thiago Zanivan

💻

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

About

Promise-based utility to control modal states in React

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published