Skip to content

fix(ui): 共通 modal が親の再描画ごとに dialog へ focus を戻すのを modal 側で直し、閉じたら元の要素に戻す (B-R11e) - #639

Merged
cipherwebllc merged 1 commit into
mainfrom
fix/r6-b11e-modal-focus
Sep 25, 2026
Merged

cipherwebllc merged 1 commit into
mainfrom
fix/r6-b11e-modal-focus

Conversation

@cipherwebllc

Copy link
Copy Markdown
Owner

概要

B-R11d (#635) のレビューで見つかった、共通 modal の focus 奪取の修正 (B-R11e) です。意図的な挙動変更 (a11y/UX) です。

QrPreviewModal (QR 生成画面とレジの QR modal) と CsvPassModal は、focus の effect が inline の onClose の識別に依存していたため、親が再描画されるたびに dialog へ focus を戻し、入力を中断していました。

DOM・文言・aria は変わりません。

検証

  • 新しいテスト 7 件 + 修正 2 件 (親の再描画で外の入力欄から focus が奪われないこと・最新の onClose が呼ばれること・再表示・後片付け・root の StrictMode・閉じたときの focus の復元と、裏の入力欄から奪わないこと)。修正前は落ち、修正後に通ります。
  • 別セッションの Opus 5.5 のレビュー: approve with changes → 反映済み (無条件の focus 復元・StrictMode のテストが効いていなかった点)。
  • typecheck 0 / eslint 0 / full vitest 15,141 pass

follow-up (B-R11f)

focus trap がない・SuccessOverlay にも同じ focus 奪取がある (TipForm/CheckoutForm/PaymentForm から inline の onDismiss)・FX 期限切れが modal 内に表示されない (文言の承認が必要)。

🤖 Generated with Claude Code

https://claude.ai/code/session_01HeizmagJBgL5peL5mQpxkc

@vercel

vercel Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
openpay Ignored Ignored Preview Sep 24, 2026 11:56pm UTC

Request Review

…戻す (B-R11e)

第 6 回レビュー B-R11d のレビューで判明。QrPreviewModal (QR 生成・レジの QR modal) と
CsvPassModal の focus effect が inline の onClose の識別に依存し、親の再描画のたびに dialog へ
focus を戻していた。onClose は latest-ref に持ち、focus effect は open の変化だけで動かす
(開いたときの focus と Escape は従来どおり)。閉じるときは、focus が body / null / dialog 内に
あるときだけ開いた要素へ戻す (overlay の裏の入力欄へ移した focus は奪わない)。
focus trap と SuccessOverlay の同種の問題は B-R11f。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeizmagJBgL5peL5mQpxkc
@cipherwebllc
cipherwebllc force-pushed the fix/r6-b11e-modal-focus branch from 39fa841 to 0892a25 Compare September 24, 2026 23:56
@cipherwebllc
cipherwebllc merged commit 0f25f9e into main Sep 25, 2026
8 checks passed
@cipherwebllc
cipherwebllc deleted the fix/r6-b11e-modal-focus branch September 25, 2026 00:26
cipherwebllc added a commit that referenced this pull request Sep 25, 2026
…a11y)

B-R11e (#639) の follow-up。
- lib/trapModalFocus.ts (新規): Tab/Shift+Tab を DOM 順で自前制御 (Safari 既定の Tab 設定でも循環)・
  一覧外の active (disabled 化等) は DOM 位置から直後/直前・focusable が無ければ dialog に留める・
  IME (isComposing / 229) は奪わない・visibility は要素自身の computed 値・display:none と inert は祖先を遡る。
- QrPreviewModal / CsvPassModal / SuccessOverlay に trap を適用。Escape・初期 focus・閉じた後の復元は
  #639 の契約のまま。
- SuccessOverlay: inline onDismiss に依存する focus effect を latest-ref・mount 時のみ focus・guard 付き復元に
  (TipForm/CheckoutForm/PaymentForm からの再描画で focus を奪わない)。aria-live は毎秒更新の時計を含む
  dialog 全体から見出しに限定し、aria-labelledby で可視見出しから名前を導く (掟 8)。
- QrGenerator の不要な useCallback とコメントを整理。FX 期限切れの modal 内表示 (文言要) は対象外。
tests: ModalFocusTrap (Tab 循環・一覧外 active・除外判定)・SuccessOverlay の再描画で focus 不動。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeizmagJBgL5peL5mQpxkc
cipherwebllc added a commit that referenced this pull request Sep 25, 2026
…a11y) (#652)

B-R11e (#639) の follow-up。
- lib/trapModalFocus.ts (新規): Tab/Shift+Tab を DOM 順で自前制御 (Safari 既定の Tab 設定でも循環)・
  一覧外の active (disabled 化等) は DOM 位置から直後/直前・focusable が無ければ dialog に留める・
  IME (isComposing / 229) は奪わない・visibility は要素自身の computed 値・display:none と inert は祖先を遡る。
- QrPreviewModal / CsvPassModal / SuccessOverlay に trap を適用。Escape・初期 focus・閉じた後の復元は
  #639 の契約のまま。
- SuccessOverlay: inline onDismiss に依存する focus effect を latest-ref・mount 時のみ focus・guard 付き復元に
  (TipForm/CheckoutForm/PaymentForm からの再描画で focus を奪わない)。aria-live は毎秒更新の時計を含む
  dialog 全体から見出しに限定し、aria-labelledby で可視見出しから名前を導く (掟 8)。
- QrGenerator の不要な useCallback とコメントを整理。FX 期限切れの modal 内表示 (文言要) は対象外。
tests: ModalFocusTrap (Tab 循環・一覧外 active・除外判定)・SuccessOverlay の再描画で focus 不動。


Claude-Session: https://claude.ai/code/session_01HeizmagJBgL5peL5mQpxkc

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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.

1 participant