Skip to content

fix(js): trap focus in detached mode - #1374

Merged
Haroenv merged 4 commits into
algolia:nextfrom
minwookshin:fix/588
Oct 7, 2026
Merged

Haroenv merged 4 commits into
algolia:nextfrom
minwookshin:fix/588

Conversation

@minwookshin

@minwookshin minwookshin commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #588. Keep keyboard focus inside the detached search dialog and restore it to the search button when the dialog closes. Native Tab movement is preserved between controls; focus guards also contain Safari's ordinary Tab navigation when it skips buttons and links. Escape uses the core handler so pending requests are cancelled. The trap follows dynamic template controls and is removed on update/destroy, with no new dependency or opt-in.

Result

  • The autocomplete-js/core suites pass: 537 tests, 39 snapshots, and 8 existing TODOs across 79 suites. Coverage includes dynamic controls, native traversal reaching either guard, Escape/focus return, and cleanup on update/destroy.
  • Focused TypeScript checking, changed-file ESLint/formatting, and ESM compilation pass.
  • Reproduced ordinary Tab leaving the dialog before this follow-up in native Safari 27 on macOS 27. Tab/Shift+Tab and Option+Tab now stay inside; Escape returns focus to the search button. No keyboard-navigation setting was changed.

@codacy-production

codacy-production Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 29 complexity

Metric Results
Complexity 29

View in Codacy

TIP This summary will be updated as you push new changes.

@minwookshin

Copy link
Copy Markdown
Contributor Author

Added coverage for editable footer controls, including explicit tabindex="-1". The full test suite and keyboard checks in Chromium, Firefox, and WebKit pass.

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Ordinary Tab can still escape the modal under Safari’s default keyboard-navigation setting.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds detached-mode focus trapping while preserving native keyboard navigation and Escape handling.

Changes:

  • Wraps focus at detached-container boundaries.
  • Adds coverage for dynamic controls, editable elements, cleanup, and Escape.
File Description
packages/​autocomplete-js/​src/​autocomplete.ts Implements detached-mode keyboard handling.
packages/​autocomplete-js/​src/​__tests__/​detached.test.ts Adds focus-trap regression tests.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/autocomplete-js/src/autocomplete.ts
minwookshin and others added 2 commits October 6, 2026 16:47
Drop the Safari focus guards, contenteditable handling and the
inert/visibility filtering, in line with the DocSearch approach.
Keep the Tab wrap, Escape via the core handler and Ctrl/Cmd+Tab
passthrough.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Ordinary Tab can still escape the dialog in Safari because the boundary list does not match native traversal.

Review effort: Balanced
Findings: None

Resolved since last review (1)

@Haroenv
Haroenv requested a balanced review from Copilot October 7, 2026 08:10

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

The implementation still allows focus to escape in Safari and when CSS-hidden controls affect boundary detection.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)

Comment thread packages/autocomplete-js/src/autocomplete.ts
@pkg-pr-new

pkg-pr-new Bot commented Oct 7, 2026

Copy link
Copy Markdown
More templates

@algolia/autocomplete-core

npm i https://pkg.pr.new/@algolia/autocomplete-core@1374

@algolia/autocomplete-js

npm i https://pkg.pr.new/@algolia/autocomplete-js@1374

@algolia/autocomplete-plugin-algolia-insights

npm i https://pkg.pr.new/@algolia/autocomplete-plugin-algolia-insights@1374

@algolia/autocomplete-plugin-query-suggestions

npm i https://pkg.pr.new/@algolia/autocomplete-plugin-query-suggestions@1374

@algolia/autocomplete-plugin-recent-searches

npm i https://pkg.pr.new/@algolia/autocomplete-plugin-recent-searches@1374

@algolia/autocomplete-plugin-redirect-url

npm i https://pkg.pr.new/@algolia/autocomplete-plugin-redirect-url@1374

@algolia/autocomplete-plugin-tags

npm i https://pkg.pr.new/@algolia/autocomplete-plugin-tags@1374

@algolia/autocomplete-preset-algolia

npm i https://pkg.pr.new/@algolia/autocomplete-preset-algolia@1374

@algolia/autocomplete-shared

npm i https://pkg.pr.new/@algolia/autocomplete-shared@1374

@algolia/autocomplete-theme-classic

npm i https://pkg.pr.new/@algolia/autocomplete-theme-classic@1374

commit: 5cdd7d9

@Haroenv
Haroenv merged commit 366c0c3 into algolia:next Oct 7, 2026
11 checks passed
@Haroenv

Haroenv commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

thank you @minwookshin !

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.

Focus not trapped in detached mode

3 participants