11import { useModalStore } from '@/store/modalStore' ;
22import Button from './Button' ;
33import { createPortal } from 'react-dom' ;
4+ import { useEffect , useRef } from 'react' ;
45// import { spawn } from 'child_process';
56
67export default function Modal ( ) {
7- const { modal } = useModalStore ( ) ;
8+ const { modal, closeModal } = useModalStore ( ) ;
9+ const confirmButtonRef = useRef < HTMLButtonElement | null > ( null ) ;
10+ const cancelButtonRef = useRef < HTMLButtonElement | null > ( null ) ;
11+ const modalRef = useRef < HTMLDivElement > ( null ) ;
12+
13+ useEffect ( ( ) => {
14+ if ( modal . isOpen ) {
15+ confirmButtonRef . current ?. focus ( ) ; // 모달이 열리면 첫 번째 버튼에 포커스 이동
16+ }
17+ } , [ modal . isOpen ] ) ;
18+
19+ const handleKeyDown = ( e : React . KeyboardEvent < HTMLDivElement > ) => {
20+ if ( e . key === 'Escape' ) {
21+ closeModal ( ) ;
22+ }
23+
24+ if ( e . key === 'Tab' ) {
25+ e . preventDefault ( ) ; // 기본 Tab 동작 막기
26+ if ( document . activeElement === confirmButtonRef . current ) {
27+ cancelButtonRef . current ?. focus ( ) ; // 확인 버튼 → 취소 버튼으로 이동
28+ } else {
29+ confirmButtonRef . current ?. focus ( ) ; // 취소 버튼 → 확인 버튼으로 이동
30+ }
31+ }
32+ } ;
33+
834 if ( ! modal . isOpen ) return null ;
35+
936 return createPortal (
1037 < div
38+ ref = { modalRef }
1139 className = "fixed inset-0 z-50 flex items-center justify-center bg-black/50"
1240 // onClick={closeModal}
41+ onKeyDown = { ( e ) => handleKeyDown ( e ) }
1342 >
1443 < div
1544 className = "bg-white p-5 mx-5 rounded-lg card-shadow w-[287px] min-h-[148px] flex flex-col justify-between"
@@ -26,11 +55,21 @@ export default function Modal() {
2655 </ div >
2756 { modal . message && < p className = "text-center caption-r" > { modal . message } </ p > }
2857 < div className = "mt-4 flex justify-end gap-[6px]" >
29- < Button variant = "primary" onClick = { modal . onConfirm } className = "body-m" >
58+ < Button
59+ ref = { confirmButtonRef }
60+ variant = "primary"
61+ onClick = { modal . onConfirm }
62+ className = "body-m focus:bg-primary-active "
63+ >
3064 { modal . confirmText }
3165 </ Button >
3266 { modal . onCancel && (
33- < Button variant = "secondary" onClick = { modal . onCancel } className = "body-m" >
67+ < Button
68+ ref = { cancelButtonRef }
69+ variant = "secondary"
70+ onClick = { modal . onCancel }
71+ className = "body-m focus:bg-gray-5"
72+ >
3473 { modal . cancelText }
3574 </ Button >
3675 ) }
0 commit comments