1+ import { reactive , inject , markRaw , nextTick , readonly } from 'vue'
12import type { Component , InjectionKey } from 'vue'
2- import { inject , markRaw , nextTick , reactive , readonly } from 'vue'
3- import type { Awaitable , PageData , PageDataPayload } from '../shared'
43import { notFoundPageData , treatAsHtml } from '../shared'
4+ import type { PageData , PageDataPayload , Awaitable } from '../shared'
5+ import { inBrowser , withBase } from './utils'
56import { siteDataRef } from './data'
6- import { getScrollOffset , inBrowser , withBase } from './utils'
77
88export interface Route {
99 path : string
@@ -261,14 +261,34 @@ export function scrollTo(el: Element, hash: string, smooth = false) {
261261 }
262262
263263 if ( target ) {
264+ let scrollOffset = siteDataRef . value . scrollOffset
265+ let offset = 0
266+ let padding = 24
267+ if ( typeof scrollOffset === 'object' && 'padding' in scrollOffset ) {
268+ padding = scrollOffset . padding
269+ scrollOffset = scrollOffset . selector
270+ }
271+ if ( typeof scrollOffset === 'number' ) {
272+ offset = scrollOffset
273+ } else if ( typeof scrollOffset === 'string' ) {
274+ offset = tryOffsetSelector ( scrollOffset , padding )
275+ } else if ( Array . isArray ( scrollOffset ) ) {
276+ for ( const selector of scrollOffset ) {
277+ const res = tryOffsetSelector ( selector , padding )
278+ if ( res ) {
279+ offset = res
280+ break
281+ }
282+ }
283+ }
264284 const targetPadding = parseInt (
265285 window . getComputedStyle ( target ) . paddingTop ,
266286 10
267287 )
268288 const targetTop =
269289 window . scrollY +
270290 target . getBoundingClientRect ( ) . top -
271- getScrollOffset ( ) +
291+ offset +
272292 targetPadding
273293 function scrollToTarget ( ) {
274294 // only smooth scroll if distance is smaller than screen height.
@@ -280,6 +300,14 @@ export function scrollTo(el: Element, hash: string, smooth = false) {
280300 }
281301}
282302
303+ function tryOffsetSelector ( selector : string , padding : number ) : number {
304+ const el = document . querySelector ( selector )
305+ if ( ! el ) return 0
306+ const bot = el . getBoundingClientRect ( ) . bottom
307+ if ( bot < 0 ) return 0
308+ return bot + padding
309+ }
310+
283311function handleHMR ( route : Route ) : void {
284312 // update route.data on HMR updates of active page
285313 if ( import . meta. hot ) {
0 commit comments