UNPKG

fk-react-ui-components

Version:

Step 1 : Create a file in [ Seeds / Plants / Trees ] <br> Step 2 : It should export an Object with component name and story Component [Refer other components] <br> Step 3 : Story Component should return a react component <br> Step 3 : Created file should

582 lines (486 loc) 22.2 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _templateObject = _taggedTemplateLiteral(['\n width: 50px;\n outline: none;\n'], ['\n width: 50px;\n outline: none;\n']); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _styledComponents = require('styled-components'); var _styledComponents2 = _interopRequireDefault(_styledComponents); var _propTypes = require('./propTypes'); var _propTypes2 = _interopRequireDefault(_propTypes); var _styles = require('./styles'); var _Inputs = require('../FormElements/Inputs'); var _Inputs2 = _interopRequireDefault(_Inputs); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } var Input = (0, _styledComponents2.default)(_Inputs2.default)(_templateObject); var Slider = function (_React$PureComponent) { _inherits(Slider, _React$PureComponent); function Slider(props) { _classCallCheck(this, Slider); var _this = _possibleConstructorReturn(this, (Slider.__proto__ || Object.getPrototypeOf(Slider)).call(this, props)); _initialiseProps.call(_this); _this.handleRefs = []; var value = props.value; if (typeof value === 'undefined' || value.length === 0) { value = typeof props.defaultValue !== 'undefined' ? props.defaultValue : props.range ? [props.min, props.max] : props.min; } _this.state = { value: value, draggingHandleIndex: null, isComponentMounted: false }; _this.handleFirstInputValueChange = _this.handleInputValueChange.bind(_this, 0); _this.handleSecondInputValueChange = _this.handleInputValueChange.bind(_this, 1); return _this; } /** * Set isComponentMounted in state as the marks can only be * rendered after rendering the main scale. */ _createClass(Slider, [{ key: 'componentDidMount', value: function componentDidMount() { this.setState({ isComponentMounted: true }); } /** * Updates the selected value in the local state of this component * @param {object} nextProps */ }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { var _this2 = this; var value = nextProps.value; if (typeof value === 'undefined' || value.length === 0) { value = typeof nextProps.defaultValue !== 'undefined' ? nextProps.defaultValue : nextProps.range ? [nextProps.min, nextProps.max] : nextProps.min; } else if (nextProps.value !== this.state.value) { value = nextProps.value; } if (nextProps.range) { [0, 1].map(function (index) { if (_this2.state.value[index] < nextProps.min) { var _value = [].concat(_toConsumableArray(_this2.state.value)); _value[index] = nextProps.min; } if (_this2.state.value[index] > nextProps.max) { var _value2 = [].concat(_toConsumableArray(_this2.state.value)); _value2[index] = nextProps.max; } }); } else { if (this.state.value < nextProps.min) { value = nextProps.min; } if (this.state.value > nextProps.max) { value = nextProps.max; } } if (value !== this.state.value) { this.setState({ value: value }); } } /** * Sets the reference for the slider wrapper. * @param {object} ref */ /** * Sets the reference for the handle(s). * @param {number} index * @param {object} ref */ /** * Called on pressing the mouse button. * Adds global mousemove and mouseup event listeners to listen the drag event. * In case of single value selection it updates the value in the local state * which moves the handle to that postion. In case of range selection this cannot * be done as there are two handles. * @param {object} event */ /** * Called on releasing the mouse button. * Removes global mousemove and mouseup event listeners * @param {object} event */ /** * Called while dragging the mouse. * Updates the value in the local state of the component. */ /** * Adds global event listeners. */ /** * Removes global event listeners. */ /** * Returns the distance in pixels from the left edge of the slider to a point * on the slider corresponding to a particular value. * @param {number} value * @return {number} */ /** * Helper function to get the nearest marker(step) corresponding to given value * @param {number} value * @return {number} */ /** * Returns the corresponding value on the slider of any point on the document where the * user has clicked / dragged mouse. * @param {number} clientX The x coordinate of the point * @return {number} */ /** * Helper function to get the marker data in the required format. */ /** * Renders the scale with the steps / marks */ }, { key: 'render', value: function render() { var _this3 = this; return _react2.default.createElement( 'div', null, _react2.default.createElement( _styles.SliderWrapper, { styles: this.props.styles.slider || {}, innerRef: this.setSliderRef, onMouseDown: this.handleMouseDown }, this.renderScale(), this.props.range ? this.state.value.map(function (value, index) { return _react2.default.createElement(_styles.Handle, { key: index, posX: _this3.getPositionX(value), styles: _this3.props.styles.handle || {}, innerRef: function innerRef(ref) { return _this3.setHandleRef(index, ref); }, active: _this3.state.draggingHandleIndex === index }); }) : _react2.default.createElement(_styles.Handle, { posX: this.getPositionX(this.state.value), styles: this.props.styles.handle || {}, innerRef: function innerRef(ref) { return _this3.setHandleRef(0, ref); }, active: this.state.draggingHandleIndex === 0 }) ), this.props.showTextField ? this.renderInput() : null ); } }]); return Slider; }(_react2.default.PureComponent); var _initialiseProps = function _initialiseProps() { var _this4 = this; this.setSliderRef = function (ref) { if (ref) { _this4.sliderRef = ref; } }; this.setHandleRef = function (index, ref) { if (ref) { _this4.handleRefs[index] = ref; } }; this.handleInputValueChange = function (index, event) { var nextValue = void 0; var value = event.target.value; var minValue = _this4.props.min; var maxValue = _this4.props.max; if (_this4.props.range) { if (index === 0) { maxValue = _this4.state.value[1]; } else { minValue = _this4.state.value[0]; } } value = value < minValue ? minValue : value; value = value > maxValue ? maxValue : value; if (_this4.props.range) { nextValue = [].concat(_toConsumableArray(_this4.state.value)); nextValue[index] = value; } else { value = value; nextValue = value; } _this4.setState({ value: nextValue }); }; this.handleMouseDown = function (event) { if (_this4.props.disabled) { return; } if (!_this4.props.range) { var value = _this4.getValue(event.clientX); _this4.setState({ value: value, draggingHandleIndex: 0 }); _this4.props.onChange(value); _this4.addGlobalEventListeners(); } else if (_this4.handleRefs.indexOf(event.target) > -1) { _this4.setState({ draggingHandleIndex: _this4.handleRefs.indexOf(event.target) }); _this4.addGlobalEventListeners(); } else { var Xmin = _this4.sliderRef.getBoundingClientRect().left; var clientPosX = event.clientX - Xmin; var handleDistances = _this4.state.value.map(function (val) { return Math.abs(_this4.getPositionX(val) - clientPosX); }); var handleToMove = handleDistances.indexOf(Math.min.apply(Math, _toConsumableArray(handleDistances))); var nextValueArray = [].concat(_toConsumableArray(_this4.state.value)); nextValueArray[handleToMove] = Math.round(_this4.getValue(event.clientX)); _this4.setState({ value: nextValueArray }); _this4.props.onChange(nextValueArray); } }; this.handleGlobalMouseUp = function (event) { _this4.setState({ draggingHandleIndex: null }); _this4.removeGlobalEventListeners(); }; this.handleGlobalMouseMove = function (event) { if (!_this4.props.range) { var value = _this4.getValue(event.clientX); _this4.setState({ value: value }); _this4.props.onChange(value); } else if (_this4.state.draggingHandleIndex !== null) { var min = _this4.props.min; var max = _this4.props.max; if (_this4.state.draggingHandleIndex === 0) { max = _this4.state.value[1]; } else if (_this4.state.draggingHandleIndex === 1) { min = _this4.state.value[0]; } var _value3 = Math.round(_this4.getValue(event.clientX, min, max)); var nextValueArray = [].concat(_toConsumableArray(_this4.state.value)); nextValueArray[_this4.state.draggingHandleIndex] = _value3; _this4.setState({ value: nextValueArray }); _this4.props.onChange(nextValueArray); } }; this.addGlobalEventListeners = function () { document.body.addEventListener('mousemove', _this4.handleGlobalMouseMove); document.body.addEventListener('mouseup', _this4.handleGlobalMouseUp); }; this.removeGlobalEventListeners = function () { document.body.removeEventListener('mousemove', _this4.handleGlobalMouseMove); document.body.removeEventListener('mouseup', _this4.handleGlobalMouseUp); }; this.getPositionX = function (value) { if (_this4.sliderRef && _this4.props.max > _this4.props.min) { var _sliderRef$getBoundin = _this4.sliderRef.getBoundingClientRect(), Xmin = _sliderRef$getBoundin.left, Xmax = _sliderRef$getBoundin.right; /** In case of non linear scale simply get posX from the marker data */ if (_this4.props.nonLinear) { var posX = void 0; _this4.getMarkerData().map(function (data) { if (data.value === value) { posX = data.posX; } }); return posX; /** In case of linear scale posX can be calculated via interpolation */ } return parseInt((Xmax - Xmin) / (_this4.props.max - _this4.props.min) * (value - _this4.props.min)); } return 0; }; this.getNearestMarkerValue = function (value) { var nearestValue = void 0; var minDistance = 0; _this4.getMarkerData().map(function (data) { var step = data.value; var distance = Math.abs(value - step); if (typeof nearestValue === 'undefined' || distance < minDistance) { nearestValue = step; minDistance = distance; } }); return nearestValue; }; this.getValue = function (clientX) { var min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this4.props.min; var max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _this4.props.max; if (_this4.sliderRef) { var _sliderRef$getBoundin2 = _this4.sliderRef.getBoundingClientRect(), Xmin = _sliderRef$getBoundin2.left, Xmax = _sliderRef$getBoundin2.right; var posX = clientX - Xmin; var value = void 0; if (_this4.props.nonLinear) { /** In case of non linear scale value should be obtained from marker data */ var nearestValue = void 0, minDistance = 0; _this4.getMarkerData().map(function (data) { var distance = Math.abs(data.posX - posX); if (typeof nearestValue === 'undefined' || distance < minDistance) { nearestValue = data.value; minDistance = distance; } }); value = nearestValue; /** In case of linear scale value can be calculated using interpolation */ } else { value = _this4.props.min + (_this4.props.max - _this4.props.min) / (Xmax - Xmin) * posX; } /** Sanitize the value */ value = value > max ? max : value; value = value < min ? min : value; if (typeof _this4.props.steps !== 'undefined' && _this4.props.selectStepsOnly && !_this4.props.nonLinear) { value = _this4.getNearestMarkerValue(value); } return value; } return _this4.props.min; }; this.getMarkerData = function () { var marks = []; /** If steps are provided in props the use it to compute marker data */ if (_this4.props.steps) { if (_this4.props.nonLinear) { if (!_this4.sliderRef) { return; } var stepKeys = Object.keys(_this4.props.steps).sort(function (a, b) { return parseInt(a) - parseInt(b); }); if (parseInt(stepKeys[0]) !== _this4.props.min) { stepKeys = stepKeys.unshift(_this4.props.min); } if (parseInt(stepKeys[stepKeys.length - 1]) !== _this4.props.max) { stepKeys.push(_this4.props.max); } var spaceBetweenKeys = (_this4.props.max - _this4.props.min) / (stepKeys.length - 1); var _sliderRef$getBoundin3 = _this4.sliderRef.getBoundingClientRect(), Xmin = _sliderRef$getBoundin3.left, Xmax = _sliderRef$getBoundin3.right; stepKeys.map(function (step, index) { var posX = parseInt((Xmax - Xmin) / (_this4.props.max - _this4.props.min) * (spaceBetweenKeys * index - _this4.props.min)); marks.push({ index: marks.length, value: parseInt(step), posX: posX, tooltip: _this4.props.getTooltip(_this4.props.steps[step]) }); }); } else { Object.keys(_this4.props.steps).sort().map(function (step) { marks.push({ index: marks.length, value: parseInt(step), posX: _this4.getPositionX(parseInt(step)), tooltip: _this4.props.getTooltip(_this4.props.steps[step]) }); }); } /** If steps is not provided than place marks at equal distance on the linear scale */ } else { var step = Math.ceil((_this4.props.max - _this4.props.min) / 10) || 1; var val = _this4.props.min; while (val <= _this4.props.max) { marks.push({ index: marks.length, value: parseInt(step), posX: _this4.getPositionX(val), tooltip: _this4.props.getTooltip(val) }); val += step; } } return marks; }; this.renderScale = function () { var markerData = _this4.getMarkerData(); var value = _this4.state.value; return _react2.default.createElement( _styles.Scale, { styles: _this4.props.styles.scale || {} }, _this4.state.isComponentMounted ? markerData.map(function (mark) { return _this4.props.showMarkerWithoutTooltip || mark.tooltip ? [_react2.default.createElement(_styles.Mark, { styles: _this4.props.styles.mark || {}, posX: mark.posX }), _react2.default.createElement( _styles.Tooltip, { styles: _this4.props.styles.tooltip || {}, posX: mark.posX }, mark.tooltip )] : null; }) : null, _this4.props.range ? _react2.default.createElement(_styles.Line, { styles: _this4.props.styles.line || {}, style: { left: _this4.getPositionX(value[0]), width: _this4.getPositionX(value[1]) - _this4.getPositionX(value[0]) } }) : _react2.default.createElement(_styles.Line, { styles: _this4.props.styles.line || {}, style: { left: 0, width: _this4.getPositionX(value) } }) ); }; this.renderInput = function () { var value = _this4.state.value; if (_this4.props.range) { value = value.map(function (v) { return parseInt(v * 100) / 100; }); } else { value = parseInt(value * 100) / 100; } return _react2.default.createElement( _styles.InputWrapper, null, _this4.props.range ? [_react2.default.createElement(Input, { value: value[0], onChange: _this4.handleFirstInputValueChange, type: 'number', disabled: _this4.props.disabled }), _react2.default.createElement( _styles.Separator, null, '-' ), _react2.default.createElement(Input, { value: value[1], onChange: _this4.handleSecondInputValueChange, type: 'number', disabled: _this4.props.disabled })] : _react2.default.createElement(Input, { value: value, onChange: _this4.handleFirstInputValueChange, type: 'number', disabled: _this4.props.disabled }) ); }; }; Slider.propTypes = _propTypes2.default; Slider.defaultProps = { disabled: false, selectStepsOnly: false, showMarkerWithoutTooltip: true, onChange: function onChange(val) {}, styles: {}, range: false, min: 0, max: 100, getTooltip: function getTooltip(val) { return val; }, showTextField: false }; exports.default = Slider;