shadcn-docs-nuxt
Version:
Effortless and beautiful docs template built with Nuxt Content & shadcn-vue.
52 lines (43 loc) • 1.26 kB
text/typescript
// Credit: nuxt-themes/docus
/**
* Scrollspy allows you to watch visible headings in a specific page.
* Useful for table of contents live style updates.
*/
export function useScrollspy() {
const observer = ref() as Ref<IntersectionObserver>;
const visibleHeadings = ref([]) as Ref<string[]>;
const activeHeadings = ref([]) as Ref<string[]>;
const observerCallback = (entries: IntersectionObserverEntry[]) =>
entries.forEach((entry) => {
const id = entry.target.id;
if (entry.isIntersecting)
visibleHeadings.value.push(id);
else visibleHeadings.value = visibleHeadings.value.filter(t => t !== id);
});
const updateHeadings = (headings: Element[]) => {
if (observer.value)
observer.value.disconnect();
observer.value = new IntersectionObserver(observerCallback);
headings.forEach((heading) => {
observer.value.observe(heading);
});
};
watch(
visibleHeadings,
(val, oldVal) => {
if (val.length === 0)
activeHeadings.value = oldVal;
else
activeHeadings.value = val;
},
{ deep: true },
);
onBeforeUnmount(() => {
observer.value?.disconnect();
});
return {
visibleHeadings,
activeHeadings,
updateHeadings,
};
}