Skip to content

Commit

Permalink
feat: support multiple selectors for scrollOffset
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Mar 15, 2023
1 parent a6b18a8 commit 86e2a6f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
26 changes: 22 additions & 4 deletions src/client/app/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,20 @@ export function scrollTo(el: Element, hash: string, smooth = false) {
}

if (target) {
let offset = siteDataRef.value.scrollOffset
if (typeof offset === 'string') {
offset =
document.querySelector(offset)!.getBoundingClientRect().bottom + 24
const scrollOffset = siteDataRef.value.scrollOffset
let offset: number = 0
if (typeof scrollOffset === 'number') {
offset = scrollOffset
} else if (typeof scrollOffset === 'string') {
offset = tryOffsetSelector(scrollOffset)
} else if (Array.isArray(scrollOffset)) {
for (const selector of scrollOffset) {
const res = tryOffsetSelector(selector)
if (res) {
offset = res
break
}
}
}
const targetPadding = parseInt(
window.getComputedStyle(target).paddingTop,
Expand All @@ -268,6 +278,14 @@ export function scrollTo(el: Element, hash: string, smooth = false) {
}
}

function tryOffsetSelector(selector: string): number {
const el = document.querySelector(selector)
if (!el) return 0
const bot = el.getBoundingClientRect().bottom
if (bot < 0) return 0
return bot + 24
}

function handleHMR(route: Route): void {
// update route.data on HMR updates of active page
if (import.meta.hot) {
Expand Down
6 changes: 5 additions & 1 deletion src/node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,12 @@ export interface UserConfig<ThemeConfig = any>
/**
* Configure the scroll offset when the theme has a sticky header.
* Can be a number or a selector element to get the offset from.
* Can also be an array of selectors in case some elements will be
* invisible due to responsive layout. VitePress will fallback to the next
* selector if a selector fails to match, or the matched element is not
* currently visible in viewport.
*/
scrollOffset?: number | string
scrollOffset?: number | string | string[]

/**
* Enable MPA / zero-JS mode.
Expand Down
2 changes: 1 addition & 1 deletion types/shared.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export interface SiteData<ThemeConfig = any> {
head: HeadConfig[]
appearance: boolean | 'dark'
themeConfig: ThemeConfig
scrollOffset: number | string
scrollOffset: number | string | string[]
locales: LocaleConfig<ThemeConfig>
localeIndex?: string
}
Expand Down

0 comments on commit 86e2a6f

Please sign in to comment.