@carbon/ibm-products
Version:
Carbon for IBM Products
212 lines (210 loc) • 8.62 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.
*/
const require_runtime = require("../../../_virtual/_rolldown/runtime.js");
const require_util = require("../utils/util.js");
const require_ConditionBuilderProvider = require("../ConditionBuilderContext/ConditionBuilderProvider.js");
const require_ConditionBuilderButton = require("../ConditionBuilderButton/ConditionBuilderButton.js");
const require_translationObject = require("../ConditionBuilderContext/translationObject.js");
const require_useTranslations = require("../utils/useTranslations.js");
const require_handleKeyboardEvents = require("../utils/handleKeyboardEvents.js");
const require_useEvent = require("../utils/useEvent.js");
let react = require("react");
react = require_runtime.__toESM(react);
let prop_types = require("prop-types");
prop_types = require_runtime.__toESM(prop_types);
let _carbon_react = require("@carbon/react");
let _carbon_react_icons = require("@carbon/react/icons");
//#region src/components/ConditionBuilder/ConditionBuilderItem/ConditionBuilderItem.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.
*/
const ConditionBuilderItem = ({ children, className, label, renderIcon, title, type, showToolTip, condition, popOverClassName, config, renderChildren, onChange, description, ...rest }) => {
const popoverRef = (0, react.useRef)(null);
const [open, setOpen] = (0, react.useState)(false);
const { conditionBuilderRef, statementConfigCustom, readOnly } = (0, react.useContext)(require_ConditionBuilderProvider.ConditionBuilderContext);
const statementIdMap = {
ifAll: require_translationObject.translationsObject.ifText,
ifAny: require_translationObject.translationsObject.ifText,
unlessAll: require_translationObject.translationsObject.unlessText,
unlessAny: require_translationObject.translationsObject.unlessText
};
statementConfigCustom?.forEach((statement) => {
statementIdMap[statement.id] = statement.label;
});
const [invalidText, addConditionText, addPropertyText, addOperatorText, addValueText, labelText] = require_useTranslations.useTranslations([
"invalidText",
"addConditionText",
"addPropertyText",
"addOperatorText",
"addValueText",
label
], statementIdMap);
const getCustomOperatorLabel = (propertyLabel) => {
return propertyLabel && config?.operators?.find((operator) => {
return operator.id === propertyLabel;
});
};
const getPropertyDetails = () => {
const { property, operator } = condition || {};
if (label === "INVALID" || rest["data-name"] === "propertyField" && property === "INVALID" || rest["data-name"] === "operatorField" && operator === "INVALID") return {
propertyLabel: invalidText,
isInvalid: true
};
if (rest["data-name"] == "operatorField" && type == "custom") return {
isInvalid: false,
propertyLabel: getCustomOperatorLabel(label)?.id
};
return {
isInvalid: false,
propertyLabel: rest["data-name"] == "valueField" && type ? require_util.getValue(type, label, config) : labelText
};
};
const { propertyLabel, isInvalid } = getPropertyDetails();
(0, react.useEffect)(() => {
/**
* rest['data-name'] holds the current field name
* popoverToOpen hold the next popover to be opened if required
*/
if (condition) {
const currentField = rest["data-name"];
if (condition.popoverToOpen && currentField !== condition.popoverToOpen) closePopover();
else if (currentField == "valueField" && type === "option" && !require_util.checkForMultiSelectOperator(condition, config)) closePopover();
if (condition.popoverToOpen == currentField) setTimeout(() => {
openPopOver();
});
} else closePopover();
}, [condition, label]);
(0, react.useEffect)(() => {
if (open && popoverRef.current) {
const firstFocusableElement = popoverRef?.current?.querySelector("input,textarea");
if (firstFocusableElement) setTimeout(() => firstFocusableElement.focus(), 0);
}
}, [popoverRef, open]);
require_useEvent.useEvent(popoverRef, "focusout", (event) => {
const focusEvent = event;
const relatedTarget = focusEvent.relatedTarget;
const popoverEl = popoverRef.current;
if (!popoverEl) return;
const focusLeftPopover = relatedTarget && !popoverEl.contains(relatedTarget);
const targetInsidePopover = popoverEl.contains(focusEvent.target);
const focusMovedToDatePicker = focusEvent.target?.closest(".flatpickr-calendar");
if ((focusLeftPopover || !targetInsidePopover) && !focusMovedToDatePicker) closePopover();
});
const manageInvalidSelection = () => {
if (rest["data-name"] === "propertyField" && !condition?.property || rest["data-name"] === "operatorField" && !condition?.operator || rest["data-name"] === "valueField" && !condition?.value) onChange?.("INVALID");
};
const closePopover = () => {
if (open) manageInvalidSelection();
setOpen(false);
};
const openPopOver = () => {
if (readOnly) return;
setOpen(true);
};
const togglePopover = () => {
if (children || renderChildren) setOpen(!open);
};
const handleKeyDownHandler = (evt) => {
require_handleKeyboardEvents.handleKeyDownForPopover(evt, conditionBuilderRef, popoverRef, closePopover);
if (evt.key === "Escape") manageInvalidSelection();
};
const getLabel = () => {
if (config?.operators && rest["data-name"] === "operatorField") return getCustomOperatorLabel(propertyLabel)?.label ?? addOperatorText;
else if (propertyLabel) return propertyLabel;
else if (rest["data-name"] === "propertyField") return addPropertyText;
else if (rest["data-name"] === "operatorField") return addOperatorText;
else if (rest["data-name"] === "valueField") return addValueText;
else return addConditionText;
};
return /* @__PURE__ */ react.default.createElement(_carbon_react.Popover, {
open,
isTabTip: true,
role: "gridcell",
className: `${popOverClassName} ${require_util.blockClass}__popover`,
ref: popoverRef,
onRequestClose: () => {
if ((event?.target)?.closest(".flatpickr-calendar")) return;
closePopover();
}
}, /* @__PURE__ */ react.default.createElement(require_ConditionBuilderButton.ConditionBuilderButton, {
label: getLabel(),
hideLabel: !label ? true : false,
onClick: togglePopover,
className,
"aria-haspopup": true,
"aria-expanded": open,
renderIcon: renderIcon ? renderIcon : label == void 0 ? _carbon_react_icons.Add : void 0,
showToolTip,
isInvalid,
description,
...rest
}), open && /* @__PURE__ */ react.default.createElement(_carbon_react.PopoverContent, {
className: `${require_util.blockClass}__popover-content-wrapper`,
role: "dialog",
"aria-label": title,
onKeyDown: handleKeyDownHandler
}, /* @__PURE__ */ react.default.createElement(_carbon_react.Layer, null, /* @__PURE__ */ react.default.createElement(_carbon_react.Section, null, /* @__PURE__ */ react.default.createElement(_carbon_react.Heading, { className: `${require_util.blockClass}__item__title` }, title), /* @__PURE__ */ react.default.createElement("div", { className: `${require_util.blockClass}__popover-content` }, renderChildren ? renderChildren(popoverRef, closePopover) : children)))));
};
ConditionBuilderItem.propTypes = {
/**
* provide the contents of the popover
*/
children: prop_types.default.node,
/**
* Provide an optional class to be applied to the containing node.
*/
className: prop_types.default.string,
/**
* current condition state object
*/
condition: prop_types.default.object,
/**
* this is the config object again the current property from inputConfig
*/
config: prop_types.default.object,
/**
* text to be displayed in the field
*/
label: prop_types.default.oneOfType([
prop_types.default.string,
prop_types.default.array,
prop_types.default.object
]),
/**
* callback to update the current condition of the state tree
*/
onChange: prop_types.default.func,
/**
* class name for popover
*/
popOverClassName: prop_types.default.string,
/**
* callback prop that returns the jsx for children
*/
renderChildren: prop_types.default.func,
/**
* Optional prop to allow overriding the icon rendering.
*/
renderIcon: prop_types.default.oneOfType([prop_types.default.func, prop_types.default.object]),
/**
* show tool tip
*/
showToolTip: prop_types.default.bool,
/**
* title of the popover
*/
title: prop_types.default.string,
/**
* input type
*/
type: prop_types.default.string
};
//#endregion
exports.ConditionBuilderItem = ConditionBuilderItem;