File size: 2,622 Bytes
ac4a6d6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import * as React from 'react';
import * as SliderPrimitive from '@radix-ui/react-slider';
import { cn } from '../lib/utils';

interface SliderProps {
  value: number[];
  onValueChange: (value: number[]) => void;
  min?: number;
  max?: number;
  step?: number;
  className?: string;
}

export function Slider({ value, onValueChange, min = 0, max = 5, step = 1, className }: SliderProps) {
  const marks = React.useMemo(() => {
    const result = [];
    for (let i = min; i <= max; i += step) {
      result.push(i);
    }
    return result;
  }, [min, max, step]);

  return (
    <div className="relative pt-2 pb-8 w-full">
      <SliderPrimitive.Root
        className={cn(
          "relative flex w-full touch-none select-none items-center cursor-pointer group",
          className
        )}
        value={value}
        onValueChange={onValueChange}
        min={min}
        max={max}
        step={step}
      >
        <SliderPrimitive.Track className="relative h-2 w-full grow rounded-full bg-gray-200/80 dark:bg-gray-800/80 overflow-hidden shadow-inner">
          <SliderPrimitive.Range className="absolute h-full rounded-full bg-gradient-to-r from-blue-500 via-indigo-500 to-purple-600 transition-all duration-150" />
        </SliderPrimitive.Track>
        <SliderPrimitive.Thumb
          className="block h-5 w-5 rounded-full border-2 border-white bg-gradient-to-tr from-blue-600 to-purple-600 shadow-lg shadow-blue-500/30 transition-transform duration-150 hover:scale-125 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-blue-500/30 disabled:pointer-events-none disabled:opacity-50 dark:border-gray-900"
          aria-label="Redaction Level Slider"
        />
      </SliderPrimitive.Root>

      <div className="absolute left-0 right-0 -bottom-1 flex justify-between px-0.5">
        {marks.map((mark) => (
          <div
            key={mark}
            className="flex flex-col items-center group/mark cursor-pointer"
            onClick={() => onValueChange([mark])}
          >
            <div className={cn(
              "w-0.5 h-2.5 transition-colors mb-1 rounded-full",
              value[0] >= mark ? "bg-purple-500 dark:bg-purple-400 font-bold" : "bg-gray-300 dark:bg-gray-700"
            )} />
            <span className={cn(
              "text-xs transition-all font-medium",
              value[0] === mark
                ? "text-purple-600 dark:text-purple-400 font-extrabold scale-110"
                : "text-gray-500 dark:text-gray-400"
            )}>
              L{mark}
            </span>
          </div>
        ))}
      </div>
    </div>
  );
}