Skip to content

fix(VMenu): submenu a11y/navigation improvements#22904

Draft
J-Sek wants to merge 4 commits into
masterfrom
fix/vmenu-submenu-improvements
Draft

fix(VMenu): submenu a11y/navigation improvements#22904
J-Sek wants to merge 4 commits into
masterfrom
fix/vmenu-submenu-improvements

Conversation

@J-Sek

@J-Sek J-Sek commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Makes nested submenus behave predictably under mixed keyboard + mouse use, instead of collapsing the whole tree to document.body on an incidental hover-out.

Behavior

  • mouseleave should not close the submenu unless the root menu opened with hover (aligns with other frameworks)
  • one submenu open per level when mixing hover and keyboard interactions
  • more reliable keyboard navigation is reliable
    • ArrowLeft steps back one level and keeps focus inside
    • Tab/Shift+Tab closes one level
    • opening a submenu lands focus on its first item
  • focus is restored correctly when a single submenu closes, rather than falling to document.body

Notes

  • useActivator gains an isSubmenu flag (plumbed via an internal _submenu prop on VOverlay) so the hover-chain logic applies only to actual submenus
  • VMenuSymbol now tracks open children by id + close handle, enabling per-level replacement and subtree collapse

Markup:

<template>
  <v-app theme="dark">
    <v-container max-width="500">
      <button>before</button>
      <v-btn color="primary">
        Open menu
        <v-menu activator="parent" open-on-hover>
          <v-list>
            <v-list-item v-for="i in 3" :key="i" link>
              <v-list-item-title>Item {{ i }}</v-list-item-title>
              <template #append>
                <v-icon icon="mdi-menu-right" size="x-small" />
              </template>

              <v-menu :open-on-focus="false" activator="parent" open-on-hover submenu>
                <v-list>
                  <v-list-item v-for="j in 3" :key="j" link>
                    <v-list-item-title>Item {{ i }} - {{ j }}</v-list-item-title>
                    <template #append>
                      <v-icon icon="mdi-menu-right" size="x-small" />
                    </template>

                    <v-menu :open-on-focus="false" activator="parent" open-on-hover submenu>
                      <v-list>
                        <v-list-item v-for="k in 3" :key="k" link>
                          <v-list-item-title>Item {{ i }} - {{ j }} - {{ k }}</v-list-item-title>
                        </v-list-item>
                      </v-list>
                    </v-menu>
                  </v-list-item>
                </v-list>
              </v-menu>
            </v-list-item>
          </v-list>
        </v-menu>
      </v-btn>
      <button>after</button>

    </v-container>
  </v-app>
</template>

@J-Sek J-Sek self-assigned this Jun 5, 2026
@J-Sek J-Sek added T: bug Functionality that does not work as intended/expected a11y Accessibility issue C: VMenu labels Jun 5, 2026
@J-Sek J-Sek added this to the v4.1.x milestone Jun 5, 2026
@J-Sek J-Sek force-pushed the fix/vmenu-submenu-improvements branch from 6756494 to 51d6d47 Compare June 5, 2026 22:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a11y Accessibility issue C: VMenu T: bug Functionality that does not work as intended/expected

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant