@carbon/ibm-products
Version:
Carbon for IBM Products
234 lines (232 loc) • 9.77 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_uuidv4 = require("../../../global/js/utils/uuidv4.js");
const require_util = require("../utils/util.js");
const require_ConditionBuilderProvider = require("../ConditionBuilderContext/ConditionBuilderProvider.js");
const require_ConditionBuilderButton = require("../ConditionBuilderButton/ConditionBuilderButton.js");
const require_useTranslations = require("../utils/useTranslations.js");
const require_ConditionPreview = require("../ConditionPreview/ConditionPreview.js");
const require_ConditionGroupBuilder = require("../ConditionGroupBuilder/ConditionGroupBuilder.js");
const require_GroupConnector = require("../ConditionBuilderConnector/GroupConnector.js");
const require_ConditionBuilderActions = require("../ConditionBuilderActions/ConditionBuilderActions.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/ConditionBuilderContent/ConditionBuilderContent.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 ConditionBuilderContent = ({ startConditionLabel, getConditionState, getActionsState, initialState, actions }) => {
const { rootState, setRootState, variant, actionState, onAddItem, onRemoveItem, readOnly, statementConfigCustom } = (0, react.useContext)(require_ConditionBuilderProvider.ConditionBuilderContext);
const initialConditionState = (0, react.useRef)(initialState?.state ? JSON.parse(JSON.stringify(initialState?.state)) : null);
const [isConditionBuilderActive, setIsConditionBuilderActive] = (0, react.useState)(false);
const [showConditionGroupPreview, setShowConditionGroupPreview] = (0, react.useState)(false);
const [addConditionGroupText, conditionHeadingText, conditionBuilderHierarchicalText] = require_useTranslations.useTranslations([
"addConditionGroupText",
"conditionHeadingText",
"conditionBuilderHierarchicalText"
]);
const showConditionGroupPreviewHandler = () => {
setShowConditionGroupPreview(true);
};
const hideConditionGroupPreviewHandler = () => {
setShowConditionGroupPreview(false);
};
(0, react.useEffect)(() => {
if (rootState?.groups?.length) setIsConditionBuilderActive(true);
else setIsConditionBuilderActive(false);
if (getConditionState) getConditionState(rootState ?? {});
}, [rootState]);
(0, react.useEffect)(() => {
getActionsState?.(actionState ?? []);
}, [actionState]);
(0, react.useEffect)(() => {
if (initialState?.enabledDefault) setRootState?.(initialState.state);
}, [initialState]);
const onStartConditionBuilder = () => {
setIsConditionBuilderActive(true);
if (initialConditionState?.current?.groups?.length) {
setRootState?.(initialConditionState.current);
initialConditionState.current = null;
} else setRootState?.(require_ConditionBuilderProvider.getEmptyState(statementConfigCustom));
};
const onRemove = (0, react.useCallback)((groupId) => {
const groupToRemove = rootState?.groups?.find((group) => group?.id === groupId);
const { preventRemove } = onRemoveItem?.({
type: "group",
state: rootState,
item: groupToRemove
}) ?? {};
if (!preventRemove) {
const groups = rootState?.groups?.filter((group) => groupId !== group?.id);
setRootState?.({
...rootState,
groups: rootState ? groups : []
});
if (groups?.length === 0) initialConditionState.current = null;
}
}, [
setRootState,
rootState,
onRemoveItem
]);
const onChangeHandler = (updatedGroup, groupIndex) => {
/**
* This method is triggered from inner components. This will be called every time when any change is to be updated in the rootState.
* This gets the updated group as argument.
*/
if (rootState && rootState.groups) {
const groups = [
...rootState.groups ? rootState.groups.slice(0, groupIndex) : [],
updatedGroup,
...rootState.groups ? rootState.groups.slice(groupIndex + 1) : []
];
setRootState?.({
...rootState,
groups
});
}
};
const addConditionGroupHandler = () => {
const { preventAdd } = onAddItem?.({
type: "group",
state: rootState
}) ?? {};
if (!preventAdd) {
const newGroup = require_ConditionBuilderProvider.getEmptyState(statementConfigCustom).groups?.[0];
setRootState?.({
...rootState,
groups: rootState && rootState.groups ? [...rootState.groups, newGroup] : [newGroup]
});
}
};
const getColorIndex = () => {
return (rootState?.groups?.length ?? 0) % 5;
};
if (!isConditionBuilderActive) return /* @__PURE__ */ react.default.createElement(_carbon_react.Button, {
className: `${require_util.blockClass}__addConditionText-button`,
renderIcon: (props) => /* @__PURE__ */ react.default.createElement(_carbon_react_icons.Add, props),
iconDescription: startConditionLabel,
kind: "ghost",
size: "sm",
onClick: onStartConditionBuilder
}, startConditionLabel);
const wrapperRole = variant === "Hierarchical" ? {
role: "treegrid",
"aria-label": conditionBuilderHierarchicalText
} : null;
return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement(_carbon_react.Section, {
className: `${require_util.blockClass}__heading`,
level: 4
}, /* @__PURE__ */ react.default.createElement(_carbon_react.Heading, null, conditionHeadingText)), /* @__PURE__ */ react.default.createElement("div", {
className: `${require_util.blockClass}__content-container`,
...wrapperRole
}, rootState && rootState?.groups?.map((eachGroup, groupIndex) => /* @__PURE__ */ react.default.createElement("div", {
key: eachGroup.id,
className: `${require_util.blockClass}__group-wrapper`
}, /* @__PURE__ */ react.default.createElement(require_ConditionGroupBuilder.default, {
className: `${require_util.blockClass}__group`,
aria: {
level: 1,
posinset: groupIndex * 2 + 1,
setsize: (rootState.groups && rootState.groups.length * 2) ?? 0
},
group: eachGroup,
onRemove: () => {
onRemove(eachGroup.id);
},
onChange: (updatedGroup) => {
onChangeHandler(updatedGroup, groupIndex);
}
}), rootState.groups && groupIndex < rootState.groups.length - 1 && /* @__PURE__ */ react.default.createElement(require_GroupConnector.default, null))), !readOnly && variant == "Hierarchical" && /* @__PURE__ */ react.default.createElement("div", {
role: "row",
tabIndex: -1,
"aria-level": 1,
className: `${require_util.blockClass}__add-group`
}, /* @__PURE__ */ react.default.createElement(require_ConditionBuilderButton.ConditionBuilderButton, {
renderIcon: _carbon_react_icons.TextNewLine,
onClick: addConditionGroupHandler,
onMouseEnter: showConditionGroupPreviewHandler,
onMouseLeave: hideConditionGroupPreviewHandler,
onFocus: showConditionGroupPreviewHandler,
onBlur: hideConditionGroupPreviewHandler,
className: `${require_util.blockClass}__add-condition-group `,
hideLabel: true,
label: addConditionGroupText,
wrapperProps: {
role: "gridcell",
"aria-label": addConditionGroupText
}
})), variant === "Hierarchical" ? /* @__PURE__ */ react.default.createElement(require_ConditionPreview.default, {
previewType: "newGroup",
colorIndex: getColorIndex(),
className: showConditionGroupPreview ? `${require_util.blockClass}__visible` : `${require_util.blockClass}__hidden`,
group: {
groupOperator: rootState?.operator,
id: require_uuidv4.default()
}
}) : null), actions && /* @__PURE__ */ react.default.createElement(require_ConditionBuilderActions.default, {
actions,
className: `${require_util.blockClass}__actions-container`
}));
};
ConditionBuilderContent.propTypes = {
/**
* optional array of object that give the list of actions.
*/
actions: prop_types.default.arrayOf(prop_types.default.shape({
id: prop_types.default.oneOfType([prop_types.default.string, prop_types.default.number]).isRequired,
label: prop_types.default.string.isRequired
})),
/**
* callback functions that will provide the updated action state back.
*/
getActionsState: prop_types.default.func,
/**
* This is a callback function that returns the updated state
*/
getConditionState: prop_types.default.func.isRequired,
/**
* Optional prop if the condition building need to start from a predefined initial state
*/
initialState: prop_types.default.shape({
state: prop_types.default.shape({
groups: prop_types.default.arrayOf(prop_types.default.shape({
groupOperator: prop_types.default.string,
statement: prop_types.default.string,
conditions: prop_types.default.arrayOf(prop_types.default.oneOfType([prop_types.default.shape({
property: prop_types.default.string,
operator: prop_types.default.string,
value: prop_types.default.oneOfType([
prop_types.default.string,
prop_types.default.arrayOf(prop_types.default.shape({
id: prop_types.default.string,
label: prop_types.default.string
})),
prop_types.default.shape({
id: prop_types.default.string,
label: prop_types.default.string
})
])
}), prop_types.default.object]))
})),
operator: prop_types.default.string
}),
enabledDefault: prop_types.default.bool
}),
startConditionLabel: prop_types.default.string.isRequired
};
//#endregion
exports.default = ConditionBuilderContent;