@carbon/ibm-products
Version:
Carbon for IBM Products
128 lines (126 loc) • 6.61 kB
JavaScript
/**
* 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 };