storytellurx-v1/app/components/utils/scroll-progress-tracker.tsx
Elias Rhouzlane 91b337752a feat: enhance global background image and scrolling functionality
- Added a new filter to the GlobalBackgroundImageDisplay component for improved visual effects.
- Modified the PositionalScroller to update positions based on clicked elements, enhancing user interaction.
- Updated ScrollProgressTracker to allow scrolling effects to be applied to the body.
- Removed the deprecated use-field-sizing utility and replaced it with a more robust implementation.
- Improved persona styles for better layout and responsiveness in chat interfaces.
- Integrated a new ScrollArea component for better scroll handling in UI.
- Updated index and layout pages to reflect new components and improved structure.
- Added new dependencies for Radix UI components to enhance UI capabilities.
2025-06-30 19:42:05 +02:00

53 lines
1.6 KiB
TypeScript

"use client";
import { useEffect, useRef } from "react";
import { Slot } from "@radix-ui/react-slot";
export const ScrollProgressTracker: React.FC<
React.HTMLAttributes<HTMLDivElement> & {
ref?: React.RefObject<HTMLDivElement | null> | null;
asChild?: boolean;
applyOnBody?: boolean;
}
> = ({ asChild, applyOnBody, ref, ...props }) => {
const innerRef = useRef<HTMLDivElement>(null);
const slotRef = ref ?? innerRef;
useEffect(() => {
let lastScrollTop = 0;
const epsilon = 6;
let scrolling = false;
const handleScroll = () => {
const targetElement = applyOnBody
? document.documentElement
: slotRef.current;
if (!targetElement || !slotRef.current) return;
const currentScrollTop = slotRef.current?.scrollTop;
const scrollDifference = currentScrollTop - lastScrollTop;
targetElement.style.setProperty(
"--scroll-top",
`${currentScrollTop}px`,
);
if (Math.abs(scrollDifference) > epsilon && !scrolling) {
targetElement.dataset.scrollDirection = currentScrollTop > lastScrollTop
? "down"
: "up";
scrolling = true;
setTimeout(() => scrolling = false, 420);
}
lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop;
};
slotRef.current?.addEventListener("scroll", handleScroll);
return () => {
slotRef.current?.removeEventListener("scroll", handleScroll);
};
}, [applyOnBody]);
const Comp = asChild ? Slot : "div";
return <Comp {...props} ref={slotRef} />;
};
export default ScrollProgressTracker;