index.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import React, { useEffect, useState, useRef, useCallback } from 'react';
  2. import { Container, Wrapper, Rail, Track } from './styled';
  3. type Props = {
  4. color?: 'primary' | 'secondary';
  5. max?: number;
  6. min?: number;
  7. defaultValue?: number;
  8. disabled?: boolean;
  9. onChange?: (value: number | number[]) => void;
  10. };
  11. const Sliders : React.FunctionComponent<Props> = ({
  12. defaultValue = 0,
  13. onChange,
  14. }) => {
  15. const sliderRef = useRef<HTMLDivElement>(null);
  16. const [valueState, setValueState] = useState(defaultValue);
  17. const [isActive, setActive] = useState(false);
  18. const parseValueToPercent = (value: number): number => {
  19. return Math.floor(value * 100);
  20. }
  21. const getFingerMoveValue = (event: MouseEvent | React.MouseEvent<HTMLElement>) => {
  22. const { current: slider } = sliderRef;
  23. if (slider) {
  24. const { width, left } = slider.getBoundingClientRect();
  25. const value = (event.clientX - left) / width;
  26. let percent = parseValueToPercent(value);
  27. if (percent <= 0) {
  28. percent = 0
  29. } else if (percent >= 100) {
  30. percent = 100
  31. }
  32. setValueState(percent);
  33. onChange && onChange(percent);
  34. }
  35. };
  36. const handleTouchMove = useCallback((event: MouseEvent) => {
  37. event.preventDefault();
  38. getFingerMoveValue(event);
  39. }, []);
  40. const handleTouchEnd = useCallback((event: MouseEvent) => {
  41. event.preventDefault();
  42. setActive(false);
  43. document.body.removeEventListener('mousemove', handleTouchMove);
  44. }, []);
  45. const handleMouseDown = useCallback((event: React.MouseEvent<HTMLElement>) => {
  46. event.preventDefault();
  47. getFingerMoveValue(event);
  48. setActive(true);
  49. document.body.addEventListener('mousemove', handleTouchMove);
  50. document.body.addEventListener('mouseup', handleTouchEnd);
  51. }, []);
  52. useEffect(() => {
  53. setValueState(defaultValue);
  54. }, []);
  55. return (
  56. <Container>
  57. <Wrapper
  58. ref={sliderRef}
  59. onMouseDown={handleMouseDown}
  60. >
  61. <Rail track={valueState} />
  62. <Track
  63. track={valueState}
  64. isActive={isActive}
  65. />
  66. </Wrapper>
  67. </Container>
  68. );
  69. };
  70. export default Sliders;