index.tsx 2.1 KB

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