About Marasi Drive Table Mobile

This commit is contained in:
2025-07-18 17:25:10 +05:00
parent 8bbb4413b0
commit a68d001ef9
7 changed files with 222 additions and 29 deletions
+78
View File
@@ -0,0 +1,78 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useState } from "react";
import useWindowSize from "../../hooks/useWindowSize";
interface CustomScrollBarProps {
containerRef: React.RefObject<HTMLElement | null>;
inlinePadding: number;
trackStyle?: string;
thumbStyle?: string;
}
function CustomScrollBar({
containerRef,
inlinePadding,
trackStyle = "",
thumbStyle = "",
}: CustomScrollBarProps) {
const [scrollLeft, setScrollLeft] = useState<number>(0);
const [totalWidth, setTotalWidth] = useState<number>(0);
const [containerWidth, setContainerWidth] = useState<number>(0);
const [thumbVisible, setThumbVisible] = useState<boolean>(false);
const windowSize = useWindowSize();
function GetContainer(): HTMLElement {
if (!containerRef.current) {
throw new Error("Container reference is not valid");
}
return containerRef.current;
}
useEffect(() => {
setTotalWidth(GetContainer().scrollWidth);
setContainerWidth(GetContainer().clientWidth);
}, [windowSize]);
useEffect(() => {
const container = GetContainer();
let hideThumbTimeout: ReturnType<typeof setTimeout> | null = null;
function handleContainerScroll() {
setScrollLeft(container.scrollLeft);
if (!thumbVisible) setThumbVisible(true);
if (hideThumbTimeout) clearTimeout(hideThumbTimeout);
hideThumbTimeout = setTimeout(() => {
setThumbVisible(false);
}, 750);
}
container.addEventListener("scroll", handleContainerScroll);
return () => {
container.removeEventListener("scroll", handleContainerScroll);
};
}, [containerRef]);
const scrollPercent =
totalWidth > containerWidth
? (scrollLeft / (totalWidth - containerWidth)) * 100
: 0;
const thumbPosition =
(scrollPercent / 100) * (containerWidth - 20 - inlinePadding * 2); // 20px - ширина ползунка
return (
<div
className={`relative h-1 w-full bg-transparent rounded-full ${trackStyle}`}
>
<div
className={`absolute w-5 h-1 bg-[#E2E2DC] rounded-full transition-opacity duration-250 ease-out ${
thumbVisible ? "opacity-100" : "opacity-0"
} ${thumbStyle}`}
style={{ transform: `translateX(${thumbPosition}px)` }}
/>
</div>
);
}
export default CustomScrollBar;