nimiq-vitepress-theme
Version:
Nimiq UI theme for VitePress
53 lines (52 loc) • 1.6 kB
JavaScript
import { useEventListener } from "@vueuse/core";
import { onMounted, onUnmounted, readonly, ref } from "vue";
export function useHeaderScroll(threshold = 10, hideDelay = 100) {
const isHeaderVisible = ref(true);
const scrollY = ref(0);
const lastScrollY = ref(0);
const scrollDirection = ref(null);
let hideTimeout = null;
const handleScroll = () => {
const currentScrollY = typeof window !== "undefined" ? window.scrollY : 0;
scrollY.value = currentScrollY;
if (currentScrollY <= 0) {
isHeaderVisible.value = true;
scrollDirection.value = null;
return;
}
const scrollDiff = currentScrollY - lastScrollY.value;
if (Math.abs(scrollDiff) < threshold) {
return;
}
const newDirection = scrollDiff > 0 ? "down" : "up";
if (hideTimeout) {
clearTimeout(hideTimeout);
hideTimeout = null;
}
if (newDirection === "up") {
isHeaderVisible.value = true;
scrollDirection.value = "up";
} else if (newDirection === "down") {
scrollDirection.value = "down";
hideTimeout = setTimeout(() => {
isHeaderVisible.value = false;
}, hideDelay);
}
lastScrollY.value = currentScrollY;
};
useEventListener("scroll", handleScroll, { passive: true });
onMounted(() => {
scrollY.value = window.scrollY;
lastScrollY.value = window.scrollY;
});
onUnmounted(() => {
if (hideTimeout) {
clearTimeout(hideTimeout);
}
});
return {
isHeaderVisible: readonly(isHeaderVisible),
scrollY: readonly(scrollY),
scrollDirection: readonly(scrollDirection)
};
}