@@ -7,37 +7,59 @@ import Modal from '@/common/component/Modal/Modal';
77type Closeable = { onClose : ( ) => void } ;
88type OpenOptions = { withWrapper ?: boolean } ;
99
10+ const hasOnCloseProp = ( props : unknown ) : props is { onClose : unknown } => {
11+ return (
12+ typeof props === 'object' && props !== null && 'onClose' in ( props as Record < string , unknown > )
13+ ) ;
14+ } ;
15+
16+ const isCloseable = ( element : ReactNode ) : element is ReactElement < Closeable > => {
17+ return (
18+ React . isValidElement ( element ) &&
19+ hasOnCloseProp ( element . props ) &&
20+ typeof element . props . onClose === 'function'
21+ ) ;
22+ } ;
23+
1024export const useOverlayModal = ( ) => {
11- const idsRef = useRef < string [ ] > ( [ ] ) ;
25+ const lastIdRef = useRef < string | null > ( null ) ;
1226
1327 const openModal = ( node : ReactNode , options : OpenOptions = { } ) => {
1428 const { withWrapper = true } = options ;
1529
1630 const id = overlay . open ( ( { unmount } ) => {
17- const handleClose = ( ) => unmount ( ) ;
18- const content = React . isValidElement ( node )
19- ? React . cloneElement ( node as ReactElement < Partial < Closeable > > , { onClose : handleClose } )
20- : node ;
31+ const handleClose = ( ) => {
32+ unmount ( ) ;
33+ if ( lastIdRef . current === id ) {
34+ lastIdRef . current = null ;
35+ }
36+ } ;
37+ const content = isCloseable ( node ) ? React . cloneElement ( node , { onClose : handleClose } ) : node ;
2138 return withWrapper ? < Modal onClose = { handleClose } > { content } </ Modal > : < > { content } </ > ;
2239 } ) ;
2340
24- idsRef . current . push ( id ) ;
25- return { id, close : ( ) => overlay . unmount ( id ) } ;
41+ lastIdRef . current = id ;
42+ return {
43+ id,
44+ close : ( ) => {
45+ overlay . unmount ( id ) ;
46+ if ( lastIdRef . current === id ) {
47+ lastIdRef . current = null ;
48+ }
49+ } ,
50+ } ;
2651 } ;
2752
2853 const closeModal = ( ) => {
29- const id = idsRef . current . pop ( ) ;
30- if ( id ) {
31- overlay . unmount ( id ) ;
54+ const id = lastIdRef . current ;
55+ if ( ! id ) {
56+ return ;
3257 }
33- } ;
34-
35- const closeAll = ( ) => {
36- while ( idsRef . current . length ) {
37- const id = idsRef . current . pop ( ) ! ;
38- overlay . unmount ( id ) ;
58+ overlay . unmount ( id ) ;
59+ if ( lastIdRef . current === id ) {
60+ lastIdRef . current = null ;
3961 }
4062 } ;
4163
42- return { openModal, closeModal, closeAll } ;
64+ return { openModal, closeModal } ;
4365} ;
0 commit comments