@carbon/ibm-products
Version:
Carbon for IBM Products
185 lines (177 loc) • 7.6 kB
JavaScript
/**
* Copyright IBM Corp. 2020, 2025
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
;
var React = require('react');
var react = require('@carbon/react');
var icons = require('@carbon/react/icons');
var index = require('../../../../_virtual/index.js');
var ConditionBuilderProvider = require('../../ConditionBuilderContext/ConditionBuilderProvider.js');
var useTranslations = require('../../utils/useTranslations.js');
var util = require('../../utils/util.js');
var _SelectSkeleton, _CheckboxCheckedFille, _Checkbox;
const ItemOptionForValueField = _ref => {
let {
conditionState = {},
config = {},
onChange
} = _ref;
const multiSelectable = util.checkForMultiSelectOperator(conditionState, config);
const {
popOverSearchThreshold,
getOptions,
rootState
} = React.useContext(ConditionBuilderProvider.ConditionBuilderContext);
const [propertyText, clearSearchText] = useTranslations.useTranslations(['propertyText', 'clearSearchText']);
const {
conditionBuilderRef
} = React.useContext(ConditionBuilderProvider.ConditionBuilderContext);
const contentRef = React.useRef(null);
const [allOptions, setAllOptions] = React.useState(config.options);
const [searchValue, setSearchValue] = React.useState('');
const filteredItems = allOptions?.filter(opt => opt.label.toLowerCase().includes(searchValue.toLowerCase()));
const selection = Array.isArray(conditionState.value) ? conditionState.value : conditionState.value !== undefined ? [conditionState.value] : [];
React.useEffect(() => {
//this commented code is kept as intentional. Alternate approach to pass async options instead of getOptions callback.
// if(rest['data-name'] == 'valueField'){
// const fetchData = async () => {
// const response = await config.options(conditionState);
// if (
// response?.length > 0 &&
// Object.keys(response[0]).includes('label') &&
// Object.keys(response[0]).includes('id')
// ) {
// setAllOptions(response);
// setFilteredItems(response);
// }
// };
// fetchData(); // Call the async method
// }else{
// setAllOptions(config.options);
// setFilteredItems(config.options);
// }
if (!allOptions && getOptions) {
const fetchData = async () => {
const response = await getOptions(rootState, conditionState);
if (response?.length > 0 && Object.keys(response[0]).includes('label') && Object.keys(response[0]).includes('id')) {
setAllOptions(response);
}
};
fetchData(); // Call the async method
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
React.useEffect(() => {
//this will focus the first input field in the popover
if (contentRef.current) {
const firstFocusableElement = contentRef.current.querySelector('input, button,li');
if (firstFocusableElement) {
firstFocusableElement?.focus();
}
}
}, [allOptions]);
const handleSelectAll = evt => {
if (evt.currentTarget.dataset.selectedAll == 'false') {
onChange(undefined);
} else {
onChange(allOptions);
}
};
const onSearchChangeHandler = evt => {
const {
value
} = evt.target;
setSearchValue(value);
};
const onClickHandler = (evt, option, isSelected) => {
const updatedSelections = selection.filter(item => item !== 'INVALID');
if (multiSelectable) {
if (isSelected) {
const items = updatedSelections.filter(v => v.id !== option.id);
onChange(items.length > 0 ? items : undefined);
} else {
onChange([...updatedSelections, option]);
}
} else {
onChange(option, evt);
}
if (evt.target instanceof SVGElement) {
evt.stopPropagation();
//stop propagate event , since this closes the popover when clicked on checkboxes which are SVGs.
}
};
const getAriaLabel = () => {
return conditionState.label ? conditionState.label : conditionState.property ? conditionState.property : propertyText;
};
if (!allOptions) {
return _SelectSkeleton || (_SelectSkeleton = /*#__PURE__*/React.createElement(react.SelectSkeleton, null));
}
return /*#__PURE__*/React.createElement("div", {
className: `${util.blockClass}__item-option`,
ref: contentRef
}, popOverSearchThreshold && allOptions.length > popOverSearchThreshold && /*#__PURE__*/React.createElement("div", {
className: `${util.blockClass}__item-option__search`
}, /*#__PURE__*/React.createElement(react.Search, {
size: "sm",
labelText: clearSearchText,
closeButtonLabelText: clearSearchText,
onChange: onSearchChangeHandler,
onKeyDown: evt => util.onKeyDownHandlerForSearch(evt, conditionBuilderRef)
})), multiSelectable && /*#__PURE__*/React.createElement("div", {
className: `${util.blockClass}__multiselectSelectionStatusContainer`
}, /*#__PURE__*/React.createElement("label", null, selection.length, "/", allOptions.length, " Selected"), /*#__PURE__*/React.createElement(react.Button, {
kind: 'ghost',
size: 'sm',
"data-selected-all": `${selection.length == 0 ? true : false}`,
onClick: handleSelectAll,
className: `${util.blockClass}__selectAll-button`
}, selection.length == 0 ? 'Select all' : 'Deselect all')), /*#__PURE__*/React.createElement("ul", {
"aria-label": getAriaLabel(),
role: "listbox",
"data-multi-select": multiSelectable
}, filteredItems?.map(option => {
const isSelected = selection.map(option => option.id).includes(option.id);
const Icon = option.icon;
return /*#__PURE__*/React.createElement("li", {
tabIndex: 0,
key: option.id,
role: "option",
"aria-selected": isSelected,
className: `${util.blockClass}__item-option__option`,
onKeyUp: () => {
return false;
},
onClick: evt => onClickHandler(evt, option, isSelected)
}, /*#__PURE__*/React.createElement("div", {
className: `${util.blockClass}__item-option__option-content`
}, multiSelectable ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
className: `${util.blockClass}__option-check-box`
}, isSelected ? _CheckboxCheckedFille || (_CheckboxCheckedFille = /*#__PURE__*/React.createElement(icons.CheckboxCheckedFilled, null)) : _Checkbox || (_Checkbox = /*#__PURE__*/React.createElement(icons.Checkbox, null))), /*#__PURE__*/React.createElement("span", {
className: `${util.blockClass}__item-option__option-label`
}, option.label), Icon && /*#__PURE__*/React.createElement("span", {
className: `${util.blockClass}__option-icon`
}, /*#__PURE__*/React.createElement(Icon, null))) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
className: `${util.blockClass}__item-option__option-label`
}, Icon && /*#__PURE__*/React.createElement(Icon, null), option.label), isSelected && /*#__PURE__*/React.createElement(icons.Checkmark, {
className: `${util.blockClass}__checkmark`
}))));
})));
};
ItemOptionForValueField.propTypes = {
/**
* current condition object
*/
conditionState: index.default.object,
/**
* current config object that this property is part of
*/
config: index.default.object,
/**
* callback to update state oin date change
*/
onChange: index.default.func
};
exports.ItemOptionForValueField = ItemOptionForValueField;