refactor(theme): improve headers active anchor (#258)

This commit is contained in:
pengzhanbo 2024-10-09 00:37:53 +08:00 committed by GitHub
parent 3fe7497df1
commit 7913caee50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 20 additions and 24 deletions

17
pnpm-lock.yaml generated
View File

@ -325,9 +325,6 @@ importers:
'@vuepress/helper':
specifier: 2.0.0-rc.52
version: 2.0.0-rc.52(typescript@5.6.2)(vuepress@2.0.0-rc.17(@vuepress/bundler-vite@2.0.0-rc.17(@types/node@20.12.10)(jiti@1.21.6)(sass-embedded@1.79.4)(sass@1.79.4)(typescript@5.6.2)(yaml@2.5.1))(typescript@5.6.2)(vue@3.5.10(typescript@5.6.2)))
'@vuepress/plugin-active-header-links':
specifier: 2.0.0-rc.52
version: 2.0.0-rc.52(typescript@5.6.2)(vuepress@2.0.0-rc.17(@vuepress/bundler-vite@2.0.0-rc.17(@types/node@20.12.10)(jiti@1.21.6)(sass-embedded@1.79.4)(sass@1.79.4)(typescript@5.6.2)(yaml@2.5.1))(typescript@5.6.2)(vue@3.5.10(typescript@5.6.2)))
'@vuepress/plugin-cache':
specifier: 2.0.0-rc.52
version: 2.0.0-rc.52(vuepress@2.0.0-rc.17(@vuepress/bundler-vite@2.0.0-rc.17(@types/node@20.12.10)(jiti@1.21.6)(sass-embedded@1.79.4)(sass@1.79.4)(typescript@5.6.2)(yaml@2.5.1))(typescript@5.6.2)(vue@3.5.10(typescript@5.6.2)))
@ -1778,11 +1775,6 @@ packages:
'@vuepress/markdown@2.0.0-rc.17':
resolution: {integrity: sha512-eIwRostE3t3zsJzPjmOufVyyBpsaWQkZluk6o0i1e9WLW3EoinKrDZdzej0Jw8IQlq6nvOPD2JMFWyXwu8fv7w==}
'@vuepress/plugin-active-header-links@2.0.0-rc.52':
resolution: {integrity: sha512-2QJbVTurvHuIAkO6YqXHoHkY6t4H6o0nktxbUjCiezkOGtiN2DHn4wpD2AFKjYstezIWDGbPianbBuGAZKr+aQ==}
peerDependencies:
vuepress: 2.0.0-rc.17
'@vuepress/plugin-cache@2.0.0-rc.52':
resolution: {integrity: sha512-CyRYVg32btWwW2mhzfY+zqgtXPqaMkJ6SRt5kL/SoKtPy6eh6qxz9Bu3bZzYA1+l8FPdln0sNNhL8+QCveUUYQ==}
peerDependencies:
@ -7100,15 +7092,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@vuepress/plugin-active-header-links@2.0.0-rc.52(typescript@5.6.2)(vuepress@2.0.0-rc.17(@vuepress/bundler-vite@2.0.0-rc.17(@types/node@20.12.10)(jiti@1.21.6)(sass-embedded@1.79.4)(sass@1.79.4)(typescript@5.6.2)(yaml@2.5.1))(typescript@5.6.2)(vue@3.5.10(typescript@5.6.2)))':
dependencies:
'@vueuse/core': 11.1.0(vue@3.5.10(typescript@5.6.2))
vue: 3.5.10(typescript@5.6.2)
vuepress: 2.0.0-rc.17(@vuepress/bundler-vite@2.0.0-rc.17(@types/node@20.12.10)(jiti@1.21.6)(sass-embedded@1.79.4)(sass@1.79.4)(typescript@5.6.2)(yaml@2.5.1))(typescript@5.6.2)(vue@3.5.10(typescript@5.6.2))
transitivePeerDependencies:
- '@vue/composition-api'
- typescript
'@vuepress/plugin-cache@2.0.0-rc.52(vuepress@2.0.0-rc.17(@vuepress/bundler-vite@2.0.0-rc.17(@types/node@20.12.10)(jiti@1.21.6)(sass-embedded@1.79.4)(sass@1.79.4)(typescript@5.6.2)(yaml@2.5.1))(typescript@5.6.2)(vue@3.5.10(typescript@5.6.2)))':
dependencies:
ci-info: 4.0.0

View File

@ -103,7 +103,6 @@
"@vuepress-plume/plugin-search": "workspace:*",
"@vuepress-plume/plugin-shikiji": "workspace:*",
"@vuepress/helper": "2.0.0-rc.52",
"@vuepress/plugin-active-header-links": "2.0.0-rc.52",
"@vuepress/plugin-cache": "2.0.0-rc.52",
"@vuepress/plugin-comment": "2.0.0-rc.53",
"@vuepress/plugin-docsearch": "2.0.0-rc.52",

View File

@ -1,7 +1,9 @@
import type { InjectionKey, Ref } from 'vue'
import type { Router } from 'vuepress/client'
import type { ThemeOutline } from '../../shared/index.js'
import { onContentUpdated } from '@vuepress-plume/plugin-content-update/client'
import { inject, onMounted, onUnmounted, onUpdated, provide, ref } from 'vue'
import { useRouter } from 'vuepress/client'
import { throttleAndDebounce } from '../utils/index.js'
import { useAside } from './aside.js'
import { useData } from './data.js'
@ -161,6 +163,7 @@ export function resolveHeaders(headers: MenuItem[], range?: ThemeOutline): MenuI
export function useActiveAnchor(container: Ref<HTMLElement | null>, marker: Ref<HTMLElement | null>): void {
const { isAsideEnabled } = useAside()
const router = useRouter()
let prevActiveLink: HTMLAnchorElement | null = null
@ -203,7 +206,7 @@ export function useActiveAnchor(container: Ref<HTMLElement | null>, marker: Ref<
// find the last header above the top of viewport
let activeLink: string | null = null
for (const { link, top } of headers) {
if (top > scrollY + 144)
if (top > scrollY + 88)
break
activeLink = link
@ -239,6 +242,8 @@ export function useActiveAnchor(container: Ref<HTMLElement | null>, marker: Ref<
marker.value.style.opacity = '0'
}
}
updateHash(router, hash || '')
}
const onScroll = throttleAndDebounce(setActiveLink, 100)
@ -273,3 +278,17 @@ function getAbsoluteTop(element: HTMLElement): number {
}
return offsetTop
}
/**
* Update current hash and do not trigger `scrollBehavior`
*/
async function updateHash(router: Router, hash: string): Promise<void> {
const { path, query } = router.currentRoute.value
const { scrollBehavior } = router.options
// temporarily disable `scrollBehavior`
router.options.scrollBehavior = undefined
await router.replace({ path, query, hash })
// restore it after navigation
router.options.scrollBehavior = scrollBehavior
}

View File

@ -1,6 +1,5 @@
import type { App, PluginConfig } from 'vuepress/core'
import type { PlumeThemePluginOptions } from '../../shared/index.js'
import { activeHeaderLinksPlugin } from '@vuepress/plugin-active-header-links'
import { cachePlugin } from '@vuepress/plugin-cache'
import { commentPlugin } from '@vuepress/plugin-comment'
import { docsearchPlugin } from '@vuepress/plugin-docsearch'
@ -44,10 +43,6 @@ export function getPlugins({
markdownTitlePlugin(),
fontsPlugin(),
contentUpdatePlugin(),
activeHeaderLinksPlugin({
headerLinkSelector: 'a.outline-link',
headerAnchorSelector: '.header-anchor',
}),
markdownHintPlugin({ hint: true, alert: true, injectStyles: false }),
...customContainerPlugins,