import React, { useEffect, useState, useRef } from 'react'; import { fromEvent, Subscription } from 'rxjs'; import { throttleTime } from 'rxjs/operators'; import { OuterWrapper, Wrapper, Rail, Track } from './styled'; type Props = { color?: 'primary' | 'secondary'; minimum?: number; maximum?: number; defaultValue?: number; value?: number; disabled?: boolean; onChange?: (value: number) => void; }; const Sliders: React.FC = ({ defaultValue = 0, value = 0, onChange, // minimum = 0, maximum = 100, }: Props) => { const sliderRef = useRef(null); const [valueState, setValueState] = useState(defaultValue); const [isActive, setActive] = useState(false); let mouseSubscription: Subscription | null = null; let touchSubscription: Subscription | null = null; const parseValueToPercent = (val: number): number => Math.floor(val * 100); // eslint-disable-next-line @typescript-eslint/no-explicit-any const getFingerMoveValue = (event: any): void => { const { current: slider } = sliderRef; let clientX = 0; if (event.touches) { const touches = event.touches[0]; ({ clientX } = touches); } else { ({ clientX } = event); } if (slider) { const { width, left } = slider.getBoundingClientRect(); const moveDistance = clientX - left; const moveRate = moveDistance / width; let percent = parseValueToPercent(moveRate); if (percent <= 0) { percent = 0; } else if (percent >= 100) { percent = 100; } if (onChange) { const val = Math.floor(percent * (maximum * 0.01)); onChange(val); } } }; const handleTouchMove = (event: Event): void => { event.preventDefault(); getFingerMoveValue(event); }; const handleTouchEnd = (event: MouseEvent): void => { event.preventDefault(); setActive(false); if (mouseSubscription) mouseSubscription.unsubscribe(); if (touchSubscription) touchSubscription.unsubscribe(); }; const handleMouseDown = ( event: React.MouseEvent | React.TouchEvent, ): void => { event.preventDefault(); getFingerMoveValue(event); setActive(true); mouseSubscription = fromEvent(document.body, 'mousemove') .pipe(throttleTime(35)) .subscribe(handleTouchMove); touchSubscription = fromEvent(document.body, 'touchmove') .pipe(throttleTime(35)) .subscribe(handleTouchMove); document.body.addEventListener('mouseup', handleTouchEnd); }; const setPercent = (): void => { const percent = parseValueToPercent((defaultValue || value) / maximum); setValueState(percent); }; useEffect(() => { setPercent(); }, []); useEffect(() => { setPercent(); }, [value]); return ( ); }; export default Sliders;