Skip to content

Conversation

@J-Sek
Copy link
Contributor

@J-Sek J-Sek commented Nov 2, 2025

  • PR aims to make the re-focus of the activator a default behavior
  • restores keydown [Enter] interaction in VDateInput and VColorPicker
  • prevents weird UX when the last focusable element is closing the overlay
  • restore focus to the first input/textarea or focusable element within the activator (fixes tab-navigation in general)
  • open-on-focus will now recognize focus inside an activator element
    • to support the first scenario in the playground below

fixes #19872
fixes #22387
reverts #19519

Problems to fix:

  • VBtn activator + open-on-focus and :capture-focus="false" or all items disabled or just non-focusable content
    • tab-out returns focus to the button
  • menu with VTextarea
    • (regression) unable to capture focus
  • VBtn activator open-on-focus and VList
    • (regression) does not capture focus on Tab (after opening)
  • after changing onFocus to onFocusin, onBlur is sometimes not effective... onFocusout might not be the best replacement though

Markup:

<template>
  <v-app theme="dark">
    <v-container max-width="500">
      <v-text-field
        autocomplete="off"
        hint="Focus element in menu, then click Escape"
        placeholder="Click or focus the field"
        persistent-hint
      >
        <v-menu
          v-model="open"
          :close-on-content-click="false"
          :open-on-focus="!open"
          activator="parent"
        >
          <v-sheet class="pa-3">
            <v-slider v-model="sliderValue" class="mx-0" step="10" hide-details>
              <template #prepend>
                <v-icon-btn :disabled="sliderValue === 0" icon="$minus" variant="text" @click="sliderValue = Math.max(0, sliderValue - 10)" />
              </template>
              <template #append>
                <v-icon-btn :disabled="sliderValue === 100" icon="$plus" variant="text" @click="sliderValue = Math.min(100, sliderValue + 10)" />
              </template>
            </v-slider>
          </v-sheet>
        </v-menu>
      </v-text-field>
      <br>

      <v-color-input
        hint="Use keyboard Enter on input type switch"
        hide-actions
        persistent-hint
      />
      <br>

      <v-color-input hint="Use keyboard Enter on Ok/Cancel" persistent-hint />
      <br>

      <v-date-input
        :hide-actions="false"
        hint="Use keyboard Enter on Ok/Cancel"
        persistent-hint
      />
      <br>

      <v-date-input
        :show-adjacent-months="false"
        hint="Use Enter when focusing last item"
        persistent-hint
      />

      <v-divider class="my-6">Testing regression</v-divider>

      <v-btn color="primary">
        Open menu
        <v-menu activator="parent">
          <v-list>
            <v-list-item v-for="i in 5" :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 5" :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 5" :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>
      <div class="text-caption">Navigate with keyboard</div>
      <br>
      <v-select :items="['Foo', 'Bar', 'Fizz', 'Buzz']" />
    </v-container>
  </v-app>
</template>

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

  const open = shallowRef(false)
  const sliderValue = shallowRef(0)
</script>

@J-Sek J-Sek self-assigned this Nov 2, 2025
@J-Sek J-Sek added T: bug Functionality that does not work as intended/expected C: VMenu C: VOverlay C: VDateInput C: VColorInput labels Nov 2, 2025
@J-Sek J-Sek modified the milestone: v3.11.x Nov 11, 2025
@KaelWD KaelWD added this to the v3.11.x milestone Dec 2, 2025
@J-Sek J-Sek force-pushed the fix/menu-keydown-enter branch from 5b24d43 to 98b6ba0 Compare December 2, 2025 14:00
@J-Sek J-Sek marked this pull request as ready for review December 2, 2025 14:00
@J-Sek J-Sek added a11y Accessibility issue help wanted We are looking for community help labels Dec 2, 2025
@J-Sek J-Sek marked this pull request as draft December 2, 2025 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a11y Accessibility issue C: VColorInput C: VDateInput C: VMenu C: VOverlay help wanted We are looking for community help T: bug Functionality that does not work as intended/expected

Projects

None yet

3 participants