Preparation of confirm modal context

This commit is contained in:
Jan Zípek 2022-08-28 13:06:44 +02:00
parent 8758d7b64e
commit ea682998a8
1 changed files with 85 additions and 0 deletions

View File

@ -0,0 +1,85 @@
import { Modal } from '@/components/Modal'
import { ComponentChild, createContext } from 'preact'
import { useCallback, useContext, useMemo, useState } from 'preact/hooks'
type Props = {
children: ComponentChild
}
type ShowModalProps = {
content: ComponentChild
onConfirm: () => void
onCancel: () => void
}
type ShowModelResult = {
show: () => void
}
type ConfirmModalContext = {
createModal: (props: ShowModalProps) => ShowModelResult
}
type ModalState = {
id: string
props: ShowModalProps
}
const ConfirmModalContext = createContext<ConfirmModalContext | null>(null)
export const ConfirmModalContextProvider = ({ children }: Props) => {
const [modals, setModals] = useState([] as ModalState[])
const createModal = useCallback((props: ShowModalProps) => {
return {
show: () =>
setModals((p) => [
...p,
{ id: new Date().getTime().toString(), props },
]),
}
}, [])
const handleClose = (modal: ModalState) => {
setModals((p) => p.filter((m) => m.id !== modal.id))
modal.props.onCancel()
}
const handleConfirm = (modal: ModalState) => {
setModals((p) => p.filter((m) => m.id !== modal.id))
modal.props.onConfirm()
}
const value = useMemo(() => ({ createModal }), [createModal])
return (
<ConfirmModalContext.Provider value={value}>
{children}
{modals.map((m) => (
<Modal open key={m.id} onClose={() => handleClose(m)}>
{m.props.content}
<button onClick={() => handleConfirm(m)}>OK</button>
</Modal>
))}
</ConfirmModalContext.Provider>
)
}
export const useConfirmModalContext = () => {
const ctx = useContext(ConfirmModalContext)
if (!ctx) {
throw new Error('useConfirmModalContext used outside context')
}
return ctx
}
export const useConfirmModal = (modal: ShowModalProps) => {
const ctx = useConfirmModalContext()
return ctx.createModal(modal)
}