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.

474 lines (397 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 _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 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 _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 { withTheme } from "react-fela"; import { Arrow } from "../arrow"; import { Block } from "../block"; import { Click } from "../click"; import { getThemeStyle } from "../../get-theme-style"; var KEY_LEFT = 37; var KEY_UP = 38; var KEY_RIGHT = 39; var KEY_DOWN = 40; var THUMB_WIDTH = 40; var THUMB_HEIGHT = 40; var thumbStyle = function thumbStyle(_ref) { var left = _ref.left, isDragging = _ref.isDragging, theme = _ref.theme, disabled = _ref.disabled; return { position: "absolute", top: 0, left: left, width: THUMB_WIDTH, height: THUMB_HEIGHT, border: "1px solid " + theme.tokens.inputBorder, background: theme.tokens.inputBackground, cursor: disabled ? "not-allowed" : "ew-resize", display: "flex", alignItems: "center", justifyContent: "center", outline: 0, ":focus": { borderColor: theme.tokens.inputBorderFocus }, extend: { condition: !isDragging, style: { 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(_this), "state", { isDragging: false, lastStep: 0, currentLeft: 0 }); _defineProperty(_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(_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(_this), "getElementProperty", function (element, property) { return element && element.getBoundingClientRect ? element.getBoundingClientRect()[property] : 0; }); _defineProperty(_assertThisInitialized(_this), "getElementWidth", function (element) { return _this.getElementProperty(element, "width"); }); _defineProperty(_assertThisInitialized(_this), "getElementLeft", function (element) { return _this.getElementProperty(element, "left"); }); _defineProperty(_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(_this), "getStepAtPercentagePosition", function (percentagePosition) { var steps = _this.getNumberOfSteps(); return Math.round(percentagePosition * (steps - 1)); }); _defineProperty(_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(_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(_this), "getCurrentValue", function () { var currentStep = _this.state.currentStep; return _this.getValueAtStepPosition(currentStep); }); _defineProperty(_assertThisInitialized(_this), "updateCurrentStep", function (position) { var trackWidth = _this.getElementWidth(_this.trackRef.current); var trackLeft = _this.getElementLeft(_this.trackRef.current); var thumbWidth = THUMB_WIDTH; 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(_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 leftPos = currentStep * (trackWidth - THUMB_WIDTH) / (steps - 1); return currentLeft ? currentLeft : Math.round(leftPos); }); _defineProperty(_assertThisInitialized(_this), "handleMouseDown", function (e) { _this.updateCurrentStep(e.clientX); _this.setState({ lastStep: _this.state.currentStep }); }); _defineProperty(_assertThisInitialized(_this), "handleDragStart", function () { _this.setState({ isDragging: true, lastStep: _this.state.currentStep }); document.addEventListener("mousemove", _this.handleDrag); document.addEventListener("mouseup", _this.handleDragEnd); }); _defineProperty(_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(_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(_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(_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, theme = _this$props4.theme, disabled = _this$props4.disabled; var value = this.getCurrentValue(); var left = this.getLeftPositionFromCurrentStep(); var styleProps = { isDragging: this.state.isDragging, left: left, theme: theme, disabled: disabled }; return React.createElement(Click, { innerRef: this.thumbRef, extend: [thumbStyle(styleProps), getThemeStyle("sliderThumb", theme, styleProps)], role: "slider", "aria-valuemin": minValue, "aria-valuemax": maxValue, "aria-valuenow": value, "aria-orientation": "horizontal", disabled: disabled, 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: theme.tokens[disabled ? "inputDisabledControl" : "inputControl"], direction: "left" }), React.createElement(Arrow, { color: theme.tokens[disabled ? "inputDisabledControl" : "inputControl"], direction: "right" })); } }, { key: "render", value: function render() { var _this4 = this; var theme = this.props.theme; return React.createElement(Block, { extend: [{ position: "relative", height: 42 }, getThemeStyle("slider", theme)] }, React.createElement(Block, { extend: [{ position: "absolute", top: 9, left: 0, right: 0, width: "100%", boxSizing: "border-box", height: 21, borderWidth: 1, borderStyle: "solid", borderColor: theme.tokens.inputBorder, background: theme.tokens.inputBackground, cursor: this.props.disabled ? "not-allwoed" : "pointer" }, getThemeStyle("sliderTrack", theme)], innerRef: this.trackRef, onMouseDown: function onMouseDown(e) { if (!_this4.props.disabled) { _this4.handleMouseDown(e); } }, onMouseUp: function onMouseUp() { if (!_this4.props.disabled) { _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 };