postio / apps /frontend /src /components /third-parties /slider.component.tsx
Leon4gr45's picture
Upload folder using huggingface_hub (part 7)
ec4551b verified
Raw
History Blame Contribute Delete
2.23 kB
import { FC, ReactNode, useCallback, useState } from 'react';
import clsx from 'clsx';
import {
ChevronLeftIcon,
ChevronRightIcon,
} from '@gitroom/frontend/components/ui/icons';
export const SliderComponent: FC<{
className: string;
list: ReactNode[];
}> = ({ className, list }) => {
const [show, setShow] = useState(0);
const goToPrevious = useCallback(() => {
setShow((prev) => (prev > 0 ? prev - 1 : prev));
}, []);
const goToNext = useCallback(() => {
setShow((prev) => (prev < list.length - 1 ? prev + 1 : prev));
}, [list.length]);
const canGoPrevious = show > 0;
const canGoNext = show < list.length - 1;
return (
<div className={clsx(className, 'relative')}>
{list[show]}
{/* Left Arrow */}
{canGoPrevious && (
<button
onClick={goToPrevious}
className="absolute top-[50%] start-[10px] -translate-y-[50%] flex items-center justify-center w-8 h-8 rounded-full bg-black/60 hover:bg-black/80 text-white transition-colors backdrop-blur-sm cursor-pointer"
aria-label="Previous slide"
>
<ChevronLeftIcon size={18} />
</button>
)}
{/* Right Arrow */}
{canGoNext && (
<button
onClick={goToNext}
className="absolute top-[50%] end-[10px] -translate-y-[50%] flex items-center justify-center w-8 h-8 rounded-full bg-black/60 hover:bg-black/80 text-white transition-colors backdrop-blur-sm cursor-pointer"
aria-label="Next slide"
>
<ChevronRightIcon size={18} />
</button>
)}
{/* Pagination Dots */}
{list.length > 1 && (
<div className="absolute bottom-[10px] left-[50%] -translate-x-[50%] flex gap-2">
{list.map((_, index) => (
<button
key={index}
onClick={() => setShow(index)}
className={clsx(
'w-2 h-2 rounded-full transition-colors cursor-pointer',
index === show
? 'bg-white'
: 'bg-transparent border border-white'
)}
aria-label={`Go to slide ${index + 1}`}
/>
))}
</div>
)}
</div>
);
};