Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions packages/vuetify/src/components/VDialog/VDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,6 @@ export const VDialog = genericComponent<OverlaySlots>()({
emit('afterLeave')
}

watch(isActive, async val => {
if (!val) {
await nextTick()
overlay.value!.activatorEl?.focus({ preventScroll: true })
}
})

useRender(() => {
const overlayProps = VOverlay.filterProps(props)
const activatorProps = mergeProps({
Expand Down
13 changes: 2 additions & 11 deletions packages/vuetify/src/components/VMenu/VMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export const VMenu = genericComponent<OverlaySlots>()({
) {
if (focusTrapSuppressed) {
if (!props.openOnHover && !overlay.value.activatorEl?.contains(after)) {
isActive.value = false
overlay.value.closeWithoutReturningFocus()
}
} else {
const focusable = focusableChildren(overlay.value.contentEl)
Expand Down Expand Up @@ -174,26 +174,17 @@ export const VMenu = genericComponent<OverlaySlots>()({
function onKeydown (e: KeyboardEvent) {
if (props.disabled) return

if (e.key === 'Tab' || (e.key === 'Enter' && !props.closeOnContentClick)) {
if (
e.key === 'Enter' &&
((e.target instanceof HTMLTextAreaElement) ||
(e.target instanceof HTMLInputElement && !!e.target.closest('form')))
) return
if (e.key === 'Enter') e.preventDefault()

if (e.key === 'Tab') {
const nextElement = getNextElement(
focusableChildren(overlay.value?.contentEl as Element, false),
e.shiftKey ? 'prev' : 'next',
(el: HTMLElement) => el.tabIndex >= 0
)
if (!nextElement) {
isActive.value = false
overlay.value?.activatorEl?.focus()
}
} else if (props.submenu && e.key === (isRtl.value ? 'ArrowRight' : 'ArrowLeft')) {
isActive.value = false
overlay.value?.activatorEl?.focus()
}
}

Expand Down
32 changes: 28 additions & 4 deletions packages/vuetify/src/components/VOverlay/VOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import vClickOutside from '@/directives/click-outside'
import {
computed,
mergeProps,
nextTick,
onBeforeUnmount,
ref,
Teleport,
Expand Down Expand Up @@ -170,8 +171,12 @@ export const VOverlay = genericComponent<OverlaySlots>()({
const isMounted = useHydration()
const { scopeId } = useScopeId()

let _returnFocusToActivator = true

watch(() => props.disabled, v => {
if (v) isActive.value = false
if (v) {
closeWithoutReturningFocus()
}
})

const { contentStyles, updateLocation } = useLocationStrategies(props, {
Expand All @@ -192,7 +197,9 @@ export const VOverlay = genericComponent<OverlaySlots>()({
function onClickOutside (e: MouseEvent) {
emit('click:outside', e)

if (!props.persistent) isActive.value = false
if (!props.persistent) {
closeWithoutReturningFocus()
}
else animateClick()
}

Expand All @@ -203,6 +210,19 @@ export const VOverlay = genericComponent<OverlaySlots>()({
)
}

function closeWithoutReturningFocus () {
_returnFocusToActivator = false
isActive.value = false
setTimeout(() => _returnFocusToActivator = true, 100)
}

watch(isActive, async val => {
if (!val && _returnFocusToActivator) {
await nextTick()
activatorEl.value?.focus({ preventScroll: true })
}
})

IN_BROWSER && watch(isActive, val => {
if (val) {
window.addEventListener('keydown', onKeydown)
Expand Down Expand Up @@ -241,8 +261,11 @@ export const VOverlay = genericComponent<OverlaySlots>()({
useBackButton(router, next => {
if (globalTop.value && isActive.value) {
next(false)
if (!props.persistent) isActive.value = false
else animateClick()
if (!props.persistent) {
closeWithoutReturningFocus()
} else {
animateClick()
}
} else {
next()
}
Expand Down Expand Up @@ -370,6 +393,7 @@ export const VOverlay = genericComponent<OverlaySlots>()({
globalTop,
localTop,
updateLocation,
closeWithoutReturningFocus,
}
},
})
Expand Down
Loading