Skip to content

Commit ad1e5d3

Browse files
committed
chore: add microtask before handling focus
1 parent 8a35345 commit ad1e5d3

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

packages/router/src/focus.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { RouteLocationNormalized } from './typed-routes'
22
import { Router, RouterOptions } from './router'
3+
import { nextTick } from 'vue'
34

45
export function enableFocusManagement(router: Router) {
56
// navigation-api router will handle this for us
@@ -13,7 +14,7 @@ export function enableFocusManagement(router: Router) {
1314
clearFocusTimeout()
1415
})
1516

16-
const unregister = router.afterEach(async (to, from) => {
17+
const unregister = router.afterEach(async to => {
1718
const focusManagement =
1819
to.meta.focusManagement ?? router.options.focusManagement
1920

@@ -31,6 +32,9 @@ export function enableFocusManagement(router: Router) {
3132
selector = focusManagement
3233
}
3334

35+
// ensure DOM is updated, enqueuing a microtask before handling focus
36+
await nextTick()
37+
3438
handleFocus(selector)
3539
})
3640

@@ -65,6 +69,7 @@ export function prepareFocusReset(
6569

6670
export function createFocusManagementHandler() {
6771
let timeoutId: ReturnType<typeof setTimeout> | undefined
72+
6873
return {
6974
handleFocus: (selector: string) => {
7075
clearTimeout(timeoutId)
@@ -100,5 +105,5 @@ function handleFocusManagement(
100105
target.focus({ preventScroll: true })
101106
// remove tabindex and event listener if focus still not worked
102107
if (document.activeElement !== target) restoreTabindex()
103-
}, 0)
108+
}, 150) // screen readers may need more time to react
104109
}

packages/router/src/navigation-api/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { App } from 'vue'
1+
import { App, nextTick } from 'vue'
22
import { shallowReactive, shallowRef, unref } from 'vue'
33
import {
44
parseURL,
@@ -310,7 +310,10 @@ export function createNavigationApiRouter(
310310
// - focusReset: manual, selector with value -> prevent scrolling when focusing the target selector element
311311
// We don't need to handle scroll here, the browser or user guards or components lifecycle hooks will handle it
312312
if (focusReset === 'manual' && selector) {
313-
handleFocus(selector)
313+
// ensure DOM is updated, enqueuing a microtask before handling focus
314+
nextTick(() => {
315+
handleFocus(selector)
316+
})
314317
}
315318
}
316319
}

0 commit comments

Comments
 (0)