Skip to content

fix(Tree): move focus to a visible neighbour when the focused row disappears - #2857

Draft
jcosta33 wants to merge 16 commits into
mainfrom
fix/tree-focus-prune
Draft

jcosta33 wants to merge 16 commits into
mainfrom
fix/tree-focus-prune

Conversation

@jcosta33

@jcosta33 jcosta33 commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

When the focused row is removed, focus moves to the next visible row (else the previous); when a collapse hides it, focus moves to the collapsed folder. The tree always keeps one tabbable row, so deleting the focused page in Frontify/web-app#16877 no longer drops the tree out of the tab order.

Tests: getFocusFallback.spec.ts, the focus pruning cases in useTreeController.spec.tsx, the focus recovery cases in TreeRoot.ct.tsx.

@changeset-bot

changeset-bot Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 50ec1d5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@frontify/fondue-components Patch
@frontify/fondue Patch
@frontify/fondue-sdk Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify

netlify Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for fondue-components ready!

Name Link
🔨 Latest commit 50ec1d5
🔍 Latest deploy log https://app.netlify.com/projects/fondue-components/deploys/6ac82b5c218b23000822b9c8
😎 Deploy Preview https://deploy-preview-2857.components.fondue-components.frontify.com
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

…moved

The render-time prune only moved the tab stop, so DOM focus fell to the page body when the focused row unmounted.
…y tree

Removing the last focused row threw in the focus effect, and removing a row while its action had focus never refocused because the tab stop did not change.
A blur that stays inside the tree is followed by focus, which already records that. The blur target check repeated it.
@jcosta33
jcosta33 force-pushed the fix/tree-focus-prune branch from b8c5c07 to 10d007e Compare October 6, 2026 12:18
@jcosta33
jcosta33 changed the base branch from feat/tree-is-draggable to main October 6, 2026 12:18
…rows to the collapsed folder

Visibility now comes from the items themselves instead of headless-tree's row metadata, so the fallback no longer depends on when the library rebuilds. A row hidden by a collapse hands focus to the collapsed folder, as Left Arrow would. Focus-within is one state flag that an emptied tree clears.
…talled menu

A focused menu item that unmounts outside TreeRoot's own commits fires no blur, so the flag stayed true and the next commit pulled focus back into the tree after the user clicked away. An outside pointerdown or focusin now clears it; events that reach the container through the React tree, portals included, count as inside.
… gone

A row's Dialog or Flyout re-rendering away its focused control left focus on body, and the restore pulled it onto the row behind the dialog. Focus that was inside a portal is now restored only when its row left the screen, as when a page is deleted from its row menu. TreeRow syncs the focused item on focus so the restore knows which row that was.
…witch

A real blur to body while the window is inactive kept the flag, so the next commit pulled focus back onto the row. The click-away test now waits for Radix to arm its outside-press dismissal before clicking.

This branch has not been deployed

No deployments
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