bootstrap icon indicating copy to clipboard operation
bootstrap copied to clipboard

Enforce focus on dropdown trigger

Open alpadev opened this issue 5 months ago • 1 comments

Description

Enforce focus on the dropdown trigger after an item has been selected (and the dropdown is hidden).

Motivation & Context

See #35793

Regarding the implementation - I've seen some proposed implementation by @julien-deramond in another issue, but he mentioned it might be quite complex. This way the focus is only moved to the trigger, if the active focus resides within the dropdown menu. As such it shouldn't conflict if the focus was moved prior/in the event of being hidden.

~I set the focus before the hidden event is dispatched, in case some implementor wanted to change the focus to something else, via the event handler (or in case the dropdown is being disposed in the handler - to prevent an error in case the element doesn't exist anymore). Although in that case, I could imagine that screen readers would announce multiple focus jumps (not sure tho), that may require additional tweaks.~

Changed the implementation to focus after the hidden event dispatched. If a user manually moves the focus in the event outside of the dropdown, it shouldn't interfere with it anyway. Added a test to the spec to confirm that. As well as another test to make sure no error is thrown if the menu is disposed in the hidden event.

Type of changes

  • [ ] Bug fix (non-breaking change which fixes an issue)
  • [x] New feature (non-breaking change which adds functionality)
  • [ ] Refactoring (non-breaking change)
  • [ ] Breaking change (fix or feature that would change existing functionality)

Checklist

  • [x] I have read the contributing guidelines
  • [x] My code follows the code style of the project (using npm run lint)
  • [ ] My change introduces changes to the documentation
  • [ ] I have updated the documentation accordingly
  • [x] I have added tests to cover my changes
  • [x] All new and existing tests passed

Live previews

Related issues

Closes #35793 Closes #41588 (tbf this can be closed already, just so we don't forget about it)

alpadev avatar Aug 31 '25 08:08 alpadev

Will this also fix ensuring focus doesn't return if selecting a different dropdown entirely? We've had to locally comment out the focus line at the end of the hide function because we have menus with sub-menus and it caused the following unwanted behavior.

Example: a menu with two dropdown sub-menus. Click on Submenu 2 and its contents appear. image

Then click on Submenu 1. Submenu 2 closes as expected and Submenu 1 opens as expected but then focus in returned back to Submenu 2 which is no longer the active menu item. image

Menu setup for the demo:

<li class="nav-item dropdown">
     <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" id="menuDemo">Demo</a>
     <ul class="dropdown-menu">
         <li class="dropend">
             <a class="dropdown-item dropdown-toggle " data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" href="#" id="subMenuDemo1">Submenu 1</a>
             <ul class="dropdown-menu dropdown-menu-end">
                 <li>Menu Item 1A</li>
                 <li>Menu Item 1B</li>
             </ul>
         </li>         
         <li class="dropend">
             <a class="dropdown-item dropdown-toggle " data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" href="#" id="subMenuDemo2">Submenu 2</a>
             <ul class="dropdown-menu dropdown-menu-end">
                 <li>Menu Item 2A</li>
                 <li>Menu Item 2B</li>
                 <li>Menu Item 2C</li>
             </ul>
         </li>
     </ul>
 </li>

tulsaskaterchic avatar Nov 13 '25 13:11 tulsaskaterchic