Keyboard navigation and focus management for file tree browser expand/collapse toggle
Summary
This issue addresses accessibility improvements for the file tree browser (FTB) expand/collapse toggle functionality that were identified during the implementation of #541102 (closed).
Problems
1. Focus Management Issue
The following discussion from !199190 (merged) should be addressed:
-
@slashmanov started a discussion: issue (ux, non-blocking): @ms.mondrian since we remove the toggle button and create it again we need to restore focus. I tried to do this locally and it's going to be hard and will bloat the MR even more. I think we can do this in a follow-up.
Issues split out to a separate issue: https://gitlab.com/gitlab-org/gitlab/-/issues/581007
2. Keyboard Navigation Issue
Additionally, @psjakubowska identified an accessibility issue in this comment:
Apart from restoring the focus, we should also block the access to the FTB when it's collapsed. Similar that is done with modals. I was able to tab through the FTB and fill in the filter bar, while it was collapsed.
Screen_Recording_2025-09-19_at_16.39.08
3. File tree browser is still interactive-able when collapsed
@brendan777 noticed, shortcut and search are still working when file tree browser is collapsed
Acceptance Criteria
-
Focus restoration: When the toggle button is recreated (due to component re-rendering), focus should be restored to the toggle button -
Keyboard accessibility: When the file tree browser is collapsed, users should not be able to tab through its contents or interact with elements inside it -
Focus trap prevention: Ensure keyboard focus cannot enter the collapsed file tree browser content -
See !204775 (comment 2758438229), tooltip should NOT linger when the file tree browser is collapsed -
File tree browser should not be interactive, when collapsed
Implementation Suggestions
From @slashmanov's comment:
I think we'd need to create the
initializedproperty in both component trees (not in the store). The first time both trees are mounted we set the property totrueand based off that property we set thefocusprop on the toggle component that would force button focus (also inside themountedhook).Alternatively we could set an ID on the button and use that for focus but I don't like us doing
querySelectoron DOM rendered by Vue components because it's fragile and implicit (we can't tell who called focus just by looking at the button).