UNPKG

@zohodesk/components

Version:

Dot UI is a customizable React component library built to deliver a clean, accessible, and developer-friendly UI experience. It offers a growing set of reusable components designed to align with modern design systems and streamline application development

1,108 lines (1,020 loc) • 36.7 kB
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import React from 'react'; import { AdvancedGroupMultiSelect_propTypes } from "./props/propTypes"; import { AdvancedGroupMultiSelect_defaultProps } from "./props/defaultProps"; import { MULTISELECT_I18N_KEYS } from "./constants"; /**** Components ****/ import Loader from '@zohodesk/svg/lib/Loader/Loader'; import Popup from "../Popup/Popup"; import TextBoxIcon from "../TextBoxIcon/TextBoxIcon"; import { Container, Box } from "../Layout"; import DropDownHeading from "../DropDown/DropDownHeading"; import MultiSelectHeader from "../MultiSelect/MultiSelectHeader"; import SelectedOptions from "../MultiSelect/SelectedOptions"; import Suggestions from "../MultiSelect/Suggestions"; import EmptyState from "../MultiSelect/EmptyState"; import Card, { CardContent, CardHeader, CardFooter } from "../Card/Card"; import { getUniqueId } from "../Provider/IdProvider"; import ResponsiveDropBox from "../ResponsiveDropBox/ResponsiveDropBox"; import { ResponsiveReceiver } from "../Responsive/CustomResponsive"; /**** Constants ****/ import { DUMMY_OBJECT } from "./../utils/Common"; /**** Icons ****/ import { Icon } from '@zohodesk/icons'; /**** CSS ****/ import style from "./MultiSelect.module.css"; /**** Methods ****/ import { debounce, scrollTo, getIsEmptyValue, getSearchString } from "../utils/Common.js"; import { makeGetMultiSelectSelectedOptions, makeGetGroupSelectOptions, optionIdGrouping, makeGetGroupSelectFilterSuggestions, makeGetOptionIdChange, extractOptionId, makeFormatOptions, makeObjectConcat } from "../utils/dropDownUtils"; /* eslint-disable react/forbid-component-props */ /* eslint-disable react/no-unused-prop-types */ class AdvancedGroupMultiSelect extends React.Component { constructor(props) { super(props); this.getNextAriaId = getUniqueId(this); this.objectConcat = makeObjectConcat(); this.getGroupSelectOptions = makeGetGroupSelectOptions(); this.getFilterSuggestions = makeGetGroupSelectFilterSuggestions(); this.getSelectedOptions = makeGetMultiSelectSelectedOptions(); this.getOptionIdChange = makeGetOptionIdChange(); this.formatSelectedOptions = makeFormatOptions(); let { searchDebounceTime = 500, selectedGroupOptions } = props; let { revampedGroups, normalizedAllOptions, normalizedFormatOptions, allOptionIds, groupIds, normalizedGroupedOptions: groupDetails } = this.handleGetGroupSelectOptions(props); let changedSelectedOptionDetails = this.handleSelectedOptionDetailsIdChange(props, { groupIds, groupDetails }); let { normalizedSelectedOptions } = this.handleGetSelectedOptions(changedSelectedOptionDetails); let { formatSelectedOptions, selectedOptionIds } = this.handleSelectedOptionIdChange(selectedGroupOptions, normalizedFormatOptions, normalizedSelectedOptions); this.handleGetGroupSelectOptions = this.handleGetGroupSelectOptions.bind(this); this.selectedOptionContainerRef = this.selectedOptionContainerRef.bind(this); this.suggestionContainerRef = this.suggestionContainerRef.bind(this); this.suggestionItemRef = this.suggestionItemRef.bind(this); this.searchInputRef = this.searchInputRef.bind(this); this.handleScroll = this.handleScroll.bind(this); this.handleScrollFuncCall = debounce(this.handleScrollFuncCall.bind(this), 500); this.handleInputCick = this.handleInputCick.bind(this); this.togglePopup = this.togglePopup.bind(this); this.handleSelectedOptionIdChange = this.handleSelectedOptionIdChange.bind(this); this.handleMouseEnter = this.handleMouseEnter.bind(this); this.handleSelectOption = this.handleSelectOption.bind(this); this.selectedOptionRef = this.selectedOptionRef.bind(this); this.handleClickSelectedOption = this.handleClickSelectedOption.bind(this); this.handleRemoveOption = this.handleRemoveOption.bind(this); this.handleKeyDown = this.handleKeyDown.bind(this); this.handleChange = this.handleChange.bind(this); this.handleFetchOptions = this.handleFetchOptions.bind(this); this.handleSearch = this.handleSearch.bind(this); this.handleSearchOptions = debounce(this.handleSearchOptions.bind(this), searchDebounceTime); this.handleSelectAll = this.handleSelectAll.bind(this); this.handleDeselectAll = this.handleDeselectAll.bind(this); this.handleActive = this.handleActive.bind(this); this.handleInactive = this.handleInactive.bind(this); this.handleInputFocus = this.handleInputFocus.bind(this); this.state = { isActive: false, searchStr: '', revampedGroups, normalizedAllOptions, normalizedFormatOptions, allOptionIds, selectedOptionIds, formatSelectedOptions, hoverIndex: 0, highLightedSelectOptions: [], lastHighLightedSelectOption: '', shiftKeyPressHighLighted: 0, isActive: false, isFetchingOptions: false, groupIds, groupDetails }; this._isMounted = false; } handleGetSelectedOptions(selectedOptionDetails) { let { normalizedFormatOptions: normalizedSelectedOptions } = this.handleFormatSelectedOptions(selectedOptionDetails, this.props); return { normalizedSelectedOptions }; } handleFormatSelectedOptions(selectedOptionDetails, props) { let { valueField, textField, allowValueFallback } = props; return this.formatSelectedOptions({ options: selectedOptionDetails, valueField, textField, allowValueFallback }); } handleSelectedOptionDetailsIdChange(props, state) { let { groupIds, groupDetails } = state; let { selectedOptionDetails = {} } = props; let newSelectedOptionDetails = []; groupIds.forEach(groupId => { let { valueField, textField, optionType } = groupDetails[groupId]; let changedDetails = this.getOptionIdChange({ options: selectedOptionDetails[groupId], valueField, prefixText: groupId, textField, optionType }); newSelectedOptionDetails = [...newSelectedOptionDetails, ...changedDetails]; }); return newSelectedOptionDetails; } selectedOptionRef(el, id) { this[`selectedOption_${id}`] = el; } suggestionContainerRef(el) { this.suggestionContainer = el; } selectedOptionContainerRef(el) { let { getTargetRef } = this.props; this.selectedOptionContainer = el; getTargetRef(el); } suggestionItemRef(el, index, id) { this[`suggestion_${id}`] = el; } searchInputRef(ref) { this.searchInput = ref; } handleSelectedOptionIdChange(selectedGroupOptions, normalizedFormatOptions, normalizedSelectedOptions) { const { allowValueFallback, limit } = this.props; let newSelectedOptions = selectedGroupOptions.map(option => optionIdGrouping(option.id, option.groupId)); let selectedOptionsLength = newSelectedOptions.length; let formatOptions = this.objectConcat({ obj1: normalizedFormatOptions, obj2: normalizedSelectedOptions }); return this.getSelectedOptions({ selectedOptions: newSelectedOptions, normalizedFormatOptions: formatOptions, selectedOptionsLength, allowValueFallback, limit }); } togglePopup(e) { let { togglePopup, defaultDropBoxPosition, isReadOnly } = this.props; !isReadOnly && togglePopup(e, defaultDropBoxPosition ? `${defaultDropBoxPosition}Center` : null); } handleFilterSuggestions() { let { revampedGroups, searchStr = '', allOptionIds } = this.state; let { needLocalSearch } = this.props; if (searchStr && searchStr.trim().length) { searchStr = getSearchString(searchStr); let { suggestionGroups, suggestionOptionIds } = this.getFilterSuggestions({ revampedGroups, searchStr, needSearch: needLocalSearch }); return { suggestionGroups, suggestionOptionIds }; } return { suggestionGroups: revampedGroups, suggestionOptionIds: allOptionIds }; } handleGetGroupSelectOptions(props) { let { allowValueFallback, groupedOptions = [] } = props; return this.getGroupSelectOptions({ groupedOptions, allowValueFallback }); } handleInputCick(e) { let { highLightedSelectOptions } = this.state; highLightedSelectOptions.length ? this.setState({ highLightedSelectOptions: [], shiftKeyPressHighLighted: 0, lastHighLightedSelectOption: '' }) : this.togglePopup(e); } handleClickSelectedOption(id = '', e) { let { selectedOptionIds } = this.state; let { highLightedSelectOptions, lastHighLightedSelectOption } = this.state; let { metaKey, ctrlKey, shiftKey } = e; if (e && shiftKey) { //shift+click let from = selectedOptionIds.indexOf(lastHighLightedSelectOption) >= 0 ? selectedOptionIds.indexOf(lastHighLightedSelectOption) : 0; let to = id && selectedOptionIds.indexOf(id) >= 0 ? selectedOptionIds.indexOf(id) : null; if (to >= 0 && to < from) { [to] = [from, from = to]; } to += 1; let newSelectedHighlights = to ? selectedOptionIds.slice(from, to) : []; to && this.setState({ highLightedSelectOptions: newSelectedHighlights, lastHighLightedSelectOption: id }); } else if (e && (ctrlKey || metaKey)) { //ctrl+click let isRemove = highLightedSelectOptions.indexOf(id) >= 0; let newSelectedHighlights = []; if (isRemove) { lastHighLightedSelectOption = id === lastHighLightedSelectOption ? '' : lastHighLightedSelectOption; newSelectedHighlights = highLightedSelectOptions.filter(option => option !== id); } else { lastHighLightedSelectOption = id; newSelectedHighlights = [...highLightedSelectOptions, id]; } this.setState({ highLightedSelectOptions: newSelectedHighlights, lastHighLightedSelectOption }); } else { this.setState({ highLightedSelectOptions: [id], lastHighLightedSelectOption: id }); } this.setState({ shiftKeyPressHighLighted: 0 }); this.searchInput && this.searchInput.focus({ preventScroll: true }); } handleRemoveOption(options) { let newOptions = !getIsEmptyValue(options) && !Array.isArray(options) ? [options] : options; let { isReadOnly } = this.props; let { selectedOptionIds } = this.state; let { highLightedSelectOptions, lastHighLightedSelectOption, shiftKeyPressHighLighted } = this.state; if (newOptions.length && !isReadOnly) { let newSelectedOptions = selectedOptionIds.filter(option => newOptions.indexOf(option) === -1); let newHighLightedSelectOptions = highLightedSelectOptions.filter(option => newSelectedOptions.indexOf(option) >= 0); let isHighlightedRemoved = false; let newOptionsLen = newOptions.length; for (let i = 0; i < newOptionsLen; i++) { let removedOption = newOptions[i]; if (highLightedSelectOptions.indexOf(removedOption) >= 0) { isHighlightedRemoved = true; break; } } this.setState({ lastHighLightedSelectOption: newSelectedOptions.indexOf(lastHighLightedSelectOption) >= 0 && !isHighlightedRemoved ? lastHighLightedSelectOption : '', highLightedSelectOptions: isHighlightedRemoved ? [] : newHighLightedSelectOptions, shiftKeyPressHighLighted: isHighlightedRemoved ? 0 : shiftKeyPressHighLighted }); this.handleChange(newSelectedOptions); } this.searchInput && this.searchInput.focus({ preventScroll: true }); } handleKeyDown(e) { let { keyCode, ctrlKey, metaKey, shiftKey } = e; let suggestions = []; let { hoverIndex, searchStr, highLightedSelectOptions, lastHighLightedSelectOption, shiftKeyPressHighLighted, selectedOptionIds: selectedOptions } = this.state; let { isNextOptions, getNextOptions, isPopupOpen, isPopupOpenOnEnter, onKeyDown, limit } = this.props; let highLightedSelectOptionsLen = highLightedSelectOptions.length; if (isPopupOpen && (keyCode === 38 || keyCode === 40 || keyCode === 13 || keyCode === 27)) { let { suggestionOptionIds } = this.handleFilterSuggestions(); suggestions = suggestionOptionIds; } if (!isPopupOpen && !isPopupOpenOnEnter) { onKeyDown && onKeyDown(e); } if (!isPopupOpen && keyCode === 40) { //down arrow press popup open e.preventDefault(); //prevent body scroll this.togglePopup(e); } let suggestionsLen = suggestions.length; if (suggestionsLen && isPopupOpen && keyCode === 38) { //up arrow /*if (hoverOption === 0) { //disable first to last option higlight !isNextOptions && this.setState({ hoverOption: suggestionsLen - 1 }); }*/ if (hoverIndex) { this.setState({ hoverIndex: hoverIndex - 1 }); } } else if (suggestionsLen && isPopupOpen && keyCode === 40) { //down arrow /*else if (hoverOption === suggestionsLen - 1 || hoverOption === null) { //disable last to first option higlight !isNextOptions && this.setState({ hoverOption: 0 }); }*/ if (isNextOptions && suggestionsLen >= 5 && hoverIndex === suggestionsLen - 3) { getNextOptions && this.handleFetchOptions(getNextOptions, searchStr); this.setState({ hoverIndex: hoverIndex + 1 }); } else if (suggestionsLen - 1 > hoverIndex) { this.setState({ hoverIndex: hoverIndex + 1 }); } } else if (keyCode === 13 && selectedOptions.length < limit) { //enter key let id = suggestions[hoverIndex] || {}; isPopupOpen && !getIsEmptyValue(id) && this.handleSelectOption(id, null, null, e); !isPopupOpen && isPopupOpenOnEnter && this.togglePopup(e); } else if (selectedOptions.length && keyCode === 8 && !searchStr.length) { //backspace key if (highLightedSelectOptionsLen) { this.handleRemoveOption(highLightedSelectOptions); } else { this.handleRemoveOption(selectedOptions.slice(-1)); // this.setState({ // highLightedSelectOptions: selectedOptions.slice(-1) // }); } } else if (selectedOptions && keyCode === 65 && (ctrlKey || metaKey) && !searchStr.length) { //ctrl+a key this.setState({ highLightedSelectOptions: selectedOptions, shiftKeyPressHighLighted: 0 }); } else if (keyCode === 39 && shiftKey && selectedOptions.length && !searchStr.length) { //shift+right arrow=39 let lastHighLightedSelectOptionIndex = lastHighLightedSelectOption && selectedOptions.indexOf(lastHighLightedSelectOption) >= 0 ? selectedOptions.indexOf(lastHighLightedSelectOption) : 0; let newShiftKeyPressHighLighted = shiftKeyPressHighLighted ? shiftKeyPressHighLighted : shiftKeyPressHighLighted + 1; let newHighLightedSelectOption = lastHighLightedSelectOptionIndex !== null ? selectedOptions[lastHighLightedSelectOptionIndex + newShiftKeyPressHighLighted] : selectedOptions[0]; if (!getIsEmptyValue(newHighLightedSelectOption)) { let newLastHighLightedSelectOption = lastHighLightedSelectOption ? lastHighLightedSelectOption : selectedOptions[0]; highLightedSelectOptions = !shiftKeyPressHighLighted ? [newLastHighLightedSelectOption] : highLightedSelectOptions; let isRemove = highLightedSelectOptions.indexOf(newHighLightedSelectOption) >= 0 && newHighLightedSelectOption !== lastHighLightedSelectOption ? true : false; let newHighLightedSelectOptions = isRemove ? highLightedSelectOptions.filter(option => option !== newHighLightedSelectOption) : [...highLightedSelectOptions, newHighLightedSelectOption]; this.setState({ highLightedSelectOptions: newHighLightedSelectOptions, shiftKeyPressHighLighted: newShiftKeyPressHighLighted + 1, lastHighLightedSelectOption: newLastHighLightedSelectOption }); } } else if (keyCode === 37 && shiftKey && selectedOptions.length && !searchStr.length) { // shift+left arrow=37 let lastHighLightedSelectOptionIndex = lastHighLightedSelectOption ? selectedOptions.indexOf(lastHighLightedSelectOption) : selectedOptions.length - 1; let newShiftKeyPressHighLighted = shiftKeyPressHighLighted !== 1 ? shiftKeyPressHighLighted : shiftKeyPressHighLighted - 1; let newHighLightedSelectOption = selectedOptions[lastHighLightedSelectOptionIndex + newShiftKeyPressHighLighted - 1]; if (!getIsEmptyValue(newHighLightedSelectOption)) { let newLastHighLightedSelectOption = lastHighLightedSelectOption ? lastHighLightedSelectOption : selectedOptions.slice(-1)[0]; highLightedSelectOptions = !shiftKeyPressHighLighted ? [newLastHighLightedSelectOption] : highLightedSelectOptions; let isRemove = highLightedSelectOptions.indexOf(newHighLightedSelectOption) >= 0 && newHighLightedSelectOption !== lastHighLightedSelectOption ? true : false; let newHighLightedSelectOptions = isRemove ? highLightedSelectOptions.filter(option => option !== newHighLightedSelectOption) : [...highLightedSelectOptions, newHighLightedSelectOption]; this.setState({ highLightedSelectOptions: newHighLightedSelectOptions, shiftKeyPressHighLighted: newShiftKeyPressHighLighted - 1, lastHighLightedSelectOption: newLastHighLightedSelectOption }); } } else if ((keyCode === 39 || keyCode === 37) && selectedOptions.length && !searchStr.length) { let isRightArrow = keyCode === 39 ? true : false; // let isLefttArrow = keyCode === 37 ? true : false; if (highLightedSelectOptions.length) { let [lastHighLightedSelectOption] = highLightedSelectOptions.slice(-1); let lastHighLightedSelectOptionIndex = selectedOptions.indexOf(lastHighLightedSelectOption); let newLastHighLightedSelectOptionIndex = isRightArrow ? lastHighLightedSelectOptionIndex === selectedOptions.length - 1 ? lastHighLightedSelectOptionIndex : lastHighLightedSelectOptionIndex + 1 : lastHighLightedSelectOptionIndex - 1; let newLastHighLightedSelectOption = selectedOptions[newLastHighLightedSelectOptionIndex]; let isEmptyHighlighted = isRightArrow && highLightedSelectOptions.length === 1 && selectedOptions.slice(-1)[0] === lastHighLightedSelectOption ? true : false; if (!getIsEmptyValue(newLastHighLightedSelectOption)) { this.setState({ lastHighLightedSelectOption: isEmptyHighlighted ? '' : newLastHighLightedSelectOption, highLightedSelectOptions: isEmptyHighlighted ? [] : [newLastHighLightedSelectOption], shiftKeyPressHighLighted: 0 }); } } else { let [newLastHighLightedSelectOption] = isRightArrow ? selectedOptions : selectedOptions.slice(-1); this.setState({ lastHighLightedSelectOption: newLastHighLightedSelectOption, highLightedSelectOptions: [newLastHighLightedSelectOption], shiftKeyPressHighLighted: 0 }); } } else if (keyCode === 27) {// this.handlePopupClose(e); } } handleMouseEnter(id, val, hoverOptionIndex, e) { e && e.preventDefault(); let { hoverIndex, allOptionIds } = this.state; let newHoverIndex = allOptionIds.indexOf(id); hoverIndex !== newHoverIndex && this.setState({ hoverIndex: newHoverIndex }); } handleFetchOptions(...args) { let [APICall, searchStr] = args; let { isFetchingOptions } = this.state; let { _isMounted } = this; if (!isFetchingOptions && APICall) { this.setState({ isFetchingOptions: true }); try { return APICall(searchStr).then(() => { _isMounted && this.setState({ isFetchingOptions: false }); }, () => { _isMounted && this.setState({ isFetchingOptions: false }); }); } catch (e) { _isMounted && this.setState({ isFetchingOptions: false }); } } } handleSearchOptions() { let { onSearch } = this.props; let { searchStr } = this.state; searchStr && this.handleFetchOptions(onSearch, searchStr); } handleSearch(value, e) { let { onSearch, isPopupOpen } = this.props; !isPopupOpen && e && this.togglePopup(e); let { searchStr = '' } = this.state; let searchStrRegex = getSearchString(searchStr); let valueStrRegex = getSearchString(value); let isSearch = searchStrRegex !== valueStrRegex ? true : false; this.setState({ searchStr: value }, () => { if (!value) { onSearch && onSearch(''); } else if (isSearch && onSearch) { this.handleSearchOptions(); } }); } handleScroll(e) { let { isNextOptions } = this.props; if (e.target.scrollTop + e.target.offsetHeight > e.target.scrollHeight - 1 && isNextOptions) { this.handleScrollFuncCall(); } } handleScrollFuncCall() { let { getNextOptions } = this.props; let { searchStr } = this.state; getNextOptions && getNextOptions(searchStr); } handleSelectAll(e) { e && e.preventDefault(); let { suggestionOptionIds } = this.handleFilterSuggestions(); let { selectedOptionIds } = this.state; let newSelectedOptions = suggestionOptionIds.filter(id => selectedOptionIds.indexOf(id) === -1); this.handleChange([...selectedOptionIds, ...newSelectedOptions]); } handleDeselectAll(e) { e && e.preventDefault(); let { highLightedSelectOptions } = this.state; if (highLightedSelectOptions.length) { this.setState({ highLightedSelectOptions: [], lastHighLightedSelectOption: '' }); } this.handleChange([]); } handleChange(selectedOptions = [], e) { let { onChange, needToCloseOnSelect, togglePopup, isSearchClearOnSelect } = this.props; let { searchStr } = this.state; let newSelectedOptions = selectedOptions.map(option => extractOptionId(option)); onChange([...newSelectedOptions]); if (searchStr.trim() != '' && isSearchClearOnSelect) { this.handleSearch(''); } this.searchInput && this.searchInput.focus({ preventScroll: true }); if (needToCloseOnSelect) { e && togglePopup(e); } } handleSelectOption(id, val, index, e) { e && e.preventDefault(); let { selectedOptionIds } = this.state; if (selectedOptionIds.indexOf(id) === -1) { this.handleChange([...selectedOptionIds, id], e); } else { this.handleRemoveOption(id); } } handleActive(e) { let { searchStr, isActive } = this.state; if (!isActive) { this.setState({ isActive: true }); } let { target } = e || {}; target && target.setSelectionRange(target, 0); let { onFocus } = this.props; onFocus && onFocus(searchStr); } handleInactive() { let { isActive } = this.state; if (isActive) { this.setState({ isActive: false }); } } handleInputFocus() { let { isDisabled, isReadOnly } = this.props; this.searchInput && !isDisabled && !isReadOnly && this.searchInput.focus({ preventScroll: true }); } componentDidMount() { this._isMounted = true; } componentWillUnmount() { this._isMounted = false; } componentDidUpdate(prevProps) { let { groupedOptions, selectedGroupOptions, isPopupOpen, selectedOptionDetails, searchStr, notifyPopupToggle } = this.props; let { normalizedFormatOptions, hoverIndex } = this.state; let newOptionIds = this.state.allOptionIds; if (prevProps.groupedOptions != groupedOptions) { let { revampedGroups, normalizedAllOptions, normalizedFormatOptions: formatNoramlizer, allOptionIds, groupIds, normalizedGroupedOptions } = this.handleGetGroupSelectOptions(this.props); normalizedFormatOptions = formatNoramlizer; newOptionIds = allOptionIds; this.setState({ revampedGroups, normalizedAllOptions, normalizedFormatOptions: formatNoramlizer, allOptionIds, groupIds, groupDetails: normalizedGroupedOptions }); } if (prevProps.selectedOptionDetails != selectedOptionDetails || prevProps.selectedGroupOptions != selectedGroupOptions) { let { groupDetails, groupIds } = this.state; let changedSelectedOptionDetails = this.handleSelectedOptionDetailsIdChange(this.props, { groupIds, groupDetails }); let { normalizedSelectedOptions } = this.handleGetSelectedOptions(changedSelectedOptionDetails); let { formatSelectedOptions, selectedOptionIds } = this.handleSelectedOptionIdChange(selectedGroupOptions, normalizedFormatOptions, normalizedSelectedOptions); this.setState({ formatSelectedOptions, selectedOptionIds }); } let hoverId = getIsEmptyValue(newOptionIds[hoverIndex]) ? '' : newOptionIds[hoverIndex]; let selSuggestion = this[`suggestion_${hoverId}`]; isPopupOpen && scrollTo(this.suggestionContainer, selSuggestion); //When suggestions length less than 5, getNextOptions function call let { isNextOptions, getNextOptions, needLocalSearch } = this.props; let { suggestionOptionIds: suggestions } = this.handleFilterSuggestions(); let suggestionsLen = suggestions.length; if (isPopupOpen && suggestionsLen <= 5 && isNextOptions && getNextOptions && !needLocalSearch) { this.handleFetchOptions(getNextOptions, searchStr); } if (prevProps.isPopupOpen != isPopupOpen) { notifyPopupToggle && notifyPopupToggle(isPopupOpen); } } responsiveFunc({ mediaQueryOR }) { return { tabletMode: mediaQueryOR([{ maxWidth: 700 }]) }; } render() { let { size, textBoxSize, selectedGroupOptions, placeHolder, dataId, dataSelectorId, isReadOnly, isDisabled, isPopupOpen, isPopupReady, defaultDropBoxPosition, removeClose, needResponsive, animationStyle, needSelectAll, selectAllText, dropBoxSize, position, getContainerRef, isAbsolutePositioningNeeded, positionsOffset, targetOffset, isRestrictScroll, emptyMessage, searchEmptyMessage, renderCustomEmptyState, title, variant, children, listItemSize, isDataLoaded, needBorder, isNextOptions, getFooter, customClass, borderColor, isPadding, htmlId, i18nKeys, a11y, palette, needEffect, autoComplete, getTargetRef, isFocus, limit, customProps } = this.props; const { SuggestionsProps = DUMMY_OBJECT } = customProps; let { clearText = MULTISELECT_I18N_KEYS.clearText, limitReachedMessage = MULTISELECT_I18N_KEYS.limitReachedMessage } = i18nKeys; let { clearLabel = MULTISELECT_I18N_KEYS.clearText } = a11y; i18nKeys = Object.assign({}, i18nKeys, { emptyText: i18nKeys.emptyText || emptyMessage, searchEmptyText: i18nKeys.searchEmptyText || searchEmptyMessage }); let { isActive, searchStr, revampedGroups = [], selectedOptionIds, formatSelectedOptions, hoverIndex, highLightedSelectOptions, isFetchingOptions } = this.state; let { suggestionGroups, suggestionOptionIds } = this.handleFilterSuggestions(); let setAriaId = this.getNextAriaId(); let ariaErrorId = this.getNextAriaId(); const isShowClearIcon = !isReadOnly && !isDisabled && selectedGroupOptions.length > 1; const isEditable = !(isReadOnly || isDisabled); return /*#__PURE__*/React.createElement("div", { className: `${style.wrapper} ${isDisabled ? style.disabled : ''} ${needEffect && !(isDisabled || isReadOnly) ? style.effect : ''}`, "data-id": `${isDisabled ? `${dataId}_disabled` : isReadOnly ? `${dataId}_readOnly` : dataId}`, "data-test-id": `${isDisabled ? `${dataId}_disabled` : isReadOnly ? `${dataId}_readOnly` : dataId}`, "data-title": isDisabled ? title : null, onClick: this.handleInputFocus, "data-selector-id": dataSelectorId }, children ? /*#__PURE__*/React.createElement(Container, { align: "vertical", alignBox: "row", onClick: this.togglePopup, className: customClass, eleRef: getTargetRef }, children) : /*#__PURE__*/React.createElement(Container, { align: "vertical", alignBox: "row", className: `${style.container} ${style[size]} ${isActive && needBorder || isEditable && isFocus && needBorder ? style.active : ''} ${needBorder ? style.hasBorder : ''} ${style[`borderColor_${borderColor}`]} ${customClass}`, eleRef: this.selectedOptionContainerRef, wrap: "wrap" }, /*#__PURE__*/React.createElement(SelectedOptions, { selectedOptions: formatSelectedOptions, highLightedSelectOptions: highLightedSelectOptions, isReadOnly: isReadOnly, getRef: this.selectedOptionRef, onRemove: this.handleRemoveOption, onSelect: this.handleClickSelectedOption, isGroupSelect: true, dataId: `${dataId}_selectedOptions` }), /*#__PURE__*/React.createElement(Box, { flexible: true, className: style.wrapper, adjust: true, shrink: true }, /*#__PURE__*/React.createElement("span", { className: ` ${style.custmSpan} ${textBoxSize === 'xmedium' ? style.custmSpanXmedium : style.custmSpanMedium} ${isShowClearIcon ? style.clearIconSpace : ''} ` }, searchStr), /*#__PURE__*/React.createElement(TextBoxIcon, { isDisabled: isDisabled, inputRef: this.searchInputRef, needBorder: false, onBlur: this.handleInactive, onChange: this.handleSearch, onClick: this.handleInputCick, onFocus: this.handleActive, onKeyDown: this.handleKeyDown, placeHolder: selectedGroupOptions.length >= 1 ? '' : placeHolder, size: textBoxSize, value: searchStr, variant: variant, dataId: `${dataId}_textBox`, isReadOnly: isReadOnly, customClass: { customTBoxWrap: style.custmInputWrapper }, tabindex: isDisabled && '-1', htmlId: htmlId, a11y: { ariaExpanded: !isReadOnly && !isDisabled && isPopupOpen ? true : false, ariaHaspopup: true, role: 'combobox', ariaControls: setAriaId, ariaOwns: setAriaId, ariaDescribedby: ariaErrorId }, autoComplete: autoComplete }, isShowClearIcon ? /*#__PURE__*/React.createElement(Container, { alignBox: "row", align: "vertical" }, /*#__PURE__*/React.createElement(Box, { className: `${style.delete} ${style[`${palette}Delete`]}`, dataId: `${dataId}_clearIcon`, "data-title": clearText, onClick: this.handleDeselectAll, tagName: "button", "aria-label": clearLabel }, /*#__PURE__*/React.createElement(Icon, { name: "ZD-delete", size: "15" }))) : null))), !isReadOnly && !isDisabled && isPopupOpen ? /*#__PURE__*/React.createElement(ResponsiveReceiver, { query: this.responsiveFunc, responsiveId: "Helmet" }, ({ tabletMode }) => /*#__PURE__*/React.createElement(ResponsiveDropBox, { animationStyle: animationStyle, boxPosition: position || `${defaultDropBoxPosition}Center`, getRef: getContainerRef, isActive: isPopupReady, isAnimate: true, isArrow: false, onClick: removeClose, needResponsive: needResponsive, isPadding: isPadding, isBoxPaddingNeed: !needSelectAll, isAbsolutePositioningNeeded: isAbsolutePositioningNeeded, positionsOffset: positionsOffset, targetOffset: targetOffset, isRestrictScroll: isRestrictScroll, htmlId: setAriaId, a11y: { role: 'listbox', ariaMultiselectable: true }, alignBox: "row", dataId: `${dataId}_dropbox` }, /*#__PURE__*/React.createElement(Box, { flexible: true }, /*#__PURE__*/React.createElement(Card, { customClass: `${style.box} ${style[`${palette}Box`]}`, onScroll: this.handleScroll }, needSelectAll && !(limit >= 0) ? /*#__PURE__*/React.createElement(CardHeader, null, /*#__PURE__*/React.createElement(MultiSelectHeader, { onSelect: this.handleSelectAll, selectAllText: selectAllText, suggestions: suggestionOptionIds, dataId: dataId })) : null, isDataLoaded ? /*#__PURE__*/React.createElement(CardContent, { shrink: true, customClass: !tabletMode && dropBoxSize ? style[dropBoxSize] : '', eleRef: this.suggestionContainerRef }, /*#__PURE__*/React.createElement(React.Fragment, { key: 'SuggestonsParent' }, suggestionGroups.length ? suggestionGroups.map(group => { let { options: suggestions = [] } = group; let groupId = group.id; let groupName = group.name; let hoverId = suggestionOptionIds[hoverIndex]; return /*#__PURE__*/React.createElement(React.Fragment, { key: groupId }, groupName && /*#__PURE__*/React.createElement("div", { className: style.groupTitle }, /*#__PURE__*/React.createElement(DropDownHeading, { text: groupName, a11y: { role: 'heading' } })), /*#__PURE__*/React.createElement(Suggestions, _extends({}, SuggestionsProps, { suggestions: suggestions, selectedOptions: selectedOptionIds, getRef: this.suggestionItemRef, hoverId: hoverId, onClick: this.handleSelectOption, onMouseEnter: this.handleMouseEnter, needTick: true, listItemSize: listItemSize, a11y: { role: 'option' }, limit: limit, limitReachedMessage: limitReachedMessage, dataId: `${dataId}_Options` }))); }) : /*#__PURE__*/React.createElement(EmptyState, { options: revampedGroups, searchString: searchStr, suggestions: suggestionGroups, renderCustomEmptyState: renderCustomEmptyState, dataId: dataId, isLoading: isFetchingOptions, i18nKeys: i18nKeys, htmlId: ariaErrorId }), isNextOptions && /*#__PURE__*/React.createElement("div", { className: style.loader }, /*#__PURE__*/React.createElement(Loader, null)))) : /*#__PURE__*/React.createElement("div", { className: style.loader }, /*#__PURE__*/React.createElement(Loader, null)), getFooter ? isDataLoaded ? /*#__PURE__*/React.createElement(CardFooter, null, getFooter()) : /*#__PURE__*/React.createElement("div", { className: style.loader }, /*#__PURE__*/React.createElement(Loader, null)) : null)))) : null); } } AdvancedGroupMultiSelect.defaultProps = AdvancedGroupMultiSelect_defaultProps; AdvancedGroupMultiSelect.propTypes = AdvancedGroupMultiSelect_propTypes; const AdvancedGroupMultiSelectComponent = Popup(AdvancedGroupMultiSelect); AdvancedGroupMultiSelectComponent.defaultProps = AdvancedGroupMultiSelect.defaultProps; AdvancedGroupMultiSelectComponent.propTypes = AdvancedGroupMultiSelect.propTypes; // if (__DOCS__) { // AdvancedGroupMultiSelect.docs = { // componentGroup: 'Form Elements', // folderName: 'Style Guide' // }; // } export default AdvancedGroupMultiSelectComponent;