fix(theme): Update sidebar on mount and route change

Ensures the sidebar link visibility is maintained not only on page load, but also when the route changes.
pull/3901/head
Breno A. 1 year ago
parent 4dc53c0f55
commit 4591b450f1

@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useScrollLock } from '@vueuse/core' import { useScrollLock } from '@vueuse/core'
import { inBrowser } from 'vitepress' import { inBrowser, useRoute } from 'vitepress'
import { nextTick, onMounted, ref, watch } from 'vue' import { nextTick, onMounted, ref, watch } from 'vue'
import { useSidebar } from '../composables/sidebar' import { useSidebar } from '../composables/sidebar'
import VPSidebarItem from './VPSidebarItem.vue' import VPSidebarItem from './VPSidebarItem.vue'
@ -14,6 +14,7 @@ const props = defineProps<{
// a11y: focus Nav element when menu has opened // a11y: focus Nav element when menu has opened
const navEl = ref<HTMLElement | null>(null) const navEl = ref<HTMLElement | null>(null)
const isLocked = useScrollLock(inBrowser ? document.body : null) const isLocked = useScrollLock(inBrowser ? document.body : null)
const route = useRoute()
watch( watch(
[props, navEl], [props, navEl],
@ -30,15 +31,26 @@ function scrollActiveLinkIntoView() {
const activeLink = navEl.value?.querySelector('.is-active') const activeLink = navEl.value?.querySelector('.is-active')
if (!activeLink) return if (!activeLink) return
const rect = activeLink.getBoundingClientRect() const rect = activeLink.getBoundingClientRect()
const isInViewPort = rect.top >= 0 && rect.bottom <= innerHeight const isInViewPort = rect.top >= 65 && rect.bottom <= innerHeight
if (!isInViewPort) { if (!isInViewPort) {
activeLink.scrollIntoView({ block: 'center' }) activeLink.scrollIntoView({ block: 'center' })
} }
} }
onMounted(() => { function handleScroll() {
nextTick(() => scrollActiveLinkIntoView()) nextTick(() => scrollActiveLinkIntoView())
}) }
onMounted(handleScroll)
watch([props, navEl, route], () => {
if (props.open) {
isLocked.value = true
navEl.value?.focus()
} else isLocked.value = false
handleScroll()
}, { immediate: true, flush: 'post' })
</script> </script>
<template> <template>

Loading…
Cancel
Save