import React, { ReactElement, useEffect, useRef, useState } from 'react'; import css from '../../../utils/css'; import { CommonProps } from '../../common'; import { SliderTooltip, SliderRail, SliderTrack, SliderContainer, SliderThumb, } from '../StyledSlider'; import { preventKeyboardScrolling, getValueByMouseEvent, getValueByKeyboard, useSliderData, removeListener, addListener, } from '../utils'; import { useResizeObserver } from '../../../utils/hooks'; export interface SingleSliderProps extends CommonProps { /** * Whether the slider's tooltip is always shown. */ alwaysShowTooltip?: boolean; /** * Custom text for tooltip. If defined, it will replace the auto generated tooltip. */ customTooltipText?: string; /** * Whether the slider is disabled. */ disabled?: boolean; /** * Slider max value. */ max?: number; /** * Slider min value. */ min?: number; /** * onChange event handler. */ onChange?: (value: number) => void; /** * Slider step. */ step?: number; /** * Current slider's value. */ value: number; } const SingleSlider = ({ min = 0, max = 100, step = 1, value, disabled, alwaysShowTooltip, customTooltipText, id, className, style, sx = {}, 'data-test-id': dataTestId, onChange, }: SingleSliderProps): ReactElement => { const refSlider = useRef(null); const { valueInNumber, valueInPercent } = useSliderData({ min, max, value }); const toolTip = customTooltipText !== undefined ? customTooltipText : valueInNumber; const [labelId] = useState(`tooltip_${Date.now().toString()}`); const [railWidth, setRailWidth] = useState(0); const [railOffsetLeft, setRailOffsetLeft] = useState(0); const onKeyDown = (e: React.KeyboardEvent): void => { preventKeyboardScrolling(e); if (disabled !== true && onChange !== undefined) { const newValueInNumber = getValueByKeyboard( valueInNumber, step, min, max, e.key ); if (onChange !== undefined) { onChange(newValueInNumber); } } }; const onMouseMove = (e: Event): void => { e.stopPropagation(); const newValueInNumber = getValueByMouseEvent( e, railWidth, railOffsetLeft, min, max, step ); if (onChange !== undefined) { onChange(newValueInNumber); } }; const onClickSlider = (e: React.MouseEvent | Event): void => onMouseMove(e as Event); const onTouchStart = (e: React.TouchEvent): void => { e.stopPropagation(); const onMouseUp = removeListener(onMouseMove); addListener(onMouseMove, onMouseUp); }; const onMouseDown = (e: React.MouseEvent): void => { e.stopPropagation(); const onMouseUp = removeListener(onMouseMove); addListener(onMouseMove, onMouseUp); }; const updateSliderDimension = (): void => { const { current } = refSlider; if (current !== null) { const { width } = current.getBoundingClientRect(); const offsetLeft = current.getBoundingClientRect().x; setRailWidth(width); setRailOffsetLeft(offsetLeft); } }; useResizeObserver(updateSliderDimension, refSlider.current); useEffect(updateSliderDimension, [refSlider]); return ( {toolTip} ); }; export default SingleSlider;