Skip to content

[Feature/#318] 모달 focus trap 및 키보드 네비게이션 구현 - #321

Merged
Seojegyeong merged 2 commits into
developfrom
feature/#318
Jul 27, 2026
Merged

Seojegyeong merged 2 commits into
developfrom
feature/#318

Conversation

@Seojegyeong

@Seojegyeong Seojegyeong commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

🚨 관련 이슈

#318

✨ 변경사항

  • 🐞 BugFix Something isn't working
  • 💻 CrossBrowsing Browser compatibility
  • 🌏 Deploy Deploy
  • 🎨 Design Markup & styling
  • 📃 Docs Documentation writing and editing (README.md, etc.)
  • ✨ Feature Feature
  • 🔨 Refactor Code refactoring
  • ⚙️ Setting Development environment setup
  • ✅ Test Test related (storybook, jest, etc.)

✏️ 작업 내용

  • Modal.tsx에 FOCUSABLE_SELECTORS 상수 추가
  • 모달 오픈 시 첫 번째 focusable 요소로 자동 포커스 이동 (기존: modal div 자체에 포커스)
  • handleKeyDown 추가 — Tab/Shift+Tab 이벤트 인터셉트, 첫·마지막 요소 간 포커스 순환
  • ESC 닫기, 모달 닫힘 시 트리거 요소로 포커스 복원은 기존 구현 유지

😅 미완성 작업

N/A

📢 논의 사항 및 참고 사항

ESC 닫기(handleEscape)와 포커스 복원(previousActiveElement)은 기존 Modal.tsx에 이미 구현되어 있음
이번 PR에서는 누락된 Tab focus trap과 오픈 시 첫 번째 요소 자동 포커스만 추가했습니다.

WCAG 2.1 AA 기준:

  • 2.1.1 (Keyboard) — ESC로 모달 닫기
  • 2.1.2 (No Keyboard Trap) — Tab이 모달 내부에서만 순환

💬 리뷰어 가이드 (P-Rules)
P1: 필수 반영 (Critical) - 버그 가능성, 컨벤션 위반. 해결 전 머지 불가.
P2: 적극 권장 (Recommended) - 더 나은 대안 제시. 가급적 반영 권장.
P3: 제안 (Suggestion) - 아이디어 공유. 반영 여부는 드라이버 자율.
P4: 단순 확인/칭찬 (Nit) - 사소한 오타, 칭찬 등 피드백.

Summary by CodeRabbit

  • 버그 수정
    • 모달이 열릴 때 첫 번째 포커스 가능한 요소에 자동으로 포커스를 이동합니다.
    • Tab 키 사용 시 포커스가 모달 외부로 빠져나가지 않도록 순환 이동을 지원합니다.

@Seojegyeong
Seojegyeong requested review from YermIm and jjjsun July 27, 2026 01:46
@Seojegyeong Seojegyeong self-assigned this Jul 27, 2026
@Seojegyeong Seojegyeong linked an issue Jul 27, 2026 that may be closed by this pull request
5 tasks
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Seojegyeong, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 34 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0b1c43bc-e15d-42df-a993-c6141e88e568

📥 Commits

Reviewing files that changed from the base of the PR and between 5ac8560 and 0096d43.

📒 Files selected for processing (1)
  • src/components/common/modal/Modal.tsx
📝 Walkthrough

Walkthrough

모달 내부 포커스 가능 요소를 탐색하는 선택자를 추가하고, 모달 오픈 시 첫 요소로 포커스를 이동하도록 변경했습니다. Tab 및 Shift+Tab 입력 시 포커스가 모달 내부에서 순환하도록 키보드 이벤트를 연결했습니다.

Changes

모달 포커스 트랩

Layer / File(s) Summary
초기 포커스 및 Tab 순환
src/components/common/modal/Modal.tsx
포커스 가능 요소 목록을 정의하고, 모달 오픈 시 첫 요소로 포커스를 이동합니다. Tab 및 Shift+Tab 입력 시 포커스를 모달 내부의 양 끝 요소로 순환시키며 콘텐츠에 키보드 핸들러를 연결합니다.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Suggested reviewers: jjjsun, yermim

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed 모달 포커스 트랩과 키보드 네비게이션 추가라는 핵심 변경을 간결하게 잘 요약했습니다.
Description check ✅ Passed 관련 이슈, 변경사항, 작업 내용, 미완성 작업, 참고 사항이 템플릿에 맞게 대부분 채워져 있습니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/#318

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

📚 Storybook 배포 완료

항목 링크
📖 Storybook https://69a147b60a56365d9e2185ef-bazrskjcbd.chromatic.com/
🔍 Chromatic https://www.chromatic.com/build?appId=69a147b60a56365d9e2185ef&number=442

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/common/modal/Modal.tsx`:
- Around line 80-104: Update handleKeyDown in Modal so a Tab press is prevented
even when no focusable descendants are found, keeping focus within the modal
rather than allowing browser focus to move outside it. Preserve the existing
first/last focus wrapping behavior when focusable elements exist.
- Around line 17-24: Update the focusable-element handling around
FOCUSABLE_SELECTORS so both initial modal focus and Tab navigation use one
shared visibility/accessibility helper. Filter candidates to tabIndex >= 0,
non-empty getClientRects(), visible computed styles, and ancestors without
aria-hidden or inert; ensure hidden inputs such as Workspace’s
className="hidden" file input are excluded before focus is attempted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6ad3e69d-b8b8-45df-9fee-ab71221b6228

📥 Commits

Reviewing files that changed from the base of the PR and between d2dba33 and 5ac8560.

📒 Files selected for processing (1)
  • src/components/common/modal/Modal.tsx

Comment thread src/components/common/modal/Modal.tsx
Comment thread src/components/common/modal/Modal.tsx

@jjjsun jjjsun left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P4: 확인했습니다!

@Seojegyeong
Seojegyeong merged commit 29c5bce into develop Jul 27, 2026
3 checks passed
@Seojegyeong
Seojegyeong deleted the feature/#318 branch July 27, 2026 04:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ [Feature] 모달 focus trap 및 키보드 네비게이션 구현

2 participants