From 3335a6a32cd5f33310d0274ad2a594bd55620fc3 Mon Sep 17 00:00:00 2001 From: Benjamin Canac Date: Thu, 11 May 2023 16:51:30 +0200 Subject: [PATCH] docs: put back `router.options.ts` --- docs/app/router.options.ts | 74 +++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/docs/app/router.options.ts b/docs/app/router.options.ts index 9380f053..23202d07 100644 --- a/docs/app/router.options.ts +++ b/docs/app/router.options.ts @@ -1,38 +1,48 @@ import type { RouterConfig } from '@nuxt/schema' -// https://router.vuejs.org/api/interfaces/routeroptions.html -export default { - scrollBehavior (to, _form, savedPosition) { - if (history.state.stop) { return } - if (history.state.smooth) { - return { - el: history.state.smooth, - behavior: 'smooth' - } - } +function findHashPosition (hash): { el: any, behavior: ScrollBehavior, top: number } { + const el = document.querySelector(hash) + // vue-router does not incorporate scroll-margin-top on its own. + if (el) { + const top = parseFloat(getComputedStyle(el).scrollMarginTop) - if (to.hash) { - const el = document.querySelector(to.hash) as any - - if (!el) { return } - - const { marginTop } = getComputedStyle(el) - - const marginTopValue = parseInt(marginTop) - - const offset = (document.querySelector(to.hash) as any).offsetTop - marginTopValue - - return { - top: offset, - behavior: 'smooth' - } - } - - // Scroll to top of window - if (savedPosition) { - return savedPosition - } else { - return { top: 0 } + return { + el: hash, + behavior: 'smooth', + top } } } + +// https://router.vuejs.org/api/#routeroptions +export default { + scrollBehavior (to, from, savedPosition) { + const nuxtApp = useNuxtApp() + + // If history back + if (savedPosition) { + // Handle Suspense resolution + return new Promise((resolve) => { + nuxtApp.hooks.hookOnce('page:finish', () => { + setTimeout(() => resolve(savedPosition), 50) + }) + }) + } + + // Scroll to heading on click + if (to.hash) { + return new Promise((resolve) => { + if (to.path === from.path) { + setTimeout(() => resolve(findHashPosition(to.hash)), 50) + } else { + nuxtApp.hooks.hookOnce('page:finish', () => { + setTimeout(() => resolve(findHashPosition(to.hash)), 50) + }) + } + }) + } + + // Scroll to top of window + return { top: 0 } + } +}