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
- 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.
Try it on CodeSandbox or browse the examples folder.
import Demodal from 'demodal'
import MyModal from './MyModal'
// ...
const result = await Demodal.open(MyModal, { myModalProp: 'value' })
// Do something with result
/**
* 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 />
</>
)
}
Thanks goes to these wonderful people (emoji key):
Thiago Zanivan 💻 |
This project follows the all-contributors specification. Contributions of any kind welcome!