Skip to content

Commit 7ed9a54

Browse files
committed
fix(VSelect): close menu when click lands inside host overlay
fixes #22897
1 parent 5e6fe60 commit 7ed9a54

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

packages/vuetify/src/components/VOverlay/VOverlay.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,9 @@ export const VOverlay = genericComponent<OverlaySlots>()({
403403
closeConditional,
404404
include: () => [
405405
activatorEl.value,
406-
// Submenu/cascade clicks count as "inside" so they don't suppress focus-return.
407-
...Array.from(document.querySelectorAll('.v-overlay__content')) as HTMLElement[],
406+
// Submenu clicks count as "inside"; clicks in ancestor overlays (e.g. a host dialog) don't.
407+
...Array.from(document.querySelectorAll('.v-overlay__content'))
408+
.filter(ownsFocus) as HTMLElement[],
408409
],
409410
}}
410411
class={[

packages/vuetify/src/components/VSelect/__tests__/VSelect.spec.browser.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Components
22
import { VSelect } from '../VSelect'
3+
import { VDialog } from '@/components/VDialog'
34
import { VForm } from '@/components/VForm'
45
import { VListItem } from '@/components/VList'
56
import { VTextField } from '@/components/VTextField'
@@ -1052,5 +1053,24 @@ describe('VSelect', () => {
10521053
expect(screen.getByRole('listbox').contains(document.activeElement)).toBe(true)
10531054
})
10541055

1056+
it('should close its menu when clicking another field inside a dialog', async () => {
1057+
const dialog = ref(true)
1058+
render(() => (
1059+
<VDialog v-model={ dialog.value }>
1060+
<div>
1061+
<VTextField data-testid="other-field" label="Other" />
1062+
<VSelect items={ items } label="Age" />
1063+
</div>
1064+
</VDialog>
1065+
))
1066+
1067+
const select = screen.getByCSS('.v-select')
1068+
await userEvent.click(select)
1069+
await expect.poll(() => select).toHaveClass('v-select--active-menu')
1070+
1071+
await userEvent.click(screen.getByTestId('other-field'))
1072+
await expect.poll(() => select).not.toHaveClass('v-select--active-menu')
1073+
})
1074+
10551075
showcase({ stories })
10561076
})

0 commit comments

Comments
 (0)