Skip to content

Commit

Permalink
fix(VDialog): focus content element after opening
Browse files Browse the repository at this point in the history
fixes #18779
  • Loading branch information
KaelWD committed Apr 14, 2024
1 parent 01c7ff1 commit 1f3c823
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 12 deletions.
30 changes: 18 additions & 12 deletions packages/vuetify/src/components/VDialog/VDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { useProxiedModel } from '@/composables/proxiedModel'
import { useScopeId } from '@/composables/scopeId'

// Utilities
import { computed, mergeProps, nextTick, ref, watch } from 'vue'
import { mergeProps, nextTick, ref, watch } from 'vue'
import { focusableChildren, genericComponent, IN_BROWSER, propsFactory, useRender } from '@/util'

// Types
Expand Down Expand Up @@ -89,24 +89,28 @@ export const VDialog = genericComponent<OverlaySlots>()({
}, { immediate: true })
}

function onAfterEnter () {
if (overlay.value?.contentEl && !overlay.value.contentEl.contains(document.activeElement)) {
overlay.value.contentEl.focus({ preventScroll: true })
}
}

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

const activatorProps = computed(() =>
mergeProps({
useRender(() => {
const overlayProps = VOverlay.filterProps(props)
const activatorProps = mergeProps({
'aria-haspopup': 'dialog',
'aria-expanded': String(isActive.value),
}, props.activatorProps)
)

useRender(() => {
const overlayProps = VOverlay.filterProps(props)
const contentProps = mergeProps({
tabindex: -1,
}, props.contentProps)

return (
<VOverlay
Expand All @@ -123,8 +127,10 @@ export const VDialog = genericComponent<OverlaySlots>()({
{ ...overlayProps }
v-model={ isActive.value }
aria-modal="true"
activatorProps={ activatorProps.value }
activatorProps={ activatorProps }
contentProps={ contentProps }
role="dialog"
onAfterEnter={ onAfterEnter }
{ ...scopeId }
>
{{
Expand Down
6 changes: 6 additions & 0 deletions packages/vuetify/src/components/VOverlay/VOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export const VOverlay = genericComponent<OverlaySlots>()({
emits: {
'click:outside': (e: MouseEvent) => true,
'update:modelValue': (value: boolean) => true,
afterEnter: () => true,
afterLeave: () => true,
},

Expand Down Expand Up @@ -254,6 +255,10 @@ export const VOverlay = genericComponent<OverlaySlots>()({
})
}

function onAfterEnter () {
emit('afterEnter')
}

function onAfterLeave () {
_onAfterLeave()
emit('afterLeave')
Expand Down Expand Up @@ -309,6 +314,7 @@ export const VOverlay = genericComponent<OverlaySlots>()({
persisted
transition={ props.transition }
target={ target.value }
onAfterEnter={ onAfterEnter }
onAfterLeave={ onAfterLeave }
>
<div
Expand Down

0 comments on commit 1f3c823

Please sign in to comment.