UNPKG

@atlaskit/range

Version:

A range lets users choose an approximate value on a slider.

75 lines (71 loc) 2.46 kB
import _extends from "@babel/runtime/helpers/extends"; import React, { forwardRef, useCallback, useState } from 'react'; import __noop from '@atlaskit/ds-lib/noop'; import { Input } from './styled'; // Combine omits the keys of the second from the first so in case of overlap the props of the second are used. // OwnProps is used for external documentation, but does not list every property supported by Range. // So we combine (a reduced list of) HTMLInputElement attributes with OwnProps to get the full type. const snapToStep = (value, min, step) => { // Normalise the value to allow for division properly with different min values const adjustedValue = value - min; // Find the number of steps the value covers const numSteps = Math.round(adjustedValue / step); // Convert numSteps back into original range return numSteps * step + min; }; const getRoundedPercentValue = (value, min, max, step) => { let percent = '0'; if (min < max && value > min) { const snappedValue = snapToStep(value, min, step); percent = ((snappedValue - min) / (max - min) * 100).toFixed(2); } return percent; }; const noop = __noop; /** * __Range__ * * A range lets users choose an approximate value on a slider. * * - [Examples](https://atlassian.design/components/range/examples) * - [Code](https://atlassian.design/components/range/code) * - [Usage](https://atlassian.design/components/range/usage) */ const Range = /*#__PURE__*/forwardRef(function Range(props, ref) { const { isDisabled = false, defaultValue = 50, max = 100, min = 0, onChange = noop, step = 1, value: propsValue, testId, ...rest } = props; const spreadProps = { max, min, step, ref, ...rest }; const [value, setValue] = useState(propsValue !== undefined ? propsValue : defaultValue); const handleChange = useCallback(e => { const newValue = Number(e.target.value); setValue(newValue); // Note use of newValue to ensure up=to-date value is used onChange(newValue); }, [onChange]); const renderValue = propsValue !== undefined ? propsValue : value; const valuePercent = getRoundedPercentValue(renderValue, min, max, step); return /*#__PURE__*/React.createElement(Input, _extends({ type: "range", disabled: isDisabled, onChange: handleChange, value: renderValue, valuePercent: valuePercent, "data-testid": testId }, spreadProps)); }); export default Range;