File size: 2,723 Bytes
d092f57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import styles from "./InputSlider.module.css"
import React, {
  CSSProperties,
  FC,
  MouseEventHandler,
  TouchEventHandler,
  useState,
} from "react"
import classNames from "classnames"
import { Tooltip } from "react-tooltip"
import { secondsToTime } from "../../lib/utils"

interface Props {
  min?: number
  max?: number
  step?: number
  value: number
  onChange: (value: number) => void
  className?: string
  setSeeking?: (seeking: boolean) => void
  showValueHover?: boolean
}

const InputSlider: FC<Props> = ({
  min = 0,
  max = 1,
  step = 0.001,
  value,
  onChange,
  className = "",
  setSeeking,
  showValueHover = false,
}) => {
  const [hoverValue, setHoverValue] = useState(0)
  const [time, setTime] = useState(secondsToTime(hoverValue))

  if (min < 0) {
    console.error("Slider with min value below 0:", min)
    return <></>
  }

  const valueStyle = {
    "--value": (value / (max - min)) * 100 + "%",
  }

  const startSeek:
    | MouseEventHandler<HTMLInputElement>
    | TouchEventHandler<HTMLInputElement> = () => {
    if (setSeeking) {
      setSeeking(true)
    }
  }

  const stopSeek:
    | MouseEventHandler<HTMLInputElement>
    | TouchEventHandler<HTMLInputElement> = () => {
    if (setSeeking) {
      setSeeking(false)
    }
  }

  const calcSliderPos = (e: React.MouseEvent<HTMLInputElement>) => {
    const target = e.target as HTMLInputElement
    return (e.nativeEvent.offsetX / target.clientWidth) * max
  }

  return (
    <div
      className={classNames(styles.slider, "flex px-1 items-center", className)}
    >
      <input
        data-tooltip-content={""}
        id={"slider"}
        data-tooltip-variant={"dark"}
        type={"range"}
        min={min}
        max={max}
        step={step}
        value={value}
        onMouseMove={(event) => {
          setHoverValue(calcSliderPos(event))
          setTime(secondsToTime(calcSliderPos(event)))
        }}
        onMouseDown={startSeek as MouseEventHandler}
        onTouchStart={startSeek as TouchEventHandler}
        onMouseUp={stopSeek as MouseEventHandler}
        onTouchEnd={stopSeek as TouchEventHandler}
        onChange={(event) => {
          const v = parseFloat(event.target.value)
          event.target.style.setProperty(
            "--value",
            (v / (max - min)) * 100 + "%"
          )
          onChange(v)
        }}
        style={valueStyle as CSSProperties}
      />
      {showValueHover && (
        <Tooltip
          anchorId={"slider"}
          place={"top"}
          //arrowColor={"var(--dark-700)"}
          content={time}
          style={{
            backgroundColor: "var(--dark-700)",
          }}
        />
      )}
    </div>
  )
}

export default InputSlider