Files
IRTH/client/src/components/favoritesPage/FavoriteSlider.tsx
T
2024-06-14 13:54:55 +05:00

117 lines
3.3 KiB
TypeScript

import { useState, useRef, useEffect } from "react";
import { ILayoutCard } from "../../types/layoutCard";
import FavoriteSliderCard from "./FavoriteSliderCard";
import Button from "../Button";
import RightArrowIcon from "../icons/RightArrowIcon";
import LeftArrowIcon from "../icons/LeftArrowIcon";
import { useSwipeable } from "react-swipeable";
interface FavoritesSliderProps {
cards: ILayoutCard[];
}
const FavoritesSlider = ({ cards }: FavoritesSliderProps) => {
const [offset, setOffset] = useState(0);
const cardRef = useRef<HTMLDivElement | null>(null);
const [cardWidth, setCardWidth] = useState(0);
const [buttonTopPos, setButtonTopPos] = useState(0);
const [cols, setCols] = useState(2);
const handlers = useSwipeable({
trackMouse: true,
onSwipedRight: () => handleOnLeftBtnClick(),
onSwipedLeft: () => handleOnRightBtnClick(),
});
const handleOnLeftBtnClick = () => {
if (0 > offset) {
setOffset((prev) => prev + 1);
}
};
const handleOnRightBtnClick = () => {
if (offset > -cards.length + cols + 1) {
setOffset((prev) => prev - 1);
}
};
useEffect(() => {
const screenWidth = window.innerWidth;
if (screenWidth >= 1024) {
setCols(4);
} else {
setCols(2);
}
}, [window.innerWidth]);
useEffect(() => {
const cardElement = cardRef.current;
if (cardElement) {
const gap = 16;
const width = cardElement.clientWidth + gap;
const buttonHeight = cardElement.clientHeight;
const _buttonTopPos = buttonHeight / 2 + 20;
setCardWidth(width);
setButtonTopPos(_buttonTopPos);
}
}, [cardRef.current]);
return (
<div className="w-[calc(100vw - 48px)] relative ">
<div
className="absolute -left-2 z-30"
style={{ top: `${buttonTopPos}px` }}
>
<Button
buttonType="primary"
isCircleRounded
icon={<LeftArrowIcon />}
onClick={handleOnLeftBtnClick}
/>
</div>
<div
className="absolute -right-2 z-30"
style={{ top: `${buttonTopPos}px` }}
>
<Button
buttonType="primary"
isCircleRounded
icon={<RightArrowIcon />}
onClick={handleOnRightBtnClick}
/>
</div>
<div className="w-full overflow-hidden" {...handlers}>
<div
className="transition-all ease-in-out duration-300"
style={{ transform: `translateX(${offset * cardWidth}px)` }}
>
<div className="flex w-fit gap-4">
{Array.from({ length: Math.floor(cards.length / cols) }).map(
(_, index) => {
return (
<div
className="grid lg:grid-cols-4 grid-cols-2 gap-4 w-[calc(100vw-48px)] h-fit"
key={index}
>
{cards
.slice(index * cols, cols + index * cols)
.map((card) => (
<FavoriteSliderCard
elementRef={cardRef}
card={card}
key={card.id}
/>
))}
</div>
);
}
)}
</div>
</div>
</div>
</div>
);
};
export default FavoritesSlider;