Files
irth-new-client-120/src/components/InteriorSlider.tsx
T
2025-08-04 17:00:27 +05:00

82 lines
2.5 KiB
TypeScript

import { useState } from "react";
import Button from "./ui/Button";
import ChevronLeftIcon from "./icons/ChevronLeftIcon";
import ChevronRightIcon from "./icons/ChevronRightIcon";
import { projects } from "../data/projects";
import { motion } from "motion/react";
import { useSwipeable } from "react-swipeable";
export interface InteriorSliderProps {
unitTypeSlug: string;
projectSlug: string;
}
function InteriorSlider({ unitTypeSlug, projectSlug }: InteriorSliderProps) {
const images = projects
?.find((project) => project.slug === projectSlug)
?.types.find((type) => type.slug === unitTypeSlug)?.interiors;
const [currentIndex, setCurrentIndex] = useState(0);
const handlers = useSwipeable({
onSwipedLeft: () =>
images && setCurrentIndex(Math.min(currentIndex + 1, images.length - 1)),
onSwipedRight: () => setCurrentIndex(Math.max(currentIndex - 1, 0)),
preventScrollOnSwipe: true,
touchEventOptions: {
passive: false,
},
trackMouse: true,
});
if (!images) return null;
return (
<div className="group overflow-hidden relative h-full" {...handlers}>
<motion.div
className="flex h-full"
animate={{ x: `calc(-${currentIndex} * 100%)` }}
transition={{
duration: 0.5,
ease: "easeInOut",
}}
>
{images?.map((src, index) => (
<img
key={index}
src={src}
alt=""
className="size-full object-cover object-left flex-shrink-0 pointer-events-none"
/>
))}
</motion.div>
<Button
className="absolute 2xl:left-[2.778vw] left-10 top-1/2 -translate-y-1/2 max-md:hidden group-hover:opacity-100 opacity-0 transition-opacity duration-300"
disabled={currentIndex === 0}
variant="secondary"
onlyIcon
onClick={() => setCurrentIndex(Math.max(currentIndex - 1, 0))}
>
<div className="2xl:size-[1.389vw] size-5">
<ChevronLeftIcon />
</div>
</Button>
<Button
className="absolute 2xl:right-[2.778vw] right-10 top-1/2 -translate-y-1/2 max-md:hidden group-hover:opacity-100 2xl:opacity-0 transition-opacity duration-300"
disabled={currentIndex === images.length - 1}
variant="secondary"
onlyIcon
onClick={() =>
setCurrentIndex(Math.min(currentIndex + 1, images.length - 1))
}
>
<div className="2xl:size-[1.389vw] size-5">
<ChevronRightIcon />
</div>
</Button>
</div>
);
}
export default InteriorSlider;