Preparation of confirm modal context
This commit is contained in:
parent
8758d7b64e
commit
ea682998a8
|
|
@ -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)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue