Skip to content

Commit

Permalink
fix(theme): deep watch sidebar groups and force render on match change
Browse files Browse the repository at this point in the history
closes vuejs#3613
  • Loading branch information
brc-dd committed Jul 2, 2024
1 parent 387acf7 commit 97f9469
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 22 deletions.
37 changes: 18 additions & 19 deletions src/client/theme-default/components/VPSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useScrollLock } from '@vueuse/core'
import { inBrowser } from 'vitepress'
import { ref, watch } from 'vue'
import { useSidebar } from '../composables/sidebar'
import VPSidebarItem from './VPSidebarItem.vue'
import VPSidebarGroup from './VPSidebarGroup.vue'
const { sidebarGroups, hasSidebar } = useSidebar()
Expand All @@ -25,6 +25,16 @@ watch(
},
{ immediate: true, flush: 'post' }
)
const key = ref(0)
watch(
sidebarGroups,
() => {
key.value += 1
},
{ deep: true }
)
</script>

<template>
Expand All @@ -37,17 +47,18 @@ watch(
>
<div class="curtain" />

<nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1">
<nav
class="nav"
id="VPSidebarNav"
aria-labelledby="sidebar-aria-label"
tabindex="-1"
>
<span class="visually-hidden" id="sidebar-aria-label">
Sidebar Navigation
</span>

<slot name="sidebar-nav-before" />

<div v-for="item in sidebarGroups" :key="item.text" class="group">
<VPSidebarItem :item="item" :depth="0" />
</div>

<VPSidebarGroup :items="sidebarGroups" :key="key" />
<slot name="sidebar-nav-after" />
</nav>
</aside>
Expand Down Expand Up @@ -122,16 +133,4 @@ watch(
.nav {
outline: 0;
}
.group + .group {
border-top: 1px solid var(--vp-c-divider);
padding-top: 10px;
}
@media (min-width: 960px) {
.group {
padding-top: 10px;
width: calc(var(--vp-sidebar-width) - 64px);
}
}
</style>
56 changes: 56 additions & 0 deletions src/client/theme-default/components/VPSidebarGroup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script setup lang="ts">
import type { DefaultTheme } from 'vitepress/theme'
import { onBeforeUnmount, onMounted, ref } from 'vue'
import VPSidebarItem from './VPSidebarItem.vue'
defineProps<{
items: DefaultTheme.SidebarItem[]
}>()
const disableTransition = ref(true)
let timer: ReturnType<typeof setTimeout> | null = null
onMounted(() => {
timer = setTimeout(() => {
timer = null
disableTransition.value = false
}, 300)
})
onBeforeUnmount(() => {
if (timer != null) {
clearTimeout(timer)
timer = null
}
})
</script>

<template>
<div
v-for="item in items"
:key="item.text"
class="group"
:class="{ 'no-transition': disableTransition }"
>
<VPSidebarItem :item="item" :depth="0" />
</div>
</template>

<style scoped>
.no-transition :deep(.caret-icon) {
transition: none;
}
.group + .group {
border-top: 1px solid var(--vp-c-divider);
padding-top: 10px;
}
@media (min-width: 960px) {
.group {
padding-top: 10px;
width: calc(var(--vp-sidebar-width) - 64px);
}
}
</style>
6 changes: 3 additions & 3 deletions src/client/theme-default/components/VPSidebarItem.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed } from 'vue'
import type { DefaultTheme } from 'vitepress/theme'
import { computed } from 'vue'
import { useSidebarControl } from '../composables/sidebar'
import VPLink from './VPLink.vue'
Expand All @@ -27,8 +27,8 @@ const textTag = computed(() => {
return !hasChildren.value
? 'p'
: props.depth + 2 === 7
? 'p'
: `h${props.depth + 2}`
? 'p'
: `h${props.depth + 2}`
})
const itemRole = computed(() => (isLink.value ? undefined : 'button'))
Expand Down

0 comments on commit 97f9469

Please sign in to comment.