@kadoui/react
Version:
Kadoui primitive components for React
53 lines (52 loc) • 2.14 kB
JavaScript
"use client";
import { jsx as _jsx } from "react/jsx-runtime";
import { useEffect, useRef, useState } from "react";
import { CarouselContext } from "./CarouselContext";
export function CarouselRoot({ dir, ...p }) {
const scrollRef = useRef(null);
const [leftOpacity, setLeftOpacity] = useState(0);
const [rightOpacity, setRightOpacity] = useState(0);
const [childrenWidth, setChildrenWidth] = useState(0);
const updateFade = () => {
const el = scrollRef.current;
if (!el)
return;
const { scrollLeft, scrollWidth, clientWidth } = el;
const maxScroll = scrollWidth - clientWidth;
if (maxScroll <= 0) {
setLeftOpacity(0);
setRightOpacity(0);
return;
}
const scrollRatio = Math.abs(+(scrollLeft / maxScroll));
const left = +Math.min(1, scrollRatio * 2).toFixed(1);
const right = +Math.min(1, (1 - scrollRatio) * 2).toFixed(1);
const currentDir = (dir ||
document.documentElement.getAttribute("dir") ||
"ltr");
setLeftOpacity(currentDir === "ltr" ? right : left);
setRightOpacity(currentDir === "ltr" ? left : right);
};
useEffect(() => {
const el = scrollRef.current;
if (!el)
return;
// Finding children width
const children = Array.from(el.querySelectorAll(".carousel-children"));
const sumChildrenWidth = children
.map((child) => child.scrollWidth)
.reduce((acc, cur) => {
return acc + cur;
}, 0);
const findedChildrenWidth = sumChildrenWidth / children.length;
setChildrenWidth(findedChildrenWidth);
updateFade();
el.addEventListener("scroll", updateFade);
window.addEventListener("resize", updateFade);
return () => {
el.removeEventListener("scroll", updateFade);
window.removeEventListener("resize", updateFade);
};
}, []);
return (_jsx(CarouselContext, { value: { scrollRef, leftOpacity, rightOpacity, childrenWidth }, children: _jsx("div", { ...p }) }));
}