@zohodesk/components
Version:
In this Package, we Provide Some Basic Components to Build Web App
1,101 lines (1,014 loc) • 36.4 kB
JavaScript
import React from 'react';
import { AdvancedGroupMultiSelect_propTypes } from "./props/propTypes";
import { AdvancedGroupMultiSelect_defaultProps } from "./props/defaultProps";
/**** 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";
/**** 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
} = 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
});
}
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() {
let id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
let e = arguments.length > 1 ? arguments[1] : undefined;
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
} = 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) {
//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() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
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() {
let selectedOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
let e = arguments.length > 1 ? arguments[1] : undefined;
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(_ref) {
let {
mediaQueryOR
} = _ref;
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,
title,
variant,
children,
listItemSize,
isDataLoaded,
needBorder,
isNextOptions,
getFooter,
customClass,
borderColor,
isPadding,
htmlId,
i18nKeys,
a11y,
palette,
needEffect,
autoComplete,
getTargetRef,
isFocus
} = this.props;
let {
clearText = 'Clear all'
} = i18nKeys;
let {
clearLabel = 'Clear all'
} = 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"
}, _ref2 => {
let {
tabletMode
} = _ref2;
return /*#__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 ? /*#__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, {
suggestions: suggestions,
selectedOptions: selectedOptionIds,
getRef: this.suggestionItemRef,
hoverId: hoverId,
onClick: this.handleSelectOption,
onMouseEnter: this.handleMouseEnter,
needTick: true,
listItemSize: listItemSize,
a11y: {
role: 'option'
},
dataId: `${dataId}_Options`
}));
}) : /*#__PURE__*/React.createElement(EmptyState, {
options: revampedGroups,
searchString: searchStr,
suggestions: suggestionGroups,
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;