UNPKG

react-custom-slider

Version:

a very easy to use customizable slider for React

411 lines (385 loc) 14.1 kB
import React, { useRef, useState, useMemo, useCallback } from 'react'; import PropTypes from 'prop-types'; function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } var Slider = function Slider(props) { var defaultValue = props.defaultValue, value = props.value, showValue = props.showValue, valueLabelColor = props.valueLabelColor, valueLabelActiveColor = props.valueLabelActiveColor, valueLabelPadding = props.valueLabelPadding, valueLabelStyle = props.valueLabelStyle, min = props.min, max = props.max, stepSize = props.stepSize, disabled = props.disabled, disabledColor = props.disabledColor, onChange = props.onChange, onRelease = props.onRelease, valueRenderer = props.valueRenderer, trackLength = props.trackLength, trackColor = props.trackColor, trackThickness = props.trackThickness, trackShape = props.trackShape, trackStyle = props.trackStyle, fillTrack = props.fillTrack, fillColor = props.fillColor, handlerSize = props.handlerSize, handlerWidth = props.handlerWidth, handlerHeight = props.handlerHeight, handlerShape = props.handlerShape, handlerColor = props.handlerColor, handlerBorderColor = props.handlerBorderColor, handlerActiveColor = props.handlerActiveColor, handlerStyle = props.handlerStyle, markers = props.markers, markersSize = props.markersSize, showMarkers = props.showMarkers, fontSize = props.fontSize, fontColor = props.fontColor, grabCursor = props.grabCursor, vertical = props.vertical, invertMarkers = props.invertMarkers, style = props.style; var handler_ref = useRef(null); var handler_width = handlerWidth ? handlerWidth : handlerSize; var handler_height = handlerHeight ? handlerHeight : handlerSize; var handlerWidth_radius = handler_width / 2; var handlerHeight_radius = handler_height / 2; var defaultStep = defaultValue - min; var _useState = useState(defaultValue), _value = _useState[0], set_Value = _useState[1]; var _useState2 = useState(false), isActive = _useState2[0], setIsActive = _useState2[1]; var _useState3 = useState(0), pointerStart_positionX = _useState3[0], setPointerStart_positionX = _useState3[1]; var _useState4 = useState(defaultStep && !value ? defaultStep : step), startValue = _useState4[0], setStartValue = _useState4[1]; var _useState5 = useState(null), handler_position = _useState5[0], setHandler_position = _useState5[1]; var step = (value !== null ? value : _value) - min; var steps = max - min; var track_radius = trackThickness / 2; var stepWidth = trackLength / steps; var markers_PositionsX = useMemo(function () { if (trackLength === 0) return []; var markers_PositionsX = []; for (var i = 0; i < markers; ++i) { var relPosition = i * (trackLength / (markers - 1)); markers_PositionsX.push({ position: relPosition + (!vertical ? handlerWidth_radius : handlerHeight_radius), value: Math.round(relPosition / stepWidth) }); } return markers_PositionsX; }, [trackLength, markers, handlerWidth_radius, stepWidth]); var sliderChangeHandler = function sliderChangeHandler(position) { var updatedValue = Math.round(min + position / stepWidth); if (updatedValue !== value && updatedValue % stepSize === 0) { setHandler_position(position); onChange(updatedValue); set_Value(updatedValue); } }; var pointerDownHandler = function pointerDownHandler(e) { if (disabled === false) { e.currentTarget.setPointerCapture(e.pointerId); setIsActive(true); setPointerStart_positionX(!vertical ? e.clientX : e.clientY); setHandler_position(step * stepWidth); setStartValue(step); } }; var trackPointerDownHandler = function trackPointerDownHandler(e) { if (disabled === false && !vertical) { var pointer_position = !vertical ? e.clientX - e.currentTarget.getBoundingClientRect().x : e.clientY - e.currentTarget.getBoundingClientRect().y; sliderChangeHandler(pointer_position); handler_ref.current.setPointerCapture(e.pointerId); setIsActive(true); setPointerStart_positionX(!vertical ? e.clientX : e.clientY); setStartValue(Math.round(pointer_position / trackLength * steps)); } }; var pointerMoveHandler = useCallback(function (e) { if (isActive) { var updatedhandler_position = startValue * stepWidth + (vertical ? 1 : -1) * (pointerStart_positionX - (!vertical ? e.clientX : e.clientY)); if (updatedhandler_position !== handler_position) { sliderChangeHandler(updatedhandler_position >= 0 && updatedhandler_position <= trackLength ? updatedhandler_position : updatedhandler_position > trackLength ? trackLength : 0); } } }, [trackLength, isActive, handler_position, pointerStart_positionX]); var pointerUpHandler = function pointerUpHandler(e) { if (disabled === false) { setIsActive(false); setPointerStart_positionX(0); setHandler_position(null); onRelease(Math.round(min + handler_position / stepWidth)); } }; var renderSlider = function renderSlider() { return /*#__PURE__*/React.createElement("div", { style: _extends({}, styles.slider, !vertical ? { height: handler_height } : { width: handler_width }, { visibility: trackLength !== 0 ? 'visible' : 'hidden' }) }, /*#__PURE__*/React.createElement("div", { style: _extends({}, styles.track, trackStyle, { borderRadius: trackShape === 'rounded' ? track_radius : 0 }, !vertical ? { left: handlerWidth_radius, right: handlerWidth_radius, top: '50%', height: trackThickness, transform: 'translateY(-50%)' } : { top: handlerHeight_radius, bottom: handlerHeight_radius, left: '50%', width: trackThickness, transform: 'translateX(-50%)' }, { backgroundColor: disabled ? disabledColor : trackColor, cursor: !disabled ? 'pointer' : 'default' }), onPointerDown: trackPointerDownHandler }), fillTrack && /*#__PURE__*/React.createElement("div", { style: _extends({}, styles.trackFill, { borderRadius: trackShape === 'rounded' ? track_radius : 0, left: handlerWidth_radius }, !vertical ? { top: handlerHeight_radius, width: handler_position !== null ? handler_position : step * stepWidth, height: trackThickness, transform: 'translateY(-50%)' } : { bottom: handlerHeight_radius, height: handler_position !== null ? handler_position : step * stepWidth, width: trackThickness, transform: 'translateX(-50%)' }, { backgroundColor: fillColor, cursor: !disabled ? 'pointer' : 'default' }), onPointerDown: trackPointerDownHandler }), /*#__PURE__*/React.createElement("div", { ref: handler_ref, onPointerDown: pointerDownHandler, onPointerMove: pointerMoveHandler, onPointerUp: pointerUpHandler, style: _extends({}, styles.handler, handlerStyle, !vertical ? { left: handler_position !== null ? handler_position : step * stepWidth } : { bottom: handler_position !== null ? handler_position : step * stepWidth }, { height: handler_height, width: handler_width, backgroundColor: isActive ? handlerActiveColor : disabled ? disabledColor : handlerColor, border: "1px solid " + handlerBorderColor, borderRadius: handlerShape === 'rounded' ? handlerHeight_radius : 4, cursor: grabCursor && !disabled ? isActive ? 'grabbing' : 'grab' : 'default' }) }), (isActive && showValue === 'active' || showMarkers === 'hidden' && showValue === 'active' && isActive || showValue === true) && showMarkers && /*#__PURE__*/React.createElement("div", { style: _extends({}, styles.marker, { zIndex: 10, height: fontSize, padding: valueLabelPadding, border: "1px solid " + handlerColor }, valueLabelStyle, !vertical ? { left: handlerWidth_radius + (handler_position !== null ? handler_position : step * stepWidth), top: !invertMarkers ? handler_height + markersSize + valueLabelPadding - 2 : -markersSize - valueLabelPadding - 1, transform: "translate(-50%," + (!invertMarkers ? -100 : 0) + "%)" } : _extends({ bottom: handlerHeight_radius + (handler_position !== null ? handler_position : step * stepWidth) }, !invertMarkers ? { left: handler_width + markersSize + valueLabelPadding } : { right: handler_width + markersSize + valueLabelPadding }, { transform: "translate(" + (!invertMarkers ? -100 : 100) + "%, 50%)" }), { backgroundColor: isActive ? valueLabelActiveColor : valueLabelColor }) }, valueRenderer(value !== null ? value : _value))); }; var renderMarkers = function renderMarkers() { return /*#__PURE__*/React.createElement(React.Fragment, null, trackLength !== 0 && markers >= 2 && /*#__PURE__*/React.createElement("div", { style: _extends({ position: 'relative', visibility: showMarkers === true || showMarkers === 'active' && isActive || showMarkers === 'inactive' && !isActive ? 'visible' : 'hidden' }, !vertical ? { height: markersSize } : { width: markersSize }) }, markers_PositionsX.map(function (_ref) { var position = _ref.position, value = _ref.value; return /*#__PURE__*/React.createElement("div", { key: position, style: _extends({}, styles.marker, !vertical ? _extends({ left: position }, !invertMarkers ? { bottom: 0 } : { top: 0 }, { transform: 'translateX(-50%)' }) : _extends({ bottom: position }, !invertMarkers ? { right: 0 } : { left: 0 }, { transform: "translateY(50%)" })) }, value); }))); }; return /*#__PURE__*/React.createElement("div", { style: _extends({}, style, styles.container, { flexDirection: !vertical ? 'column' : 'row', fontSize: fontSize, color: fontColor }, !vertical ? { width: trackLength + handler_width } : { height: trackLength + handler_height, width: handler_width + markersSize }) }, invertMarkers ? /*#__PURE__*/React.createElement(React.Fragment, null, showMarkers && renderMarkers(), renderSlider()) : /*#__PURE__*/React.createElement(React.Fragment, null, renderSlider(), showMarkers && renderMarkers())); }; var styles = { container: { display: 'flex', flex: 1, justifyContent: 'center' }, slider: { position: 'relative' }, track: { position: 'absolute' }, trackFill: { position: 'absolute' }, handler: { position: 'absolute', boxSizing: 'border-box', borderRadius: 4 }, marker: { position: 'absolute', textAlign: 'center' } }; Slider.defaultProps = { defaultValue: 0, value: null, showValue: true, valueLabelColor: '#3d3b4c', valueLabelActiveColor: '#4c61ff', valueLabelPadding: 4, valueLabelStyle: { color: '#fff' }, min: 0, max: 100, stepSize: 1, disabled: false, disabledColor: 'red', onChange: function onChange() {}, onRelease: function onRelease() {}, valueRenderer: function valueRenderer(value) { return value.toString(); }, trackLength: 200, trackColor: '#e5e5e5', trackThickness: 5, trackShape: 'rounded', trackStyle: {}, fillTrack: true, fillColor: '#4c61ff', handlerSize: 20, handlerWidth: null, handlerHeight: null, handlerShape: 'squared', handlerColor: '#fff', handlerBorderColor: '#999', handlerActiveColor: '#e5e5e5', handlerStyle: {}, fontSize: 12, fontColor: '#333', markers: 2, markersSize: 20, showMarkers: true, grabCursor: true, vertical: false, invertMarkers: false, style: {} }; Slider.propTypes = { defaultValue: PropTypes.number.isRequired, value: PropTypes.number.isRequired, showValue: PropTypes.oneOf([true, false, 'active']), valueLabelColor: PropTypes.string, valueLabelActiveColor: PropTypes.string, valueLabelPadding: PropTypes.number, valueLabelStyle: PropTypes.object, min: PropTypes.number, max: PropTypes.number, stepSize: PropTypes.number, disabled: PropTypes.bool, disabledColor: PropTypes.string, onChange: PropTypes.func, onRelease: PropTypes.func.isRequired, valueRenderer: PropTypes.func, trackLength: PropTypes.number.isRequired, trackColor: PropTypes.string, trackThickness: PropTypes.number, trackShape: PropTypes.oneOf(['squared', 'rounded']), trackStyle: PropTypes.object, fillTrack: PropTypes.bool, fillColor: PropTypes.string, handlerSize: PropTypes.number, handlerWidth: PropTypes.number, handlerHeight: PropTypes.number, handlerShape: PropTypes.oneOf(['squared', 'rounded']), handlerColor: PropTypes.string, handlerBorderColor: PropTypes.string, handlerActiveColor: PropTypes.string, handlerStyle: PropTypes.object, fontSize: PropTypes.number, fontColor: PropTypes.string, markers: PropTypes.number, markersSize: PropTypes.number, showMarkers: PropTypes.oneOf([true, false, 'hidden', 'active', 'inactive']), grabCursor: PropTypes.bool, vertical: PropTypes.bool, invertMarkers: PropTypes.bool, style: PropTypes.object }; export default Slider; //# sourceMappingURL=index.modern.js.map