diff --git a/src/app/(after-login)/epigrams/_components/detail/DetailHeader.tsx b/src/app/(after-login)/epigrams/_components/detail/DetailHeader.tsx index b1d71be..5756d64 100644 --- a/src/app/(after-login)/epigrams/_components/detail/DetailHeader.tsx +++ b/src/app/(after-login)/epigrams/_components/detail/DetailHeader.tsx @@ -23,7 +23,14 @@ export function DetailHeader({ tags, isOwner, onEdit, onRemove }: DetailHeaderPr
수정하기 - 삭제하기 + { + e.stopPropagation(); + onRemove(); + }} + > + 삭제하기 +
)} diff --git a/src/app/(after-login)/mypage/_components/MyProfile.tsx b/src/app/(after-login)/mypage/_components/MyProfile.tsx index 04400eb..acec9e3 100644 --- a/src/app/(after-login)/mypage/_components/MyProfile.tsx +++ b/src/app/(after-login)/mypage/_components/MyProfile.tsx @@ -17,13 +17,17 @@ export default function MyProfile() {
{session && ( <> -
open('ProfileEdit')} className='cursor-pointer'> +
+

{session.user?.nickname}

diff --git a/src/app/(after-login)/mypage/_components/ProfileEditModal.tsx b/src/app/(after-login)/mypage/_components/ProfileEditModal.tsx index 01179d2..2d8bde7 100644 --- a/src/app/(after-login)/mypage/_components/ProfileEditModal.tsx +++ b/src/app/(after-login)/mypage/_components/ProfileEditModal.tsx @@ -75,11 +75,15 @@ export default function ProfileEditModal() { if (!isOpen || type !== 'ProfileEdit') return null; return ( - +
+

+ 프로필 수정 +

+ 취소 diff --git a/src/components/DeleteModal.tsx b/src/components/DeleteModal.tsx index 10250d1..774ffbf 100644 --- a/src/components/DeleteModal.tsx +++ b/src/components/DeleteModal.tsx @@ -22,8 +22,16 @@ export default function DeleteModal({ isSubmitting = false, }: DeleteModalProps) { return ( - +
+

+ {type === 'comment' ? '댓글 삭제' : '게시물 삭제'} +

삭제 경고 아이콘 diff --git a/src/utils/focusTrap.ts b/src/utils/focusTrap.ts new file mode 100644 index 0000000..ac56b0a --- /dev/null +++ b/src/utils/focusTrap.ts @@ -0,0 +1,72 @@ +export function getFocusableElements(container: HTMLElement) { + return Array.from( + container.querySelectorAll( + 'a[href], button, textarea, input, select, [tabindex]:not([tabindex="-1"])', + ), + ).filter((el) => !el.hasAttribute('disabled') && !el.getAttribute('aria-hidden')); +} + +export function focusTrap(e: React.KeyboardEvent, container: HTMLElement | null) { + if (e.key !== 'Tab' || !container) return; + + const focusableElements = getFocusableElements(container); + if (focusableElements.length === 0) return; + + const first = focusableElements[0]; + const last = focusableElements[focusableElements.length - 1]; + const isShift = e.shiftKey; + const activeElement = document.activeElement; + + if (isShift) { + if (activeElement === first || !container.contains(activeElement)) { + e.preventDefault(); + last.focus(); + } + } else { + if (activeElement === last || !container.contains(activeElement)) { + e.preventDefault(); + first.focus(); + } + } +} + +/** + * keyboard arrow의 조작으로 변경되는 tab focus + * - React DOM에 직접적으로 연결이 아니라, useEffect 내부에서 eventListener를 등록, 해제하는 방향으로 작성 (window KeyobardEvent 사용) + * - 넘겨진 event에서 currentTarget으로 eventListener가 걸린 HTMLElement를 container로 등록하고 사용 + */ + +export function focusTrapWithArrow(e: KeyboardEvent, direction: 'vertical' | 'horizontal') { + const container = e.currentTarget as HTMLElement; + if (!container) return; + + const isForward = + (direction === 'vertical' && e.key === 'ArrowDown') || + (direction === 'horizontal' && e.key === 'ArrowRight'); + + const isBackward = + (direction === 'vertical' && e.key === 'ArrowUp') || + (direction === 'horizontal' && e.key === 'ArrowLeft'); + + if (!isForward && !isBackward) return; + + const focusableElements = getFocusableElements(container); + if (focusableElements.length === 0) return; + + const currentIndex = focusableElements.findIndex((el) => el === document.activeElement); + if (currentIndex === -1) return; + + const focusableLength = focusableElements.length; + let targetIndex: number | null = null; + + if (isForward) { + targetIndex = currentIndex + 1 < focusableLength ? currentIndex + 1 : 0; + } else if (isBackward) { + targetIndex = currentIndex - 1 >= 0 ? currentIndex - 1 : focusableLength - 1; + } + + if (targetIndex !== null) { + e.preventDefault(); + focusableElements[targetIndex]?.focus(); + } +}