From b66785d68a86c118a7a036f3de8b3e504390f1da Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 16 Jan 2022 23:34:44 +0800 Subject: [PATCH] feat: scrollOffset option --- src/client/app/router.ts | 16 +++++++++++++++- src/node/config.ts | 9 ++++++++- types/shared.d.ts | 1 + 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/client/app/router.ts b/src/client/app/router.ts index 14c9120640a4..0b3d523faff0 100644 --- a/src/client/app/router.ts +++ b/src/client/app/router.ts @@ -2,6 +2,7 @@ import { reactive, inject, markRaw, nextTick, readonly } from 'vue' import type { Component, InjectionKey } from 'vue' import { PageData } from '../shared' import { inBrowser } from './utils' +import { siteDataRef } from './data' export interface Route { path: string @@ -192,7 +193,20 @@ function scrollTo(el: HTMLElement, hash: string, smooth = false) { } if (target) { - const targetTop = (target as HTMLElement).offsetTop + let offset = siteDataRef.value.scrollOffset + if (typeof offset === 'string') { + offset = + document.querySelector(offset)!.getBoundingClientRect().bottom + 24 + } + const targetPadding = parseInt( + window.getComputedStyle(target as HTMLElement).paddingTop, + 10 + ) + const targetTop = + window.scrollY + + (target as HTMLElement).getBoundingClientRect().top - + offset + + targetPadding // only smooth scroll if distance is smaller than screen height. if (!smooth || Math.abs(targetTop - window.scrollY) > window.innerHeight) { window.scrollTo(0, targetTop) diff --git a/src/node/config.ts b/src/node/config.ts index 7b337f547c5e..f2453951a89d 100644 --- a/src/node/config.ts +++ b/src/node/config.ts @@ -51,6 +51,12 @@ export interface UserConfig { outDir?: string shouldPreload?: (link: string, page: string) => boolean + /** + * Configure the scroll offset when the theme has a sticky header. + * Can be a number or a selector element to get the offset from. + */ + scrollOffset?: number | string + /** * Enable MPA / zero-JS mode * @experimental @@ -243,6 +249,7 @@ export async function resolveSiteData( head: userConfig.head || [], themeConfig: userConfig.themeConfig || {}, locales: userConfig.locales || {}, - langs: createLangDictionary(userConfig) + langs: createLangDictionary(userConfig), + scrollOffset: userConfig.scrollOffset || 90 } } diff --git a/types/shared.d.ts b/types/shared.d.ts index f2af2930c821..8f41bc5eb076 100644 --- a/types/shared.d.ts +++ b/types/shared.d.ts @@ -22,6 +22,7 @@ export interface SiteData { description: string head: HeadConfig[] themeConfig: ThemeConfig + scrollOffset: number | string locales: Record /** * Available locales for the site when it has defined `locales` in its