UNPKG

vcc-ui

Version:

VCC UI is a collection of React UI Components that can be used for developing front-end applications at Volvo Car Corporation.

448 lines (368 loc) 16.5 kB
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import React, { Component } from "react"; import PropTypes from "prop-types"; import { Arrow } from "../arrow"; import { Block, withTheme } from "../block"; import { Click } from "../click"; import { COLORS } from "../../constants/colors"; var KEY_LEFT = 37; var KEY_UP = 38; var KEY_RIGHT = 39; var KEY_DOWN = 40; var thumbStyle = function thumbStyle(left, isDragging) { return _objectSpread({ position: "absolute", top: "0", left: left, width: "40px", height: "40px", border: "1px solid #bbb", background: "white", cursor: "ew-resize", display: "flex", alignItems: "center", justifyContent: "center" }, !isDragging && { transition: "left 200ms ease-out" }); }; var SliderComponent = /*#__PURE__*/ function (_Component) { _inherits(SliderComponent, _Component); function SliderComponent(props) { var _this; _classCallCheck(this, SliderComponent); _this = _possibleConstructorReturn(this, _getPrototypeOf(SliderComponent).call(this, props)); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "state", { isDragging: false, lastStep: 0, currentLeft: 0 }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "componentDidUpdate", function (prevProps) { var initialValue = _this.props.initialValue; var prevInitialValue = prevProps.initialValue; if (initialValue !== prevInitialValue) { _this.setState(function () { return { currentStep: _this.getStepForValue(initialValue) }; }); } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleChange", function () { var _this$props$onChange = _this.props.onChange, onChange = _this$props$onChange === void 0 ? function () {} : _this$props$onChange; var _this$state = _this.state, lastStep = _this$state.lastStep, currentStep = _this$state.currentStep; var currentValue = _this.getCurrentValue(); if (lastStep !== currentStep && typeof onChange === "function") { onChange(currentValue); } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getElementProperty", function (element, property) { return element && element.getBoundingClientRect ? element.getBoundingClientRect()[property] : 0; }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getElementWidth", function (element) { return _this.getElementProperty(element, "width"); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getElementLeft", function (element) { return _this.getElementProperty(element, "left"); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getNumberOfSteps", function () { var _this$props = _this.props, step = _this$props.step, minValue = _this$props.minValue, maxValue = _this$props.maxValue, _this$props$valueList = _this$props.valueList, valueList = _this$props$valueList === void 0 ? [] : _this$props$valueList; if (valueList.length > 0) { return valueList.length; } else { return (maxValue - minValue) / step + 1; } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getStepAtPercentagePosition", function (percentagePosition) { var steps = _this.getNumberOfSteps(); return Math.round(percentagePosition * (steps - 1)); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getStepForValue", function (value) { var _this$props2 = _this.props, minValue = _this$props2.minValue, maxValue = _this$props2.maxValue, _this$props2$valueLis = _this$props2.valueList, valueList = _this$props2$valueLis === void 0 ? [] : _this$props2$valueLis; var steps = _this.getNumberOfSteps(); var thisValue = value - minValue; var range = maxValue - minValue; if (valueList.length > 0) { return valueList.indexOf(value); } else { return Math.round((steps - 1) * thisValue / range); } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getValueAtStepPosition", function (step) { var _this$props3 = _this.props, minValue = _this$props3.minValue, maxValue = _this$props3.maxValue, _this$props3$valueLis = _this$props3.valueList, valueList = _this$props3$valueLis === void 0 ? [] : _this$props3$valueLis; var steps = _this.getNumberOfSteps(); if (valueList.length > 0) { return valueList.find(function (value, index) { return index === step; }); } else { return minValue + step * ((maxValue - minValue) / (steps - 1)); } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getCurrentValue", function () { var currentStep = _this.state.currentStep; return _this.getValueAtStepPosition(currentStep); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "updateCurrentStep", function (position) { var trackWidth = _this.getElementWidth(_this.trackRef.current); var trackLeft = _this.getElementLeft(_this.trackRef.current); var thumbWidth = _this.getElementWidth(_this.thumbRef.current); var newPositionLeft = position - trackLeft - thumbWidth / 2; var isMax = newPositionLeft >= trackWidth - thumbWidth; var isMin = newPositionLeft <= 0; var currentPositionLeft = isMax ? trackWidth - thumbWidth : isMin ? 0 : newPositionLeft; var currentPositionPercent = currentPositionLeft / (trackWidth - thumbWidth); if (typeof position === "number") { _this.setState({ currentStep: _this.getStepAtPercentagePosition(currentPositionPercent), currentLeft: currentPositionLeft }); } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getLeftPositionFromCurrentStep", function () { if (!_this.trackRef || !_this.thumbRef) { return 0; } var _this$state2 = _this.state, _this$state2$currentS = _this$state2.currentStep, currentStep = _this$state2$currentS === void 0 ? 0 : _this$state2$currentS, _this$state2$currentL = _this$state2.currentLeft, currentLeft = _this$state2$currentL === void 0 ? 0 : _this$state2$currentL; var steps = _this.getNumberOfSteps(); var trackWidth = _this.getElementWidth(_this.trackRef.current); var thumbWidth = _this.getElementWidth(_this.thumbRef.current); var leftPos = currentStep * (trackWidth - thumbWidth) / (steps - 1); return currentLeft ? currentLeft : Math.round(leftPos); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleMouseDown", function (e) { _this.updateCurrentStep(e.clientX); _this.setState({ lastStep: _this.state.currentStep }); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleDragStart", function () { _this.setState({ isDragging: true, lastStep: _this.state.currentStep }); document.addEventListener("mousemove", _this.handleDrag); document.addEventListener("mouseup", _this.handleDragEnd); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleDrag", function (e) { var onMoveStart = _this.props.onMoveStart; var currentValue = _this.getCurrentValue(); e.preventDefault(); e.stopPropagation(); if (_this.state.isDragging) { _this.updateCurrentStep(e.touches ? e.touches[0].clientX : e.clientX); if (typeof onMoveStart === "function") { onMoveStart(currentValue); } } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleDragEnd", function () { var onMoveEnd = _this.props.onMoveEnd; _this.setState({ isDragging: false }); document.removeEventListener("mousemove", _this.handleDrag); document.removeEventListener("mouseup", _this.handleDragEnd); _this.thumbRef.current.blur(); _this.resetCurrentLeft(); _this.handleChange(); if (typeof onMoveEnd === "function") { onMoveEnd(); } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "adjustCurrentStepBy", function (diff) { var currentStep = _this.state.currentStep; var steps = _this.getNumberOfSteps(); var nextStep = currentStep + diff; _this.setState({ currentStep: nextStep <= steps - 1 && nextStep >= 0 ? nextStep : currentStep }); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleKeyDown", function (e) { e.preventDefault(); e.stopPropagation(); var key = e.which; if (key === KEY_UP || key === KEY_RIGHT) { _this.adjustCurrentStepBy(1); } else if (key === KEY_DOWN || key === KEY_LEFT) { _this.adjustCurrentStepBy(-1); } }); _this.trackRef = React.createRef(); _this.thumbRef = React.createRef(); return _this; } _createClass(SliderComponent, [{ key: "componentDidMount", value: function componentDidMount() { var _this2 = this; var initialValue = this.props.initialValue; this.setState({ currentStep: this.getStepForValue(initialValue) }); var resizeTimer; this.resizeEventHandler = function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(function () { _this2.forceUpdate(); }, 1); }; window.addEventListener("resize", this.resizeEventHandler); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { window.removeEventListener("resize", this.resizeEventHandler); } }, { key: "resetCurrentLeft", value: function resetCurrentLeft() { this.setState({ currentLeft: 0 }); } }, { key: "handleMouseUp", value: function handleMouseUp() { this.resetCurrentLeft(); this.handleChange(); } }, { key: "handleKeyUp", value: function handleKeyUp() { this.setState({ lastStep: this.state.currentStep }); this.handleChange(); } }, { key: "renderThumb", value: function renderThumb() { var _this3 = this; var _this$props4 = this.props, minValue = _this$props4.minValue, maxValue = _this$props4.maxValue; var value = this.getCurrentValue(); var left = this.getLeftPositionFromCurrentStep(); return React.createElement(Click, { innerRef: this.thumbRef, extend: _objectSpread({}, thumbStyle(left, this.state.isDragging)), role: "slider", "aria-valuemin": minValue, "aria-valuemax": maxValue, "aria-valuenow": value, "aria-orientation": "horizontal", onMouseDown: function onMouseDown() { return _this3.handleDragStart(); }, onMouseMove: function onMouseMove(e) { return _this3.handleDrag(e); }, onMouseUp: function onMouseUp() { return _this3.handleDragEnd(); }, onContextMenu: function onContextMenu() { return _this3.handleDragEnd(); }, onTouchStart: function onTouchStart() { return _this3.handleDragStart(); }, onTouchMove: function onTouchMove(e) { return _this3.handleDrag(e); }, onTouchEnd: function onTouchEnd() { return _this3.handleDragEnd(); }, onKeyDown: function onKeyDown(e) { return _this3.handleKeyDown(e); }, onKeyUp: function onKeyUp() { return _this3.handleKeyUp(); } }, React.createElement(Arrow, { color: COLORS.blue, direction: "left" }), React.createElement(Arrow, { color: COLORS.blue, direction: "right" })); } }, { key: "render", value: function render() { var _this4 = this; var theme = this.props.theme; return React.createElement(Block, { extend: _objectSpread({ position: "relative", height: "42px" }, theme.slider) }, React.createElement(Block, { extend: _objectSpread({ position: "absolute", top: "9px", left: "0", right: "0", width: "100%", boxSizing: "border-box", height: "21px", border: "1px solid #bbb", background: "white" }, theme.sliderTrack), innerRef: this.trackRef, onMouseDown: function onMouseDown(e) { return _this4.handleMouseDown(e); }, onMouseUp: function onMouseUp() { return _this4.handleMouseUp(); } }), typeof this.state.currentStep !== "undefined" && this.renderThumb()); } }]); return SliderComponent; }(Component); _defineProperty(SliderComponent, "propTypes", { initialValue: PropTypes.number.isRequired, minValue: PropTypes.number, maxValue: PropTypes.number, step: PropTypes.number, valueList: PropTypes.array, onMoveStart: PropTypes.func, onMoveEnd: PropTypes.func, onChange: PropTypes.func }); SliderComponent.displayName = "Slider"; var Slider = withTheme(SliderComponent); export { Slider };