UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

104 lines (103 loc) 2.88 kB
import * as React from 'react'; import cx from 'classnames'; import { Tooltip } from '../Tooltip/Tooltip.js'; import { Box, useMergedRefs } from '../../utils/index.js'; export const Thumb = (props) => { let { value, index, minVal, maxVal, step, sliderMin, sliderMax, isActive, onThumbActivated, onThumbValueChanged, tooltipProps, thumbProps, disabled, } = props; let thumbRef = React.useRef(null); let handleOnKeyboardEvent = React.useCallback( (event, keyboardReleased) => { if (disabled || event.altKey) return; switch (event.key) { case 'ArrowLeft': case 'ArrowDown': onThumbValueChanged( index, Math.max(value - step, minVal), keyboardReleased, ); break; case 'ArrowRight': case 'ArrowUp': onThumbValueChanged( index, Math.min(value + step, maxVal), keyboardReleased, ); break; case 'Home': onThumbValueChanged(index, minVal, keyboardReleased); break; case 'End': onThumbValueChanged(index, maxVal, keyboardReleased); break; default: return; } event.preventDefault(); }, [disabled, onThumbValueChanged, index, value, step, minVal, maxVal], ); let handlePointerDownOnThumb = React.useCallback(() => { disabled || onThumbActivated(index); }, [disabled, index, onThumbActivated]); let adjustedValue = React.useMemo(() => { if (value < sliderMin) return sliderMin; if (value > sliderMax) return sliderMax; return value; }, [sliderMax, sliderMin, value]); let lowPercent = React.useMemo(() => { if (sliderMax === sliderMin) return 0; return (100.0 * (adjustedValue - sliderMin)) / (sliderMax - sliderMin); }, [adjustedValue, sliderMax, sliderMin]); let { style, className, ...rest } = thumbProps || {}; return React.createElement( Tooltip, { placement: 'top', autoUpdateOptions: { animationFrame: true, }, ariaStrategy: 'none', ...tooltipProps, }, React.createElement(Box, { ...rest, ref: useMergedRefs(thumbRef, thumbProps?.ref), style: { ...style, '--iui-slider-thumb-position': `${lowPercent}%`, }, className: cx( 'iui-slider-thumb', { 'iui-active': isActive, }, className, ), role: 'slider', tabIndex: disabled ? void 0 : 0, 'aria-valuemin': minVal, 'aria-valuenow': value, 'aria-valuemax': maxVal, 'aria-disabled': disabled, onPointerDown: handlePointerDownOnThumb, onKeyDown: (event) => handleOnKeyboardEvent(event, false), onKeyUp: (event) => handleOnKeyboardEvent(event, true), }), ); };