1
1
import * as React from 'react' ;
2
+ import * as _ from 'lodash' ;
2
3
3
4
type CloseModal = ( ) => void ;
4
5
5
6
type UnknownProps = { [ key : string ] : unknown } ;
6
7
export type ModalComponent < P = UnknownProps > = React . FC < P & { closeModal : CloseModal } > ;
7
8
8
- export type LaunchModal = < P = UnknownProps > ( component : ModalComponent < P > , extraProps : P ) => void ;
9
+ export type LaunchModal = < P = UnknownProps > (
10
+ component : ModalComponent < P > ,
11
+ extraProps : P ,
12
+ id ?: string ,
13
+ ) => void ;
9
14
10
15
type ModalContextValue = {
11
16
launchModal : LaunchModal ;
@@ -17,24 +22,50 @@ export const ModalContext = React.createContext<ModalContextValue>({
17
22
closeModal : ( ) => { } ,
18
23
} ) ;
19
24
25
+ type ComponentMap = {
26
+ [ key : string ] : {
27
+ Component : ModalComponent < UnknownProps > ;
28
+ props : { [ key : string ] : any } ;
29
+ } ;
30
+ } ;
31
+
20
32
export const ModalProvider : React . FC = ( { children } ) => {
21
33
const [ isOpen , setOpen ] = React . useState ( false ) ;
22
34
const [ Component , setComponent ] = React . useState < ModalComponent > ( ) ;
23
35
const [ componentProps , setComponentProps ] = React . useState ( { } ) ;
36
+ const [ componentsMap , setComponentsMap ] = React . useState < ComponentMap > ( { } ) ;
24
37
25
38
const launchModal = React . useCallback < LaunchModal > (
26
- ( component , compProps ) => {
27
- setComponent ( ( ) => component ) ;
39
+ ( component , compProps , id = undefined ) => {
40
+ if ( id ) {
41
+ setComponentsMap ( ( components ) => ( {
42
+ ...components ,
43
+ [ id ] : { Component : component , props : compProps } ,
44
+ } ) ) ;
45
+ } else {
46
+ setComponent ( ( ) => component ) ;
47
+ }
28
48
setComponentProps ( compProps ) ;
29
49
setOpen ( true ) ;
30
50
} ,
31
51
[ setOpen , setComponent , setComponentProps ] ,
32
52
) ;
33
- const closeModal = React . useCallback < CloseModal > ( ( ) => setOpen ( false ) , [ setOpen ] ) ;
53
+
54
+ const closeModal = React . useCallback < CloseModal > ( ( ) => {
55
+ setOpen ( false ) ;
56
+ setComponent ( undefined ) ;
57
+ } , [ setOpen ] ) ;
58
+
59
+ const closeModalWithID = React . useCallback < ( id : string ) => void > ( ( id ) => {
60
+ setComponentsMap ( ( components ) => _ . omit ( components , id ) ) ;
61
+ } , [ ] ) ;
34
62
35
63
return (
36
64
< ModalContext . Provider value = { { launchModal, closeModal } } >
37
65
{ isOpen && ! ! Component && < Component { ...componentProps } closeModal = { closeModal } /> }
66
+ { _ . map ( componentsMap , ( c , id ) => (
67
+ < c . Component { ...c . props } key = { id } closeModal = { ( ) => closeModalWithID ( id ) } />
68
+ ) ) }
38
69
{ children }
39
70
</ ModalContext . Provider >
40
71
) ;
0 commit comments