UNPKG

@carbon/ibm-products

Version:

Carbon for IBM Products

185 lines (177 loc) 7.6 kB
/** * 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. */ 'use strict'; 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;