import classNames from 'classnames' import { ChangeEvent, useRef, useState } from 'react' import Draggable from 'react-draggable' import { OverlayMark } from 'components/Icons/index' import useToggle from 'hooks/useToggle' type Props = { value: number onChange: (value: number) => void className?: string disabled?: boolean } export default function Slider(props: Props) { const [showTooltip, setShowTooltip] = useToggle() const [sliderRect, setSliderRect] = useState({ width: 0, left: 0, right: 0 }) const ref = useRef(null) const nodeRef = useRef(null) const [isDragging, setIsDragging] = useToggle() function handleSliderRect() { const leftCap = ref.current?.getBoundingClientRect().left ?? 0 const rightCap = ref.current?.getBoundingClientRect().right ?? 0 const newSliderWidth = ref.current?.getBoundingClientRect().width ?? 0 if ( sliderRect.width !== newSliderWidth || leftCap !== sliderRect.left || rightCap !== sliderRect.right ) { setSliderRect({ left: leftCap, right: rightCap, width: newSliderWidth, }) } } function handleDrag(e: any) { if (!isDragging) { setIsDragging(true) } const current: number = e.clientX if (current < sliderRect.left) { props.onChange(0) return } if (current > sliderRect.right) { props.onChange(100) return } const value = Math.round(((current - sliderRect.left) / sliderRect.width) * 100) if (value !== props.value) { props.onChange(value) } } function handleSliderClick(e: ChangeEvent) { props.onChange(Number(e.target.value)) } function handleShowTooltip() { setShowTooltip(true) } function handleHideTooltip() { setShowTooltip(false) } const DraggableElement: any = Draggable return (
{!props.disabled && (
setIsDragging(false)} position={{ x: (sliderRect.width / 100) * props.value, y: 0 }} >
{(showTooltip || isDragging) && (
{props.value.toFixed(0)}%
)}
)}
) } interface MarkProps { value: number sliderValue: number onClick: (value: number) => void disabled?: boolean } function Mark(props: MarkProps) { return ( ) } interface TrackProps { maxValue: number sliderValue: number } function Track(props: TrackProps) { const minValue = props.maxValue - 21 let percentage = 0 if (props.sliderValue >= props.maxValue) percentage = 100 if (props.sliderValue > minValue && props.sliderValue < props.maxValue) { percentage = ((props.sliderValue - minValue) / (props.maxValue - minValue)) * 100 } return (
) }