diff --git a/app/pages/package-docs/[...path].vue b/app/pages/package-docs/[...path].vue index 37cf258219..d40e28d819 100644 --- a/app/pages/package-docs/[...path].vue +++ b/app/pages/package-docs/[...path].vue @@ -138,6 +138,40 @@ const stickyStyle = computed(() => { '--combined-header-height': `${56 + (packageHeaderHeight.value || 44)}px`, } }) + +// Track active TOC item based on URL hash +const tocContainerRef = useTemplateRef('tocContainerRef') + +function updateActiveTocLink() { + const container = tocContainerRef.value + if (!container) return + + const hash = window.location.hash + + container.querySelector('a.toc-active')?.classList.remove('toc-active') + + if (hash) { + const link = container.querySelector(`a[href="#${CSS.escape(hash.slice(1))}"]`) + link?.classList.add('toc-active') + } +} + +function onTocClick(e: Event) { + const link = (e.target as HTMLElement).closest('a[href^="#"]') + if (link) { + nextTick(updateActiveTocLink) + } +} + +if (import.meta.client) { + watch( + () => docsData.value?.toc, + () => nextTick(updateActiveTocLink), + ) + + onMounted(updateActiveTocLink) + useEventListener(window, 'hashchange', updateActiveTocLink) +}