UNPKG

audiolux-multi-range-slider

Version:

Simple component to select range values from slider. React component that return two value minValue and maxValue by event onInput/onChange. A custom fork of multi-range-slider-react

418 lines (417 loc) 17.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = __importStar(require("react")); require("./multirangeslider.css"); let _wheelTimeout = null; let _triggerTimeout = null; const MultiRangeSlider = (props, ref) => { let ruler = props.ruler === undefined || props.ruler === null ? true : props.ruler; let label = props.label === undefined || props.label === null ? true : props.label; let subSteps = props.subSteps === undefined || props.subSteps === null ? false : props.subSteps; let stepOnly = props.stepOnly === undefined || props.stepOnly === null ? false : props.stepOnly; let preventWheel = props.preventWheel === undefined || props.preventWheel === null ? false : props.preventWheel; let refBar = (0, react_1.useRef)(null); let min = +(props.min || 0); let max = +(props.max || 100); let step = Math.abs(+(props.step || 5)); let fixed = 0; let disabled = !!props.disabled; let stepValue = props.canMinMaxValueSame ? 0 : step; let stepCount = Math.floor((+max - +min) / +step); let labels = props.labels || []; if (labels.length === 0) { labels = []; labels.push(min.toString()); labels.push(max.toString()); } else { stepCount = labels.length - 1; } if (typeof label === 'string') { label = label === 'true'; } if (typeof ruler === 'string') { ruler = ruler === 'true'; } if (typeof preventWheel === 'string') { preventWheel = preventWheel === 'true'; } if (step.toString().includes('.')) { fixed = 2; } let _minValue = props.minValue; if (_minValue === null || _minValue === undefined) { _minValue = 25; } _minValue = +_minValue; let _maxValue = props.maxValue; if (_maxValue === null || _maxValue === undefined) { _maxValue = 75; } _maxValue = +_maxValue; if (_minValue < min) { _minValue = min; } if (_minValue > max) { _minValue = max; } if (_maxValue < _minValue) { _maxValue = +_minValue + +step; } if (_maxValue > max) { _maxValue = max; } if (_maxValue < min) { _maxValue = min; } const [minValue, set_minValue] = (0, react_1.useState)(+_minValue); const [maxValue, set_maxValue] = (0, react_1.useState)(+_maxValue); const [barMin, set_barMin] = (0, react_1.useState)(((minValue - min) / (max - min)) * 100); const [barMax, set_barMax] = (0, react_1.useState)(((max - maxValue) / (max - min)) * 100); const [minCaption, setMinCaption] = (0, react_1.useState)(''); const [maxCaption, setMaxCaption] = (0, react_1.useState)(''); const [isChange, setIsChange] = (0, react_1.useState)(true); const onBarLeftClick = (e) => { if (disabled) return; let _minValue = minValue - step; if (_minValue < min) { _minValue = min; } set_minValue(_minValue); }; const onInputMinChange = (e) => { if (disabled) return; let _minValue = parseFloat(e.target.value); if (_minValue > maxValue - stepValue) { _minValue = maxValue - stepValue; } set_minValue(_minValue); setIsChange(true); }; const onLeftThumbMousedown = (e) => { if (disabled) return; let startX = e.clientX; let thumb = e.target; let bar = thumb.parentNode; let barBox = bar.getBoundingClientRect(); let barValue = minValue; setIsChange(false); let onLeftThumbMousemove = (e) => { let clientX = e.clientX; let dx = clientX - startX; let per = dx / barBox.width; let val = barValue + (max - min) * per; if (stepOnly) { val = Math.round(val / step) * step; } val = parseFloat(val.toFixed(fixed)); if (val < min) { val = min; } else if (val > maxValue - stepValue) { val = maxValue - stepValue; } set_minValue(val); }; let onLeftThumbMouseup = (e) => { setIsChange(true); document.removeEventListener('mousemove', onLeftThumbMousemove); document.removeEventListener('mouseup', onLeftThumbMouseup); }; document.addEventListener('mousemove', onLeftThumbMousemove); document.addEventListener('mouseup', onLeftThumbMouseup); }; const onLeftThumbTouchStart = (e) => { if (disabled) return; let startX = e.touches[0].clientX; let thumb = e.target; let bar = thumb.parentNode; let barBox = bar.getBoundingClientRect(); let barValue = minValue; setIsChange(false); let onLeftThumbToucheMove = (e) => { let clientX = e.touches[0].clientX; let dx = clientX - startX; let per = dx / barBox.width; let val = barValue + (max - min) * per; if (stepOnly) { val = Math.round(val / step) * step; } val = parseFloat(val.toFixed(fixed)); if (val < min) { val = min; } else if (val > maxValue - stepValue) { val = maxValue - stepValue; } set_minValue(val); }; let onLeftThumbTouchEnd = (e) => { setIsChange(true); document.removeEventListener('touchmove', onLeftThumbToucheMove); document.removeEventListener('touchend', onLeftThumbTouchEnd); }; document.addEventListener('touchmove', onLeftThumbToucheMove); document.addEventListener('touchend', onLeftThumbTouchEnd); }; const onInnerBarLeftClick = (e) => { if (disabled) return; let _minValue = minValue + step; if (_minValue > maxValue - stepValue) { _minValue = maxValue - stepValue; } set_minValue(_minValue); }; const onInnerBarRightClick = (e) => { if (disabled) return; let _maxValue = maxValue - step; if (_maxValue < minValue + stepValue) { _maxValue = minValue + stepValue; } set_maxValue(_maxValue); }; const onInputMaxChange = (e) => { if (disabled) return; let _maxValue = parseFloat(e.target.value); if (_maxValue < minValue + stepValue) { _maxValue = minValue + stepValue; } set_maxValue(_maxValue); setIsChange(true); }; const onRightThumbMousedown = (e) => { if (disabled) return; let startX = e.clientX; let thumb = e.target; let bar = thumb.parentNode; let barBox = bar.getBoundingClientRect(); let barValue = maxValue; setIsChange(false); let onRightThumbMousemove = (e) => { let clientX = e.clientX; let dx = clientX - startX; let per = dx / barBox.width; let val = barValue + (max - min) * per; if (stepOnly) { val = Math.round(val / step) * step; } val = parseFloat(val.toFixed(fixed)); if (val < minValue + stepValue) { val = minValue + stepValue; } else if (val > max) { val = max; } set_maxValue(val); }; let onRightThumbMouseup = (e) => { setIsChange(true); document.removeEventListener('mousemove', onRightThumbMousemove); document.removeEventListener('mouseup', onRightThumbMouseup); }; document.addEventListener('mousemove', onRightThumbMousemove); document.addEventListener('mouseup', onRightThumbMouseup); }; const onRightThumbTouchStart = (e) => { if (disabled) return; let startX = e.touches[0].clientX; let thumb = e.target; let bar = thumb.parentNode; let barBox = bar.getBoundingClientRect(); let barValue = maxValue; setIsChange(false); let onRightThumbTouchMove = (e) => { let clientX = e.touches[0].clientX; let dx = clientX - startX; let per = dx / barBox.width; let val = barValue + (max - min) * per; if (stepOnly) { val = Math.round(val / step) * step; } val = parseFloat(val.toFixed(fixed)); if (val < minValue + stepValue) { val = minValue + stepValue; } else if (val > max) { val = max; } set_maxValue(val); }; let onRightThumbTouchEnd = (e) => { setIsChange(true); document.removeEventListener('touchmove', onRightThumbTouchMove); document.removeEventListener('touchend', onRightThumbTouchEnd); }; document.addEventListener('touchmove', onRightThumbTouchMove); document.addEventListener('touchend', onRightThumbTouchEnd); }; const onBarRightClick = (e) => { if (disabled) return; let _maxValue = maxValue + step; if (_maxValue > max) { _maxValue = max; } set_maxValue(_maxValue); }; const onMouseWheel = (e) => { if (disabled) return; if (preventWheel === true) { return; } if (!e.shiftKey && !e.ctrlKey) { return; } let val = (max - min) / 100; if (val > 1) { val = 1; } if (e.deltaY < 0) { val = -val; } let _minValue = minValue; let _maxValue = maxValue; if (e.shiftKey && e.ctrlKey) { if (_minValue + val >= min && _maxValue + val <= max) { _minValue = _minValue + val; _maxValue = _maxValue + val; } } else if (e.ctrlKey) { val = _maxValue + val; if (val < _minValue + stepValue) { val = _minValue + stepValue; } else if (val > max) { val = max; } _maxValue = val; } else if (e.shiftKey) { val = _minValue + val; if (val < min) { val = min; } else if (val > _maxValue - stepValue) { val = _maxValue - stepValue; } _minValue = val; } setIsChange(false); set_maxValue(_maxValue); set_minValue(_minValue); _wheelTimeout && window.clearTimeout(_wheelTimeout); _wheelTimeout = window.setTimeout(() => { setIsChange(true); }, 100); }; (0, react_1.useEffect)(() => { if (refBar && refBar.current) { let bar = refBar.current; let p_bar = bar.parentNode; p_bar.addEventListener('wheel', (e) => { if (!e.shiftKey && !e.ctrlKey) { return; } e.preventDefault(); }); } }, [refBar]); (0, react_1.useEffect)(() => { if (maxValue < minValue) { throw new Error('maxValue is less than minValue'); } const triggerChange = () => { let result = { min, max, minValue, maxValue }; isChange && props.onChange && props.onChange(result); props.onInput && props.onInput(result); }; setMinCaption(props.minCaption || minValue.toFixed(fixed)); setMaxCaption(props.maxCaption || maxValue.toFixed(fixed)); let _barMin = ((minValue - min) / (max - min)) * 100; set_barMin(_barMin); let _barMax = ((max - maxValue) / (max - min)) * 100; set_barMax(_barMax); _triggerTimeout && window.clearTimeout(_triggerTimeout); _triggerTimeout = window.setTimeout(triggerChange, 20); }, [minValue, maxValue, min, max, fixed, props, isChange]); (0, react_1.useEffect)(() => { let _minValue = props.minValue; if (_minValue === null || _minValue === undefined) { _minValue = 25; } _minValue = +_minValue; if (_minValue < min) { _minValue = min; } if (_minValue > max) { _minValue = max; } setIsChange(false); set_minValue(+_minValue); }, [props.minValue, min, max]); (0, react_1.useEffect)(() => { let _maxValue = props.maxValue; if (_maxValue === null || _maxValue === undefined) { _maxValue = 75; } _maxValue = +_maxValue; if (_maxValue > max) { _maxValue = max; } if (_maxValue < min) { _maxValue = min; } setIsChange(false); set_maxValue(+_maxValue); }, [props.maxValue, min, max, step]); return (react_1.default.createElement("div", { ref: ref, id: props.id, className: (props.baseClassName || 'multi-range-slider') + ' ' + (props.className || '') + (disabled ? ' disabled' : ''), style: props.style, onWheel: onMouseWheel }, react_1.default.createElement("div", { className: 'bar', ref: refBar }, react_1.default.createElement("div", { className: 'bar-left', style: { width: barMin + '%', backgroundColor: props.barLeftColor }, onClick: onBarLeftClick }), react_1.default.createElement("input", { placeholder: 'min-value', className: 'input-type-range input-type-range-min', type: 'range', min: min, max: max, step: step, value: minValue, onInput: onInputMinChange }), react_1.default.createElement("div", { className: 'thumb thumb-left', style: { backgroundColor: props.thumbLeftColor }, onMouseDown: onLeftThumbMousedown, onTouchStart: onLeftThumbTouchStart }, react_1.default.createElement("div", { className: 'caption' }, react_1.default.createElement("span", { className: 'min-caption' }, minCaption))), react_1.default.createElement("div", { className: 'bar-inner', style: { backgroundColor: props.barInnerColor } }, react_1.default.createElement("div", { className: 'bar-inner-left', onClick: onInnerBarLeftClick }), react_1.default.createElement("div", { className: 'bar-inner-right', onClick: onInnerBarRightClick })), react_1.default.createElement("input", { placeholder: 'max-value', className: 'input-type-range input-type-range-max', type: 'range', min: min, max: max, step: step, value: maxValue, onInput: onInputMaxChange }), react_1.default.createElement("div", { className: 'thumb thumb-right', style: { backgroundColor: props.thumbRightColor }, onMouseDown: onRightThumbMousedown, onTouchStart: onRightThumbTouchStart }, react_1.default.createElement("div", { className: 'caption' }, react_1.default.createElement("span", { className: 'max-caption' }, maxCaption))), react_1.default.createElement("div", { className: 'bar-right', style: { width: barMax + '%', backgroundColor: props.barRightColor }, onClick: onBarRightClick })), ruler && (react_1.default.createElement("div", { className: 'ruler' }, [...Array(stepCount)].map((e, i) => (react_1.default.createElement("div", { key: i, className: 'ruler-rule' }, subSteps && [...Array(10)].map((e, n) => react_1.default.createElement("div", { key: n, className: 'ruler-sub-rule' }))))))), label && (react_1.default.createElement("div", { className: 'labels' }, labels.map((label) => { return (react_1.default.createElement("div", { key: label.toString(), className: 'label' }, label)); }))))); }; exports.default = react_1.default.memo((0, react_1.forwardRef)(MultiRangeSlider));