File size: 2,225 Bytes
ec4551b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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>
  );
};