@itwin/itwinui-react
Version:
A react component library for iTwinUI
104 lines (103 loc) • 2.88 kB
JavaScript
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),
}),
);
};