UNPKG

@carbon/ibm-products

Version:
128 lines (126 loc) 6.61 kB
/** * Copyright IBM Corp. 2020, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import { blockClass, checkForMultiSelectOperator, onKeyDownHandlerForSearch } from "../../utils/util.js"; import { ConditionBuilderContext } from "../../ConditionBuilderContext/ConditionBuilderProvider.js"; import { useTranslations } from "../../utils/useTranslations.js"; import React, { useContext, useEffect, useRef, useState } from "react"; import PropTypes from "prop-types"; import { Button, Search, SelectSkeleton } from "@carbon/react"; import { Checkbox as Checkbox$1, CheckboxCheckedFilled, Checkmark } from "@carbon/react/icons"; //#region src/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItemOption/ItemOptionForValueField.tsx /** * Copyright IBM Corp. 2024 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ /**@ts-ignore */ const ItemOptionForValueField = ({ conditionState = {}, config = {}, onChange, closePopover }) => { const multiSelectable = checkForMultiSelectOperator(conditionState, config); const { popOverSearchThreshold, getOptions, rootState } = useContext(ConditionBuilderContext); const [propertyText, clearSearchText] = useTranslations(["propertyText", "clearSearchText"]); const { conditionBuilderRef } = useContext(ConditionBuilderContext); const contentRef = useRef(null); const [allOptions, setAllOptions] = useState(config?.options); const [searchValue, setSearchValue] = useState(""); const filteredItems = allOptions?.filter((opt) => opt.label.toLowerCase().includes(searchValue.toLowerCase())); const selection = Array.isArray(conditionState.value) ? conditionState.value : conditionState.value !== void 0 ? [conditionState.value] : []; useEffect(() => { 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(); } }, []); useEffect(() => { 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(void 0); 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 : void 0); } else onChange([...updatedSelections, option]); else onChange(option, evt); if (evt.target instanceof SVGElement) evt.stopPropagation(); }; const getAriaLabel = () => { return conditionState.label ? conditionState.label : conditionState.property ? conditionState.property : propertyText; }; if (!allOptions) return /* @__PURE__ */ React.createElement(SelectSkeleton, null); return /* @__PURE__ */ React.createElement("div", { className: `${blockClass}__item-option`, ref: contentRef }, allOptions.length > popOverSearchThreshold ? /* @__PURE__ */ React.createElement("div", { className: `${blockClass}__item-option__search` }, /* @__PURE__ */ React.createElement(Search, { size: "sm", labelText: clearSearchText, closeButtonLabelText: clearSearchText, onChange: onSearchChangeHandler, onKeyDown: (evt) => { onKeyDownHandlerForSearch(evt, conditionBuilderRef, closePopover); } })) : null, multiSelectable && /* @__PURE__ */ React.createElement("div", { className: `${blockClass}__multiselectSelectionStatusContainer` }, /* @__PURE__ */ React.createElement("label", null, selection.length, "/", allOptions.length, " Selected"), /* @__PURE__ */ React.createElement(Button, { kind: "ghost", size: "sm", "data-selected-all": `${selection.length == 0 ? true : false}`, onClick: handleSelectAll, className: `${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: `${blockClass}__item-option__option`, onKeyUp: () => { return false; }, onClick: (evt) => onClickHandler(evt, option, isSelected) }, /* @__PURE__ */ React.createElement("div", { className: `${blockClass}__item-option__option-content` }, multiSelectable ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { className: `${blockClass}__option-check-box` }, isSelected ? /* @__PURE__ */ React.createElement(CheckboxCheckedFilled, null) : /* @__PURE__ */ React.createElement(Checkbox$1, null)), /* @__PURE__ */ React.createElement("span", { className: `${blockClass}__item-option__option-label` }, /* @__PURE__ */ React.createElement("span", { className: `${blockClass}__item-option__option-label-text`, title: option.label }, option.label), Icon && /* @__PURE__ */ React.createElement("span", { className: `${blockClass}__option-icon` }, /* @__PURE__ */ React.createElement(Icon, null)))) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { className: `${blockClass}__item-option__option-label` }, Icon && /* @__PURE__ */ React.createElement(Icon, null), /* @__PURE__ */ React.createElement("span", { className: `${blockClass}__item-option__option-label-text`, title: option.label }, option.label)), isSelected && /* @__PURE__ */ React.createElement(Checkmark, { className: `${blockClass}__checkmark` })))); }))); }; ItemOptionForValueField.propTypes = { /** * current condition object */ conditionState: PropTypes.object, /** * current config object that this property is part of */ config: PropTypes.object, /** * callback to update state oin date change */ onChange: PropTypes.func }; //#endregion export { ItemOptionForValueField };