react-await-modal
v2.0.1
Published
React Await Modal
Downloads
4
Maintainers
Readme
React Await Modal (TypeScript support)
Dependencies
- react
- react-dom
Installation
npm i react-await-modal
Usage
Creating modal component
// Component should receive props mentioned below:
// - visible - show modal or not
// - onClose - function, that we can call from inside component to close it with cirtain result
// - ...props - custom props for component passed from open method, try to avoid reserved names: visible, onClose!
const ConfirmModal = ({ visible, onClose, ...props }) => {
const { title, text } = props
const _onYes = () => {
onClose(true)
}
const _onNo = () => {
onClose(false)
}
// Depending on visible prop we can apply hiding styles or unmount component
return visible ? <div className='modal modal--small confirm-modal'>
<h2>{ title }</h2>
<pre>{ text }</pre>
<div className='modal__footer'>
<button onClick={_onYes}>Yes</button>
<button onClick={_onNo}>No</button>
</div>
<div> : <></>
}
Instantiating modal factory from ModalFactory class and then we can create modal instance
import modalFactory from '@/modals'
import ConfirmModal from '@/components/ConfirmModal'
import InfoModal from '@/components/InfoModal'
enum ModalKey {
Confirm = 'confirm'
} // might be plain JS object
const modalFactory = new ModalFactory({
strict: true, // whether throw errors or warnings
keyPostfixLength: 2 // length of unique digit that attaches to component-based-key key
})
// passing modal component and UNIQUE key (optional)
export const confirmModal = modalFactory.create(ConfirmModal, ModalKey.Confirm)
export const confirmModal1 = modalFactory.create(ConfirmModal) // key would be equal ConfirmModal-01
export const confirmModal2 = modalFactory.create(ConfirmModal) // key would be equal ConfirmModal-02
// counter will be seperate for different names
export const infoModal = modalFactory.create(InfoModal) // key would be InfoModal-01
export default modalFactory
Inserting Manager component where we want to mount our modals, then setting ref to factory
import React from 'react'
import { ModalFactory } from 'react-await-modal'
import modals from '@/modals'
// some imports here...
const IndexApp: React.FC<AppPropsType> = ({ Component, pageProps }) => {
// Some logic here...
return <StoreProvider store={store}>
<Component {...pageProps} />
<ModalFactory.Manager ref={factory.setRef.bind(factory)} single />
// using bind to save context, otherwise error will occur
// single prop instructs to show only last opened modal to avoid overlapping
</StoreProvider>
}
Usage:
import { confrimModal } from '@/components/Modals'
// ...
const _onLogout = () => {
const result = await confrimModal.open({
title: 'Exit',
text: 'You sure you want to exit?'
})
// while modal is visible, following code won't be executed
if (!result) return
dispatch(logout()) // if result is true, dispatching
}
return <div>
<button onClick={_onLogout}>Exit<button>
</div>
TypeScript typization
import React, { FC } from 'react'
import { ModalProps } from 'react-await-modal'
interface ConfirmModalProps {
title?: string
text?: string
}
type ConfirmModalResult = boolean // might be more complex type
type ConfirmModalType = FC<ModalProps<
ConfirmModalProps, // {} by default
ConfirmModalResult // void by default
>>
const ConfirmModal: ConfirmModalType = () => {
// component description
}
export default ConfirmModal
Closing modals from outside
import modalFactory, { confirmModal, ModalKey } from '@/modals'
modalFactory.kill(ModalKey.Confirm, { force: true }) // closes ConfirmModal with result = { force: true }
// ModalKey.Confirm could be replaced with confirmModal.key
confirmModal.close({ force: true }) // does the same as previous line of code
modalFactory.killAll({ force: true }) // closed all modals with same result
// result might be undefined