Skip to content

bug(ui): #4806 HostSelectionDialog focus trap breaks Shift+Tab — snaps to first element instead of wrapping #5016

@mrveiss

Description

@mrveiss

Problem

PR #4980 added a focus trap to `HostSelectionDialog.vue` at line ~417 using a `focusin` listener that snaps focus to `focusable[0]` whenever focus escapes.

This breaks natural keyboard navigation:

  • Shift+Tab on the first focusable element → lands on `body` → listener snaps back to first → user can never wrap to last
  • Any click outside the dialog on a focusable element → bounces focus back to first control → disorients users and blocks browser devtools usage

Fix

Implement a real focus trap via keydown listener on the dialog root that intercepts Tab/Shift+Tab and wraps focus:

  • Tab on last focusable → focus first
  • Shift+Tab on first focusable → focus last
  • All other tabs: default browser behavior

BaseModal has the same pattern — fix both together.

Related discoveries

  • `_uid = Math.random().toString(36).substr(2, 9)` — `substr` is deprecated. BaseModal does the same. Use Vue 3.5+ `useId()`.

Meta

Found during session 144 quality gate (2026-04-17).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfrontend

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions