2.0.1 • Published 1 year ago

react-await-modal v2.0.1

Weekly downloads
-
License
ISC
Repository
gitlab
Last release
1 year ago

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 
2.0.1

1 year ago

2.0.0

1 year ago

1.1.1

1 year ago

1.1.0

1 year ago

1.0.1

2 years ago

1.0.0

2 years ago