UNPKG

@kiwicom/orbit-components

Version:

Orbit-components is a React component library which provides developers with the easiest possible way of building Kiwi.com’s products.

645 lines (519 loc) 26.6 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.PureSlider = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var React = _interopRequireWildcard(require("react")); var _styledComponents = _interopRequireWildcard(require("styled-components")); var _js = require("@adeira/js"); var _transition = _interopRequireDefault(require("../utils/transition")); var _Text = _interopRequireDefault(require("../Text")); var _Heading = _interopRequireDefault(require("../Heading")); var _Stack = _interopRequireDefault(require("../Stack")); var _Hide = _interopRequireDefault(require("../Hide")); var _Handle = _interopRequireDefault(require("./components/Handle")); var _Bar = _interopRequireDefault(require("./components/Bar")); var _keyMaps = _interopRequireDefault(require("../common/keyMaps")); var _consts = _interopRequireDefault(require("./consts")); var _Histogram = _interopRequireDefault(require("./components/Histogram")); var _defaultTheme = _interopRequireDefault(require("../defaultTheme")); var _mediaQuery = _interopRequireDefault(require("../utils/mediaQuery")); var _boundingClientRect = _interopRequireDefault(require("../utils/boundingClientRect")); function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } var StyledSlider = _styledComponents.default.div.withConfig({ displayName: "Slider__StyledSlider", componentId: "j475w2-0" })(["position:relative;"]); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198 StyledSlider.defaultProps = { theme: _defaultTheme.default }; var StyledSliderContent = _styledComponents.default.div.withConfig({ displayName: "Slider__StyledSliderContent", componentId: "j475w2-1" })(["display:block;width:100%;box-sizing:border-box;padding-bottom:", ";", ";"], function (_ref) { var theme = _ref.theme; return theme.orbit.spaceXSmall; }, _mediaQuery.default.tablet((0, _styledComponents.css)(["width:calc(100% + 48px);position:absolute;bottom:-16px;left:-24px;right:-24px;opacity:0;visibility:hidden;padding:12px 24px 48px 24px;border-radius:", ";transition:", ";background:transparent;", ";"], function (_ref2) { var theme = _ref2.theme; return theme.orbit.borderRadiusNormal; }, (0, _transition.default)(["all"], "fast", "ease-in-out"), function (_ref3) { var focused = _ref3.focused, theme = _ref3.theme; return focused && (0, _styledComponents.css)(["visibility:visible;opacity:1;background:", ";box-shadow:", ";"], theme.orbit.paletteWhite, theme.orbit.boxShadowRaised); }))); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198 StyledSliderContent.defaultProps = { theme: _defaultTheme.default }; var StyledSliderInput = _styledComponents.default.div.withConfig({ displayName: "Slider__StyledSliderInput", componentId: "j475w2-2" })(["display:flex;align-items:center;width:100%;height:24px;"]); var PureSlider = /*#__PURE__*/function (_React$PureComponent) { (0, _inherits2.default)(PureSlider, _React$PureComponent); var _super = _createSuper(PureSlider); function PureSlider() { var _this; (0, _classCallCheck2.default)(this, PureSlider); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _super.call.apply(_super, [this].concat(args)); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "bar", /*#__PURE__*/React.createRef()); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", { value: _this.props.defaultValue || _consts.default.VALUE, handleIndex: null, focused: false }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "pauseEvent", function (event) { if (typeof event.stopPropagation === "function") { event.stopPropagation(); } if (typeof event.preventDefault === "function" && (typeof event.cancelable !== "boolean" || event.cancelable)) { event.preventDefault(); } }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "stopPropagation", function (event) { if (typeof event.stopPropagation === "function") event.stopPropagation(); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isNotEqual", function (a, b) { if (Array.isArray(a) && Array.isArray(b)) { return a.toString() !== b.toString(); } return a !== b; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "calculateValue", function (ratio, addition, deduction) { var _this$props = _this.props, _this$props$maxValue = _this$props.maxValue, maxValue = _this$props$maxValue === void 0 ? _consts.default.MAX : _this$props$maxValue, _this$props$minValue = _this$props.minValue, minValue = _this$props$minValue === void 0 ? _consts.default.MIN : _this$props$minValue; return Math.round((maxValue - minValue + (addition ? 1 : 0)) * ratio + minValue - (deduction ? 1 : 0)); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "calculateValueFromPosition", function (pageX, throughClick) { var barRect = (0, _boundingClientRect.default)(_this.bar); if (barRect) { var _this$props2 = _this.props, histogramData = _this$props2.histogramData, histogramLoading = _this$props2.histogramLoading, rtl = _this$props2.theme.rtl; var _this$state = _this.state, handleIndex = _this$state.handleIndex, _value = _this$state.value; var mousePosition = (rtl ? barRect.right : pageX) - (rtl ? pageX : barRect.left); var positionRatio = mousePosition / barRect.width; var _hasHistogram = histogramLoading || !!histogramData; // when range slider if (Array.isArray(_value)) { if (_value[0] === _value[_value.length - 1]) { if (_this.calculateValue(positionRatio, true, true) >= _value[_value.length - 1]) { return _this.calculateValue(positionRatio, true, true); } return _this.calculateValue(positionRatio, true); } if (_this.isNotEqual(_this.sortArray(_value), _value)) { if (handleIndex === 0) { return _this.calculateValue(positionRatio, true, true); } return _this.calculateValue(positionRatio, true); } var closestKey = _this.findClosestKey(_this.calculateValue(positionRatio), _this.sortArray(_value)); // when first handle of range slider or when clicked and it should move the first handle if (handleIndex === 0 || throughClick && closestKey === 0) { return _this.calculateValue(positionRatio, true); } } // simple slider without histogram if (handleIndex === null && !_hasHistogram) { return _this.calculateValue(positionRatio); } return _this.calculateValue(positionRatio, true, true); } return null; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "sortArray", function (arr) { if (Array.isArray(arr)) { return arr.slice().sort(function (a, b) { return a - b; }); } return arr; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "findClosestKey", function (goal, value) { return Array.isArray(value) ? value.reduce(function (acc, curr, index) { return Array.isArray(value) && Math.abs(curr - goal) < Math.abs(value[acc] - goal) ? index : acc; }, 0) : null; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "moveValueByStep", function (step, forcedValue) { var _this$state2 = _this.state, value = _this$state2.value, handleIndex = _this$state2.handleIndex; if (Array.isArray(value)) { return _this.replaceValue(forcedValue || _this.alignValue(value[Number(handleIndex)] + step), Number(handleIndex)); } return forcedValue || _this.alignValue(value + step); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleKeyDown", function (event) { if (event.ctrlKey || event.shiftKey || event.altKey) return; var _this$props3 = _this.props, _this$props3$step = _this$props3.step, step = _this$props3$step === void 0 ? _consts.default.STEP : _this$props3$step, _this$props3$minValue = _this$props3.minValue, minValue = _this$props3$minValue === void 0 ? _consts.default.MIN : _this$props3$minValue, _this$props3$maxValue = _this$props3.maxValue, maxValue = _this$props3$maxValue === void 0 ? _consts.default.MAX : _this$props3$maxValue, rtl = _this$props3.theme.rtl; if (event.keyCode === _keyMaps.default.ARROW_UP) { _this.pauseEvent(event); _this.injectCallbackAndSetState(_this.props.onChange, _this.moveValueByStep(step)); } if (event.keyCode === _keyMaps.default.ARROW_DOWN) { _this.pauseEvent(event); _this.injectCallbackAndSetState(_this.props.onChange, _this.moveValueByStep(-step)); } if (event.keyCode === _keyMaps.default.ARROW_RIGHT) { var switchStep = rtl ? -step : step; _this.pauseEvent(event); _this.injectCallbackAndSetState(_this.props.onChange, _this.moveValueByStep(switchStep)); } if (event.keyCode === _keyMaps.default.ARROW_LEFT) { var _switchStep = rtl ? step : -step; _this.pauseEvent(event); _this.injectCallbackAndSetState(_this.props.onChange, _this.moveValueByStep(_switchStep)); } if (event.keyCode === _keyMaps.default.HOME) { _this.pauseEvent(event); _this.injectCallbackAndSetState(_this.props.onChange, _this.moveValueByStep(0, minValue)); } if (event.keyCode === _keyMaps.default.END) { _this.pauseEvent(event); _this.injectCallbackAndSetState(_this.props.onChange, _this.moveValueByStep(0, maxValue)); } }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleBlur", function () { _this.setState({ focused: false }); var value = _this.state.value; window.removeEventListener("keydown", _this.handleKeyDown); window.removeEventListener("focusout", _this.handleBlur); _this.injectCallbackAndSetState(_this.props.onChangeAfter, value, true); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleOnFocus", function (i) { return function (event) { if (typeof i === "number") _this.setState({ handleIndex: i }); var value = _this.state.value; _this.setState({ focused: true }); _this.pauseEvent(event); window.addEventListener("keydown", _this.handleKeyDown); window.addEventListener("focusout", _this.handleBlur); _this.injectCallbackAndSetState(_this.props.onChangeBefore, value, true); }; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleMove", function (newValue) { var _this$state3 = _this.state, value = _this$state3.value, handleIndex = _this$state3.handleIndex; if (newValue != null) { if (Array.isArray(value)) { return _this.replaceValue(_this.alignValue(newValue), Number(handleIndex)); } return _this.alignValue(newValue); } return null; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleBarMouseDown", function (event) { var value = _this.state.value; _this.setState({ handleIndex: null }); var newValue = _this.calculateValueFromPosition(event.pageX, true); if (newValue) { if (Array.isArray(value)) { var _index = _this.findClosestKey(newValue, value); var replacedValue = _this.replaceValue(_this.alignValue(newValue), _index); _this.injectCallbackAndSetState(_this.props.onChangeBefore, value, true); _this.injectCallbackAndSetState(_this.props.onChange, replacedValue); _this.injectCallbackAndSetState(_this.props.onChangeAfter, replacedValue); } else { var alignedValue = _this.alignValue(newValue); _this.injectCallbackAndSetState(_this.props.onChangeBefore, value, true); _this.injectCallbackAndSetState(_this.props.onChange, alignedValue); _this.injectCallbackAndSetState(_this.props.onChangeAfter, alignedValue); } } }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "injectCallbackAndSetState", function (callback, newValue) { var forced = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var value = _this.state.value; if (newValue != null) { if (_this.isNotEqual(newValue, value) || forced) { _this.setState({ value: newValue }); if (callback) { callback(_this.sortArray(newValue)); } } } }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleMouseMove", function (event) { var newValue = _this.calculateValueFromPosition(event.pageX); _this.pauseEvent(event); _this.injectCallbackAndSetState(_this.props.onChange, _this.handleMove(newValue)); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleMouseUp", function () { var value = _this.state.value; _this.setState({ focused: false }); window.removeEventListener("mousemove", _this.handleMouseMove); window.removeEventListener("mouseup", _this.handleMouseUp); _this.injectCallbackAndSetState(_this.props.onChangeAfter, value, true); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleMouseDown", function (i) { return function (event) { // just allow left-click if (event.button === 0 && event.buttons !== 2) { var _value2 = _this.state.value; _this.setState({ focused: true }); if (typeof i === "number") _this.setState({ handleIndex: i }); window.addEventListener("mousemove", _this.handleMouseMove); window.addEventListener("mouseup", _this.handleMouseUp); _this.pauseEvent(event); _this.injectCallbackAndSetState(_this.props.onChangeBefore, _value2, true); } }; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleOnTouchMove", function (event) { if (event.touches.length > 1) return; var newValue = _this.calculateValueFromPosition(event.touches[0].pageX); _this.pauseEvent(event); _this.injectCallbackAndSetState(_this.props.onChange, _this.handleMove(newValue)); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleTouchEnd", function () { var value = _this.state.value; _this.setState({ focused: false }); window.removeEventListener("touchmove", _this.handleOnTouchMove); window.removeEventListener("touchend", _this.handleTouchEnd); _this.injectCallbackAndSetState(_this.props.onChangeAfter, value, true); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleOnTouchStart", function (i) { return function (event) { if (event.touches.length <= 1) { _this.setState({ focused: true }); var _value3 = _this.state.value; if (typeof i === "number") _this.setState({ handleIndex: i }); window.addEventListener("touchmove", _this.handleOnTouchMove, { passive: false }); window.addEventListener("touchend", _this.handleTouchEnd); _this.stopPropagation(event); _this.injectCallbackAndSetState(_this.props.onChangeBefore, _value3, true); } }; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "alignValueToStep", function (value) { var _this$props$step = _this.props.step, step = _this$props$step === void 0 ? _consts.default.STEP : _this$props$step; if (step === 1) return value; var gap = value % step; if (gap === 0) return value; if (gap * 2 >= step) { return value - gap + step; } return value - gap; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "alignValueToMaxMin", function (value) { var _this$props4 = _this.props, _this$props4$maxValue = _this$props4.maxValue, maxValue = _this$props4$maxValue === void 0 ? _consts.default.MAX : _this$props4$maxValue, _this$props4$minValue = _this$props4.minValue, minValue = _this$props4$minValue === void 0 ? _consts.default.MIN : _this$props4$minValue; if (value > maxValue) { return maxValue; } if (value < minValue) { return minValue; } return value; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "alignValue", function (value) { return _this.alignValueToMaxMin(_this.alignValueToStep(value)); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "replaceValue", function (newValue, index) { var value = _this.state.value; if (index == null || !Array.isArray(value)) return newValue; return value.map(function (item, key) { return key === index ? newValue : item; }); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderHandle", function (valueNow, i) { var _this$props5 = _this.props, _this$props5$minValue = _this$props5.minValue, minValue = _this$props5$minValue === void 0 ? _consts.default.MIN : _this$props5$minValue, _this$props5$maxValue = _this$props5.maxValue, maxValue = _this$props5$maxValue === void 0 ? _consts.default.MAX : _this$props5$maxValue, histogramData = _this$props5.histogramData, histogramLoading = _this$props5.histogramLoading, ariaValueText = _this$props5.ariaValueText, ariaLabel = _this$props5.ariaLabel; var _this$state4 = _this.state, handleIndex = _this$state4.handleIndex, value = _this$state4.value; var key = i && encodeURIComponent(i.toString()); var index = i || 0; return /*#__PURE__*/React.createElement(_Handle.default, { tabIndex: "0", onTop: handleIndex === i, valueMax: maxValue, valueMin: minValue, onMouseDown: _this.handleMouseDown(i), onFocus: _this.handleOnFocus(i), onTouchStart: _this.handleOnTouchStart(i), value: value, ariaValueText: ariaValueText, ariaLabel: ariaLabel, hasHistogram: histogramLoading || !!histogramData, index: index, key: key, dataTest: "SliderHandle-".concat(index) }); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderHandles", function () { var value = _this.state.value; return Array.isArray(value) ? value.map(function (valueNow, i) { return _this.renderHandle(valueNow, i); }) : _this.renderHandle(value); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderSliderTexts", function (biggerSpace) { var _this$props6 = _this.props, label = _this$props6.label, valueDescription = _this$props6.valueDescription, histogramDescription = _this$props6.histogramDescription; if (!(label || valueDescription || histogramDescription)) return null; return /*#__PURE__*/React.createElement(_Stack.default, { direction: "row", spacing: "none", spaceAfter: biggerSpace ? "medium" : "small" }, (label || histogramDescription) && /*#__PURE__*/React.createElement(_Stack.default, { direction: "column", spacing: "none", basis: "60%", grow: true }, label && /*#__PURE__*/React.createElement(_Heading.default, { type: "title4" }, label), valueDescription && /*#__PURE__*/React.createElement(_Text.default, { type: "secondary", size: "small" }, valueDescription)), histogramDescription && /*#__PURE__*/React.createElement(_Stack.default, { shrink: true, justify: "end", grow: false }, /*#__PURE__*/React.createElement(_Text.default, { type: "primary", size: "small" }, histogramDescription))); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderHeading", function (hasHistogram) { if (hasHistogram) { return /*#__PURE__*/React.createElement(_Hide.default, { on: ["smallMobile", "mediumMobile", "largeMobile"], block: true }, _this.renderSliderTexts(true)); } return _this.renderSliderTexts(true); }); return _this; } (0, _createClass2.default)(PureSlider, [{ key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { var _this$props$defaultVa = this.props.defaultValue, defaultValue = _this$props$defaultVa === void 0 ? _consts.default.VALUE : _this$props$defaultVa; var _prevProps$defaultVal = prevProps.defaultValue, prevDefaultValue = _prevProps$defaultVal === void 0 ? _consts.default.VALUE : _prevProps$defaultVal; if (this.isNotEqual(prevDefaultValue, defaultValue)) { var _newValue = Array.isArray(defaultValue) ? defaultValue.map(function (item) { return Number(item); }) : Number(defaultValue); // eslint-disable-next-line react/no-did-update-set-state this.setState({ value: _newValue }); } } }, { key: "render", value: function render() { var _this$props7 = this.props, _this$props7$minValue = _this$props7.minValue, minValue = _this$props7$minValue === void 0 ? _consts.default.MIN : _this$props7$minValue, _this$props7$maxValue = _this$props7.maxValue, maxValue = _this$props7$maxValue === void 0 ? _consts.default.MAX : _this$props7$maxValue, histogramData = _this$props7.histogramData, _this$props7$histogra = _this$props7.histogramLoading, histogramLoading = _this$props7$histogra === void 0 ? false : _this$props7$histogra, histogramLoadingText = _this$props7.histogramLoadingText, dataTest = _this$props7.dataTest, _this$props7$step = _this$props7.step, step = _this$props7$step === void 0 ? _consts.default.STEP : _this$props7$step; if (histogramData) { var properHistogramLength = (maxValue - minValue + step) / step; process.env.NODE_ENV !== "production" ? (0, _js.warning)(histogramData.length === properHistogramLength, "Warning: Length of histogramData array is ".concat(histogramData.length, ", but should be ").concat(properHistogramLength, ". This will cause broken visuals of the whole Histogram.")) : void 0; } var _this$state5 = this.state, value = _this$state5.value, focused = _this$state5.focused; var sortedValue = this.sortArray(value); var hasHistogram = histogramLoading || !!histogramData; return /*#__PURE__*/React.createElement(StyledSlider, { "data-test": dataTest }, this.renderHeading(hasHistogram), hasHistogram && /*#__PURE__*/React.createElement(StyledSliderContent, { focused: focused }, this.renderSliderTexts(false), /*#__PURE__*/React.createElement(_Histogram.default, { data: histogramData, value: sortedValue, min: minValue, step: step, loading: histogramLoading, loadingText: histogramLoadingText })), /*#__PURE__*/React.createElement(StyledSliderInput, null, /*#__PURE__*/React.createElement(_Bar.default, { ref: this.bar, onMouseDown: this.handleBarMouseDown, value: sortedValue, max: maxValue, min: minValue, hasHistogram: hasHistogram }), this.renderHandles())); } }]); return PureSlider; }(React.PureComponent); exports.PureSlider = PureSlider; (0, _defineProperty2.default)(PureSlider, "defaultProps", { theme: _defaultTheme.default }); var ThemedSlider = (0, _styledComponents.withTheme)(PureSlider); ThemedSlider.displayName = "Slider"; var _default = ThemedSlider; exports.default = _default;