Skip to content

fix: Improve focus handling when clicking outside injection div#9749

Merged
gonfunko merged 3 commits intov13from
dropdown-focus
Apr 23, 2026
Merged

fix: Improve focus handling when clicking outside injection div#9749
gonfunko merged 3 commits intov13from
dropdown-focus

Conversation

@gonfunko
Copy link
Copy Markdown
Contributor

The basics

The details

Resolves

Fixes RaspberryPiFoundation/blockly-keyboard-experimentation#563

Proposed Changes

This PR improves focus management when focus transitions out of the injection div, either via click or tab, while the WidgetDiv, DropDownDiv, or both are open. Previously, this would get focus management into a bad wedged state. Now, the WidgetDiv/DropDownDiv(s) will be dismissed, the element that spawned them will get passive focus, and focus will transition to whatever the clicked/tabbed-to element is. When focus returns to the workspace, the element that spawned the WidgetDiv/DropDownDiv will regain active focus.

At a high level, this works by:

  • Listening for focusout events on the div that holds the WidgetDiv/DropDownDiv
  • When a focusout event is received, checks to make sure that the newly-focused element is actually outside of that div
  • If so, notifies the WidgetDiv and DropDownDiv, which will (a) resign ephemeral focus if they hold it, while instructing the focus manager to not actively focus the previously-focused element, and (b) hide themselves
  • Keeping tabs on the appropriate state, in the case of multiple workspaces and multiple *Divs, as focus moves around and the *Divs hide and show.

I manually verified that this worked for dropdowns, menus, and field editors with a single playground and in the multi-playground, and also that behavior is as expected for FieldAngle which uses both the DropDownDiv and the WidgetDiv simultaneously. The latter will need some slight tweaks (in general, for fields that use both, WidgetDiv should take ephemeral focus in preference to DropDownDiv so that the field editor is focused initially), but focus can move between the field editor and angle picker, both can be interacted with, and when the value is committed or focus leaves the workspace, the field becomes passively/actively focused as appropriate.

I have not added unit tests because (a) it would be a pain but more importantly (b) it'd be very useful to make sure that this is robust and works for MakeCode given the previous churn that attempts to resolve this issue have caused before investing the effort to put together a test suite given point (a).

@gonfunko gonfunko requested a review from maribethb April 22, 2026 22:10
@gonfunko gonfunko requested a review from a team as a code owner April 22, 2026 22:10
@github-actions github-actions Bot added the PR: fix Fixes a bug label Apr 22, 2026
Comment thread packages/blockly/core/focus_manager.ts
Comment thread packages/blockly/core/common.ts Outdated
@gonfunko
Copy link
Copy Markdown
Contributor Author

This also fixes #8868

@gonfunko gonfunko requested a review from maribethb April 23, 2026 18:22
@gonfunko gonfunko merged commit 1d15983 into v13 Apr 23, 2026
5 checks passed
@gonfunko gonfunko deleted the dropdown-focus branch April 23, 2026 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: fix Fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants