UNPKG

@massds/mayflower-react

Version:

React versions of Mayflower design system UI components

307 lines (254 loc) 10.2 kB
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } 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; } /** * MultiSelectDropDown module. * @module @massds/mayflower-react/MultiSelectDropDown * @requires module:@massds/mayflower-assets/scss/02-molecules/multiselect-dropdown * @requires module:@massds/mayflower-assets/scss/01-atoms/input-checkbox * @requires module:@massds/mayflower-assets/scss/02-molecules/tags * @requires module:@massds/mayflower-assets/scss/01-atoms/button-tag * @requires module:@massds/mayflower-assets/scss/01-atoms/svg-icons * @requires module:@massds/mayflower-assets/scss/01-atoms/svg-loc-icons */ import React from "react"; import PropTypes from "prop-types"; import classNames from "classnames"; import InputCheckBox from "../InputCheckBox/index.mjs"; import Tags from "../Tags/index.mjs"; export const getObjByValue = (arr, value, key) => { let i = 0; const arrayMax = arr.length; for (; i < arrayMax; i += 1) { const item = arr[i]; if (item[key] === value) { return item; } } return undefined; }; let MultiSelectDropDown = /*#__PURE__*/function (_React$Component) { _inheritsLoose(MultiSelectDropDown, _React$Component); function MultiSelectDropDown(props) { var _this; _this = _React$Component.call(this, props) || this; _defineProperty(_assertThisInitialized(_this), "_timeoutID", void 0); _defineProperty(_assertThisInitialized(_this), "onBlur", () => { // Time out to wait for React processing delay on activeElement _this._timeoutID = setTimeout(() => { if (document.activeElement !== null) { if (!_this.wrapperRef.contains(document.activeElement)) { _this.setState({ dropwDownExpand: false }); } } }, 0); }); _defineProperty(_assertThisInitialized(_this), "handleTagClick", (target, e) => { e.stopPropagation(); const val = target.getAttribute('data-ma-filter-value'); const values = _this.state.values; values.splice(values.indexOf(val), 1); _this.setState({ values: values, dropwDownExpand: true }); }); _defineProperty(_assertThisInitialized(_this), "handleClearAll", () => { _this.setState({ values: [] }); _this.focusOnComboBox(); }); _defineProperty(_assertThisInitialized(_this), "handleClickOutside", event => { // Close the panel if the user clicks outside the component. const node = _this.wrapperRef; if (node && !node.contains(event.target)) { if (_this.state.dropwDownExpand) { _this.closeDropDown(); } } }); _defineProperty(_assertThisInitialized(_this), "handleDropDownKeyDown", event => { if (event.key === 'Enter') { _this.handleSelect(event); } }); _defineProperty(_assertThisInitialized(_this), "handleSelect", event => { const value = event.target.value; const values = _this.state.values; if (values.indexOf(value) > -1) { values.splice(values.indexOf(value), 1); } else { values.push(value); } _this.setState({ values: values }); }); _defineProperty(_assertThisInitialized(_this), "handleKeyDown", event => { // Detect onBlur using tab key if (event.key === 'Tab') { _this.onBlur(); } // If the user pressed escape collapse list. if (event.key === 'Escape') { _this.closeDropDown(); _this.focusOnComboBox(); } let index = -1; const tagName = event.target.tagName; if (tagName === 'INPUT') { const targetId = event.target.id; index = Number(targetId.split('-').pop()); } const nextIndex = index + 1; const prevIndex = index - 1; if (event.key === 'ArrowUp') { if (prevIndex === -1) { _this.focusOnComboBox(); } if (prevIndex >= 0) { const prevItem = document.getElementById("input-checkbox-" + prevIndex); if (prevItem) { prevItem.focus(); } } } if (event.key === 'ArrowDown' && nextIndex < _this.props.dropdownItems.length) { const nextItem = document.getElementById("input-checkbox-" + nextIndex); if (nextItem) { nextItem.focus(); } } }); _defineProperty(_assertThisInitialized(_this), "focusOnComboBox", () => { const comboBox = document.getElementById(_this.props.fieldName + "-multiselect-combobox"); comboBox.focus(); }); _defineProperty(_assertThisInitialized(_this), "handleClick", () => { _this.toggleDropDown(); }); _defineProperty(_assertThisInitialized(_this), "handleComboBoxKeyDown", event => { event.stopPropagation(); if (event.key === 'Enter') { _this.toggleDropDown(); } }); _defineProperty(_assertThisInitialized(_this), "toggleDropDown", () => { _this.setState(prevState => ({ dropwDownExpand: !prevState.dropwDownExpand })); }); _defineProperty(_assertThisInitialized(_this), "closeDropDown", () => { _this.setState({ dropwDownExpand: false }); }); _this.state = { values: [], dropwDownExpand: false }; return _this; } var _proto = MultiSelectDropDown.prototype; _proto.componentDidMount = function componentDidMount() { this.buttonClicked = false; document.addEventListener('mousedown', e => this.handleClickOutside(e)); this.wrapperRef.addEventListener('keydown', e => this.handleKeyDown(e)); }; _proto.componentWillUnmount = function componentWillUnmount() { document.removeEventListener('mousedown', () => this.handleClickOutside()); this.wrapperRef.removeEventListener('keydown', () => this.handleKeyDown()); this.wrapperRef.removeEventListener('onblur', e => this.handleKeyDown(e)); }; _proto.render = function render() { var _classNames; const _this$props = this.props, dropdownItems = _this$props.dropdownItems, fieldName = _this$props.fieldName, title = _this$props.title, titleClasses = _this$props.titleClasses, defaultText = _this$props.defaultText; const _this$state = this.state, values = _this$state.values, dropwDownExpand = _this$state.dropwDownExpand; const tags = values.map(val => getObjByValue(dropdownItems, val, 'value')); const tagsProps = { tags: tags.map(tag => ({ value: tag.value, text: tag.label, type: fieldName })), onClearThisCallback: this.handleTagClick, onClearCallback: this.handleClearAll }; const titleCls = classNames((_classNames = {}, _classNames[titleClasses.join(' ')] = true, _classNames)); return /*#__PURE__*/React.createElement("div", { className: "ma__multiselect-dropdown", ref: node => { this.wrapperRef = node; } }, /*#__PURE__*/React.createElement("fieldset", { className: "group" }, /*#__PURE__*/React.createElement("legend", { className: titleClasses.length > 0 ? titleCls : null }, title), /*#__PURE__*/React.createElement("div", { role: "combobox", tabIndex: 0, "aria-expanded": dropwDownExpand, "aria-controls": fieldName + "-multiselect", id: fieldName + "-multiselect-combobox", "aria-haspopup": true, className: "ma__select-box__field", onClick: this.handleClick, onKeyDown: this.handleComboBoxKeyDown }, /*#__PURE__*/React.createElement("div", { className: "ma__select-box__link" }, /*#__PURE__*/React.createElement("span", { className: "js-dropdown-link" }, values.length > 0 ? /*#__PURE__*/React.createElement(Tags, tagsProps) : defaultText), /*#__PURE__*/React.createElement("span", { className: "ma__select-box__icon" }))), dropwDownExpand && /*#__PURE__*/React.createElement("div", { id: fieldName + "-multiselect", className: "ma__multiselect-dropdown-menu ma__multiselect-dropdown-menu--expanded" }, dropdownItems.map((item, i) => /*#__PURE__*/React.createElement(InputCheckBox, { id: "input-checkbox-" + i /* eslint-disable-next-line react/no-array-index-key */ , key: "input-checkbox-" + i, name: fieldName, value: item.value, label: item.label, onChange: this.handleSelect, onKeyDown: this.handleDropDownKeyDown, classes: ['ma__multiselect-dropdown-item'], defaultValue: values.indexOf(item.value) > -1 ? item.value : false, tabIndex: -1 }))))); }; return MultiSelectDropDown; }(React.Component); MultiSelectDropDown.propTypes = process.env.NODE_ENV !== "production" ? { /** The legend title of the multiple select dropdown, can be a string, an element or a React component. */ title: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, /** Legend classes. */ titleClasses: PropTypes.arrayOf(PropTypes.string), /** Default display in dropdown field. */ defaultText: PropTypes.string, /** Custom callback on dropdown item selection. */ onItemSelect: PropTypes.func, /** Custom callback on dropdown click. */ onDropDownClick: PropTypes.func, /** An array of dropdown multiselect items */ dropdownItems: PropTypes.arrayOf(PropTypes.shape({ text: PropTypes.string, href: PropTypes.string })), /** Field name attribute that is used for grouping DOM submission and identify tags type */ fieldName: PropTypes.string } : {}; MultiSelectDropDown.defaultProps = { titleClasses: [] }; export default MultiSelectDropDown;