Skip to content

Conversation

J-Sek
Copy link
Contributor

@J-Sek J-Sek commented Sep 22, 2025

  • introduces retain-focus for VOverlay (VMenu) and VNavigationDrawer
    • consolidated with the same prop on VDialog
  • supports multiple coexisting traps (only keeps focus within the closest trap)
  • skips over VList container - TBD

closes #16140

Note: considering activate, deactivate (like in VueUse)

Markup:

<template>
  <v-app>
    <v-navigation-drawer v-model="sidebar" capture-focus retain-focus temporary>
      <div class="d-flex flex-column ga-3">
        <v-btn text="Button 1" />
        <v-btn text="Button 2" />
        <v-btn>
          Menu with list
          <v-menu activator="parent" location="right" retain-focus>
            <v-list>
              <v-list-item title="foo" @click="" />
              <v-list-item title="bar" @click="" />
              <v-list-item title="baz" @click="" />
            </v-list>
          </v-menu>
        </v-btn>
        <v-btn>
          Menu in buttons
          <v-menu activator="parent" location="right" retain-focus>
            <v-sheet>
              <v-btn-group direction="vertical">
                <v-btn text="foo" @click="" />
                <v-btn text="bar" @click="" />
                <v-btn text="baz" @click="" />
              </v-btn-group>
            </v-sheet>
          </v-menu>
        </v-btn>
      </div>
    </v-navigation-drawer>
    <v-container>
      <v-row class="gc-6">
        <v-menu :close-on-content-click="false" width="500" retain-focus>
          <template #activator="{ props }">
            <v-btn v-bind="props" text="Open Menu" />
          </template>

          <template #default="{ isActive }">
            <v-card title="Menu">
              <v-card-text>
                <v-text-field />
              </v-card-text>

              <v-card-actions>
                <v-btn text="Close" @click="isActive.value = false" />
                <v-btn text="Save" @click="isActive.value = false" />
              </v-card-actions>
            </v-card>
          </template>
        </v-menu>
        <v-btn prepend-icon="mdi-earth">
          Dialog with radio group
          <v-dialog
            v-slot="{ isActive }"
            activator="parent"
            height="300"
            width="auto"
            capture-focus
            retain-focus
            scrollable
          >
            <v-card title="Select an option">
              <template #subtitle>
                <small> would be better to let <v-kbd>Tab</v-kbd> escape to the actions, as the list might be very long </small>
              </template>
              <v-divider />
              <v-card-text class="px-4" style="height: 300px;">
                <v-radio-group hide-details>
                  <v-radio v-for="i in 10" :key="i" :label="`Option #${i}`" :value="i" />
                </v-radio-group>
              </v-card-text>
              <v-divider />
              <v-card-actions>
                <v-btn text="Close" @click="isActive.value = false" />
                <v-btn color="surface-variant" text="Save" variant="flat" @click="isActive.value = false" />
              </v-card-actions>
            </v-card>
          </v-dialog>
        </v-btn>
        <v-btn text="Open sidebar" @click="sidebar = true" />
      </v-row>
    </v-container>
  </v-app>
</template>

<script setup>
  import { ref } from 'vue'

  const sidebar = ref(false)
</script>

@KaelWD
Copy link
Member

KaelWD commented Sep 23, 2025

Why is this separate from retainFocus? Seems kinda confusing to have two props that do almost the same thing but in slightly different ways.

@J-Sek J-Sek changed the title feat(VNagivationDrawer, VOverlay): add focus-trap prop feat(VNagivationDrawer, VOverlay): add retain-focus prop Sep 23, 2025
@J-Sek
Copy link
Contributor Author

J-Sek commented Sep 23, 2025

TODO:

  • ensure capture-focus works when activator is the last element in the DOM (like in the example in PR description)
    • maybe replace with keydown?
  • ? let tab escape VList and VRadioGroup

@J-Sek J-Sek force-pushed the dev branch 3 times, most recently from a7fa817 to 2e2cddb Compare October 8, 2025 15:22
@J-Sek J-Sek added this to the v3.11.0 milestone Oct 17, 2025
@J-Sek J-Sek linked an issue Oct 17, 2025 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug Report][3.0.1] v-navigation-drawer does not have focus trap

2 participants