UNPKG

@shopgate/pwa-common

Version:

Common library for the Shopgate Connect PWA.

183 lines (180 loc) 5.43 kB
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose"; import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import find from 'lodash/find'; import Dropdown from "../Dropdown"; import I18n from "../I18n"; import SelectBoxItem from "./components/Item"; import styles from "./style"; /** * The select box component. */ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; let SelectBox = /*#__PURE__*/function (_Component) { /** * Initializes the component. * @param {Object} props The components props. */ function SelectBox(props) { var _this; _this = _Component.call(this, props) || this; /** * Handles any interaction the user does outside of the component. * In this case the select gets closed. * @param {Object} event The event object. */ _this.handleInteractionOutside = event => { _this.setState({ isOpen: false }); event.preventDefault(); event.stopPropagation(); }; /** * Sets the open state to true */ _this.handleOpenList = () => { if (_this.state.isOpen) { return; } _this.setState({ isOpen: true }); if (_this.firstItemRef) { _this.firstItemRef.focus(); } }; /** * Sets the new active selection. * @param {string} value Value of the selected item. */ _this.handleSelectionUpdate = value => { const selection = find(_this.props.items, { value }); _this.setState({ selected: selection, isOpen: false }); // Delay the callback to make sure actions are fired after animations are done. setTimeout(() => { _this.props.handleSelectionUpdate(selection.value); }, _this.props.duration); if (_this.controlRef) { _this.controlRef.focus(); } }; /** @param {HTMLElement} ref The element */ _this.setControlRef = ref => { _this.controlRef = ref; }; /** @param {HTMLElement} ref The element */ _this.setFirstItemRef = ref => { _this.firstItemRef = ref; }; _this.state = { isOpen: false, selected: find(props.items, { value: props.initialValue }) }; return _this; } /** * Reset selected when changing the initial value. * @param {Object} nextProps The next props the component will receive. */ _inheritsLoose(SelectBox, _Component); var _proto = SelectBox.prototype; _proto.UNSAFE_componentWillReceiveProps = function UNSAFE_componentWillReceiveProps(nextProps) { if (this.props.initialValue !== nextProps.initialValue) { this.setState({ selected: find(nextProps.items, { value: nextProps.initialValue }) }); } }; /** * Renders the component * @returns {JSX} */ _proto.render = function render() { const Icon = this.props.icon; const { icon, iconOpen = null, selection, button, dropdown, selectItem, selectItemSelected } = this.props.classNames; const buttonLabel = this.state.selected ? this.state.selected.label : this.props.defaultText; const iconClasses = classNames(icon, { [iconOpen]: this.state.isOpen && iconOpen !== null }); return /*#__PURE__*/_jsxs("div", { className: `${this.props.className} common__select-box`, "data-test-id": this.props.testId, children: [/*#__PURE__*/_jsxs("button", { className: button, onClick: this.handleOpenList, "data-test-id": buttonLabel, type: "button", "aria-haspopup": true, "aria-expanded": this.state.isOpen ? true : null, "aria-controls": buttonLabel, ref: this.setControlRef, children: [/*#__PURE__*/_jsx("span", { className: selection, children: /*#__PURE__*/_jsx(I18n.Text, { string: buttonLabel }) }), /*#__PURE__*/_jsx("div", { className: iconClasses, children: /*#__PURE__*/_jsx(Icon, {}) })] }), /*#__PURE__*/_jsx(Dropdown, { className: dropdown, isOpen: this.state.isOpen, duration: this.props.duration, children: /*#__PURE__*/_jsx("ul", { role: "menu", id: buttonLabel, tabIndex: "-1", children: this.props.items.map(item => /*#__PURE__*/_jsx(SelectBoxItem, { classNames: { selectItem, selectItemSelected }, wrapper: this.props.item, value: item.value, label: item.label, handleSelectionUpdate: this.handleSelectionUpdate, isSelected: buttonLabel === item.label, forwardedRef: buttonLabel === item.label ? this.setFirstItemRef : null }, item.value)) }) }), this.state.isOpen && /*#__PURE__*/_jsx("button", { className: styles.overlay, onClick: this.handleInteractionOutside, onTouchMove: this.handleInteractionOutside, type: "button", "aria-hidden": true })] }); }; return SelectBox; }(Component); SelectBox.defaultProps = { className: '', classNames: {}, duration: 225, defaultText: 'filter.sort.default', handleSelectionUpdate: () => {}, initialValue: null, testId: null }; export default SelectBox;