Skip to content

Conversation

@jamjoe
Copy link

@jamjoe jamjoe commented Nov 5, 2025

Description

fixes #22264
There is a race condition for the check for globalTop due to the setTimout. When clicking the v-select, it would make the v-menu no longer be globalTop before the closeConditional ran, so the menu would stay open.
As near as I can tell that check is no longer needed. The scrim checks should be good enough.

Markup:

<template>
  <v-container>
    <v-row>
      <v-col cols="12">
        <h2>Test Case 1: VMenu with VSelect (Current Issue)</h2>
        <p>Open menu, click inside menu content, then click the Select</p>
        <p><strong>Expected:</strong> Menu should close when clicking v-select</p>
        <div class="text-center">
          <v-menu v-model="menu" :close-on-content-click="false" location="end">
            <template #activator="{ props }">
              <v-btn  v-bind="props"> Menu as Popover </v-btn>
            </template>

            <v-card min-width="300">
              <v-list>
                <v-list-item
                  prepend-avatar="https://cdn.vuetifyjs.com/images/john.jpg"
                  subtitle="Founder of Vuetify"
                  title="John Leider"
                >
                  <template #append>
                    <v-btn
                      :class="fav ? 'text-red' : ''"
                      icon="mdi-heart"
                      variant="text"
                      @click="fav = !fav"
                    />
                  </template>
                </v-list-item>
              </v-list>

              <v-divider />

              <v-list>
                <v-list-item>
                  <v-switch
                    v-model="message"
                    color="purple"
                    label="Enable messages"
                    hide-details
                  />
                </v-list-item>

                <v-list-item>
                  <v-switch
                    v-model="hints"
                    color="purple"
                    label="Enable hints"
                    hide-details
                  />
                </v-list-item>
              </v-list>

              <v-card-actions>
                <v-spacer />

                <v-btn variant="text" @click="menu = false"> Cancel </v-btn>
                <v-btn color="primary" variant="text" @click="menu = false">
                  Save
                </v-btn>
              </v-card-actions>
            </v-card>
          </v-menu>
        </div>
        <v-select :items="['1', '2']" label="select" />
      </v-col>
    </v-row>

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

    <v-row>
      <v-col cols="12">
        <h2>Test Case 2: Tooltip + Snackbar (Issue #15276 from Aug 2022)</h2>
        <p>Hover over button, click it to show snackbar, then move mouse away</p>
        <p><strong>Expected:</strong> Tooltip should disappear when mouse leaves button</p>

        <v-tooltip text="This is a tooltip">
          <template #activator="{ props }">
            <v-btn v-bind="props" @click="snackbar1 = true">Click Me</v-btn>
          </template>
        </v-tooltip>

        <v-snackbar v-model="snackbar1" timeout="3000">
          Snackbar is now showing!
        </v-snackbar>
      </v-col>
    </v-row>

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

    <v-row>
      <v-col cols="12">
        <h2>Test Case 3: Tooltip with open-on-focus (Issue #15475 from Aug 2022)</h2>
        <p>Focus the button to open tooltip</p>
        <p><strong>Expected:</strong> Tooltip should open when button is focused</p>

        <v-tooltip text="Focus tooltip" open-on-focus>
          <template #activator="{ props }">
            <v-btn v-bind="props">Focus Me</v-btn>
          </template>
        </v-tooltip>
      </v-col>
    </v-row>

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

    <v-row>
      <v-col cols="12">
        <h2>Test Case 4: Nested Menus</h2>
        <p>Open parent menu, open child menu, click outside both</p>
        <p><strong>Expected:</strong> Both menus should close</p>

        <v-menu v-model="parentMenu" :close-on-content-click="false">
          <template #activator="{ props }">
            <v-btn v-bind="props">Parent Menu</v-btn>
          </template>

          <v-card class="pa-4" min-width="300">
            <v-card-title>Parent Menu</v-card-title>
            <v-card-text>
              <v-menu v-model="childMenu">
                <template #activator="{ props }">
                  <v-btn v-bind="props">Child Menu</v-btn>
                </template>

                <v-card class="pa-4" min-width="200">
                  <v-card-title>Child Menu</v-card-title>
                </v-card>
              </v-menu>
            </v-card-text>
          </v-card>
        </v-menu>
      </v-col>
    </v-row>

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

    <v-row>
      <v-col cols="12">
        <h2>Test Case 5: VAutocomplete in VMenu (Issue #20003)</h2>
        <p>Open menu, focus autocomplete, click outside both</p>
        <p><strong>Expected:</strong> Both autocomplete menu and parent menu should close</p>

        <v-menu v-model="autocompleteMenu" :close-on-content-click="false">
          <template #activator="{ props }">
            <v-btn v-bind="props">Menu with Autocomplete</v-btn>
          </template>

          <v-card class="pa-4" min-width="300">
            <v-autocomplete
              :items="['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']"
              label="Autocomplete"
            />
          </v-card>
        </v-menu>
      </v-col>
    </v-row>

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

    <v-row>
      <v-col cols="12">
        <h2>Test Case 6: VDialog</h2>
        <p>Open dialog, click outside</p>
        <p><strong>Expected:</strong> Dialog should close (has scrim)</p>

        <v-dialog v-model="dialog" max-width="500">
          <template #activator="{ props }">
            <v-btn v-bind="props">Open Dialog</v-btn>
          </template>

          <v-card>
            <v-card-title>Dialog Title</v-card-title>
            <v-card-text>This dialog has a scrim, so it should only close when clicking the scrim</v-card-text>
            <v-card-actions>
              <v-spacer />
              <v-btn @click="dialog = false">Close</v-btn>
            </v-card-actions>
          </v-card>
        </v-dialog>
      </v-col>
    </v-row>

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

    <v-row>
      <v-col cols="12">
        <h2>Test Case 7: VMenu opens, then VDialog opens on top</h2>
        <p>Open menu, then open dialog, click outside dialog (on menu content)</p>
        <p><strong>Expected:</strong> Dialog closes, menu stays open</p>

        <v-menu v-model="menuForDialog" :close-on-content-click="false">
          <template #activator="{ props }">
            <v-btn v-bind="props">Open Menu First</v-btn>
          </template>

          <v-card class="pa-4" min-width="300">
            <v-card-title>Menu Content</v-card-title>
            <v-card-text>
              <v-dialog v-model="dialogFromMenu" max-width="400">
                <template #activator="{ props }">
                  <v-btn v-bind="props">Open Dialog</v-btn>
                </template>

                <v-card>
                  <v-card-title>Dialog on top of Menu</v-card-title>
                  <v-card-text>Click outside this dialog (on the menu behind it)</v-card-text>
                  <v-card-actions>
                    <v-spacer />
                    <v-btn @click="dialogFromMenu = false">Close</v-btn>
                  </v-card-actions>
                </v-card>
              </v-dialog>
            </v-card-text>
          </v-card>
        </v-menu>
      </v-col>
    </v-row>

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

    <v-row>
      <v-col cols="12">
        <h2>Test Case 8: Persistent VMenu</h2>
        <p>Open persistent menu, click outside</p>
        <p><strong>Expected:</strong> Menu should NOT close (persistent prop)</p>

        <v-menu v-model="persistentMenu" :close-on-content-click="false" persistent>
          <template #activator="{ props }">
            <v-btn v-bind="props">Persistent Menu</v-btn>
          </template>

          <v-card class="pa-4" min-width="300">
            <v-card-title>Persistent Menu</v-card-title>
            <v-card-text>This menu won't close when clicking outside</v-card-text>
            <v-card-actions>
              <v-btn @click="persistentMenu = false">Close Manually</v-btn>
            </v-card-actions>
          </v-card>
        </v-menu>
      </v-col>
    </v-row>

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

  </v-container>
</template>

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

  const snackbar1 = ref(false)
  const menu = ref(false)
  const parentMenu = ref(false)
  const childMenu = ref(false)
  const autocompleteMenu = ref(false)
  const dialog = ref(false)
  const menuForDialog = ref(false)
  const dialogFromMenu = ref(false)
  const persistentMenu = ref(false)
</script>

fixes vuetifyjs#22264
There is a race condition where the check for globalTop due to the setTimout.  As near as I can tell that check is no longer needed.
@J-Sek
Copy link
Contributor

J-Sek commented Nov 6, 2025

Duplicate of #22227

@J-Sek J-Sek marked this as a duplicate of #22227 Nov 6, 2025
@J-Sek J-Sek closed this Nov 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug Report][3.10.7] v-menu doesn't close when :close-on-content-click="false" and click inside other v-select outside

2 participants