mh-rn-component
Version:
103 lines (93 loc) • 2.4 kB
Flow
import React, {
createContext,
MutableRefObject,
useState,
useMemo,
useContext,
useRef,
useCallback
} from 'react'
import Dialog, { Props } from './index'
import { DialogType, DialogContextType, DialogList, VisibleDialogsType } from "./types"
const DialogContext = createContext<DialogContextType>({
dialogList: {},
visibleDialogs: {},
setDialog: () => { },
hideDialog: () => { },
hideAll: () => { }
})
const CustiomDialog = () => {
const { dialogList, visibleDialogs,hideDialog } = useContext(DialogContext)
const DialogListIds = () => {
return Object.keys(visibleDialogs)
}
return (<>
{
DialogListIds().map((id) => {
return <Dialog key={id} onChange={hideDialog} show={visibleDialogs[id]} {...dialogList[id]}></Dialog>
})
}
</>)
}
export const DialogProvider = ({ children }: { children: any }) => {
const [dialogList, setDialogList] = useState<DialogList>({})
const [visibleDialogs, setVisibleDialogs] = useState<VisibleDialogsType>({});
const dialogIndex = useRef(9000)
const hideDialog = useCallback((id: any) => {
setVisibleDialogs((prev) => {
return { ...prev, [id]: false }
})
}, [setVisibleDialogs])
const hideAll = useCallback(() => {
setVisibleDialogs({})
}, [setVisibleDialogs])
const setDialog = useCallback(
(props: DialogType): number => {
const { id = dialogIndex.current++, ...rest } = props
setDialogList((prev) => {
return {
...prev, [id]: {
id,
...rest
}
}
})
setVisibleDialogs((prev) => {
return { ...prev, [id]: true }
})
return id
}, [dialogList, visibleDialogs, hideDialog])
const contextValue = useMemo(() => {
return {
dialogList,
visibleDialogs,
setDialog,
hideDialog,
hideAll
}
},
[
dialogList,
visibleDialogs,
setDialog,
hideDialog,
hideAll
])
return (
<DialogContext.Provider value={contextValue}>
{children}
<CustiomDialog></CustiomDialog>
</DialogContext.Provider>
)
}
export const useDialog = () => {
const { setDialog, hideDialog, hideAll } = useContext(DialogContext)
const dialog = useMemo(() => (
{
show: setDialog,
close: hideDialog,
closeAll: hideAll
}
), [setDialog, hideDialog, hideAll])
return dialog
}