react-custom-slider
Version:
a very easy to use customizable slider for React
414 lines (387 loc) • 14.4 kB
JavaScript
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var React = require('react');
var React__default = _interopDefault(React);
var PropTypes = _interopDefault(require('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 = React.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 = React.useState(defaultValue),
_value = _useState[0],
set_Value = _useState[1];
var _useState2 = React.useState(false),
isActive = _useState2[0],
setIsActive = _useState2[1];
var _useState3 = React.useState(0),
pointerStart_positionX = _useState3[0],
setPointerStart_positionX = _useState3[1];
var _useState4 = React.useState(defaultStep && !value ? defaultStep : step),
startValue = _useState4[0],
setStartValue = _useState4[1];
var _useState5 = React.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 = React.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 = React.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__default.createElement("div", {
style: _extends({}, styles.slider, !vertical ? {
height: handler_height
} : {
width: handler_width
}, {
visibility: trackLength !== 0 ? 'visible' : 'hidden'
})
}, /*#__PURE__*/React__default.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__default.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__default.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__default.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__default.createElement(React__default.Fragment, null, trackLength !== 0 && markers >= 2 && /*#__PURE__*/React__default.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__default.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__default.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__default.createElement(React__default.Fragment, null, showMarkers && renderMarkers(), renderSlider()) : /*#__PURE__*/React__default.createElement(React__default.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
};
module.exports = Slider;
//# sourceMappingURL=index.js.map