11import { Button } from '@shared/ui/Button/Button' ;
2- import { useEffect , useState } from 'react' ;
2+ import { useCallback , useEffect , useState } from 'react' ;
33import { modalStyles } from './Modal.styles' ;
44
55export interface ModalProps {
@@ -21,11 +21,24 @@ export const Modal = ({
2121} : ModalProps ) => {
2222 const [ closing , setClosing ] = useState ( false ) ;
2323
24- const handleClose = ( callback : ( ) => void ) => {
25- setClosing ( true ) ;
26- setTimeout ( callback , 150 ) ;
27- } ;
24+ /**
25+ * 닫힘 로직 (모든 경로에서 공통 사용)
26+ */
27+ const handleClose = useCallback (
28+ ( callback : ( ) => void ) => {
29+ if ( closing ) {
30+ return ;
31+ }
32+
33+ setClosing ( true ) ;
34+ setTimeout ( callback , 150 ) ; // fade-out duration
35+ } ,
36+ [ closing ]
37+ ) ;
2838
39+ /**
40+ * ESC 키로 닫기
41+ */
2942 useEffect ( ( ) => {
3043 const handleKeyDown = ( e : KeyboardEvent ) => {
3144 if ( e . key === 'Escape' ) {
@@ -37,21 +50,23 @@ export const Modal = ({
3750 return ( ) => {
3851 window . removeEventListener ( 'keydown' , handleKeyDown ) ;
3952 } ;
40- } , [ onCancel ] ) ;
53+ } , [ handleClose , onCancel ] ) ;
4154
4255 return (
56+ /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
4357 < div className = { modalStyles . container } onClick = { ( ) => handleClose ( onCancel ) } >
58+ { /* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ }
4459 < div
45- className = { [ modalStyles . content , closing ? 'animate-fade-out' : 'animate-fade-in' ] . join (
46- ' '
47- ) }
60+ className = { `${ modalStyles . content } ${ closing ? 'animate-fade-out' : 'animate-fade-in' } ` }
4861 onClick = { ( e ) => e . stopPropagation ( ) }
4962 >
63+ { /* Text */ }
5064 < div className = { modalStyles . textGroup } >
5165 < p className = "typo-body-2 text-black" > { title } </ p >
5266 { subtitle && < p className = "typo-caption-2 truncate text-black" > { subtitle } </ p > }
5367 </ div >
5468
69+ { /* Buttons */ }
5570 < div className = { modalStyles . buttonGroup } >
5671 < div className = { modalStyles . buttonWrapper } >
5772 < Button
0 commit comments