@carbon/ibm-products
Version:
Carbon for IBM Products
229 lines (215 loc) • 9.04 kB
JavaScript
/**
* 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 _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var React = require('react');
var react = require('@carbon/react');
var index = require('../../_virtual/index.js');
var cx = require('classnames');
var devtools = require('../../global/js/utils/devtools.js');
var ConditionBuilderContent = require('./ConditionBuilderContent/ConditionBuilderContent.js');
var ConditionBuilderProvider = require('./ConditionBuilderContext/ConditionBuilderProvider.js');
var settings = require('../../settings.js');
var handleKeyboardEvents = require('./utils/handleKeyboardEvents.js');
var util = require('./utils/util.js');
// Carbon and package components we use.
/* TODO: @import(s) of carbon components and other package components. */
const componentName = 'ConditionBuilder';
// NOTE: the component SCSS is not imported here: it is rolled up separately.
// Default values can be included here and then assigned to the prop params,
// e.g. prop = defaults.prop,
// This gathers default values together neatly and ensures non-primitive
// values are initialized early to avoid react making unnecessary re-renders.
// Note that default values are not required for props that are 'required',
// nor for props where the component can apply undefined values reasonably.
// Default values should be provided when the component needs to make a choice
// or assumption when a prop is not supplied.
// Default values for props
// const defaults = {
// /* TODO: add defaults for relevant props if needed */
// };
/**
* TODO: A description of the component.
*/
exports.ConditionBuilder = /*#__PURE__*/React.forwardRef((_ref, ref) => {
let {
className,
inputConfig,
startConditionLabel = 'Add Condition',
popOverSearchThreshold,
getOptions,
initialState,
getConditionState,
getActionsState,
variant = util.NON_HIERARCHICAL_VARIANT,
actions,
translateWithId,
statementConfigCustom,
onAddItem,
...rest
} = _ref;
const localRef = React.useRef(null);
const conditionBuilderRef = ref || localRef;
const handleKeyDownHandler = evt => {
handleKeyboardEvents.handleKeyDown(evt, conditionBuilderRef, variant);
};
return /*#__PURE__*/React.createElement(ConditionBuilderProvider.ConditionBuilderProvider, {
inputConfig: inputConfig,
popOverSearchThreshold: popOverSearchThreshold,
getOptions: getOptions,
variant: variant,
translateWithId: translateWithId,
conditionBuilderRef: conditionBuilderRef,
statementConfigCustom: statementConfigCustom,
onAddItem: onAddItem
}, /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({}, rest, {
className: cx(util.blockClass,
// Apply the block class to the main HTML element
className,
// Apply any supplied class names to the main HTML element.
// example: `${blockClass}__template-string-class-${kind}-n-${size}`,
{
// switched classes dependant on props or state
// example: [`${blockClass}__here-if-small`]: size === 'sm',
}),
ref: conditionBuilderRef
}, devtools.getDevtoolsProps(componentName)), /*#__PURE__*/React.createElement(react.VStack, {
className: `${util.blockClass}__${variant}`,
onKeyDown: handleKeyDownHandler
}, /*#__PURE__*/React.createElement(ConditionBuilderContent.default, {
startConditionLabel: startConditionLabel,
getConditionState: getConditionState,
getActionsState: getActionsState,
initialState: initialState,
actions: actions
}))));
});
// Return a placeholder if not released and not enabled by feature flag
exports.ConditionBuilder = settings.pkg.checkComponentEnabled(exports.ConditionBuilder, componentName);
// The display name of the component, used by React. Note that displayName
// is used in preference to relying on function.name.
exports.ConditionBuilder.displayName = componentName;
// The types and DocGen commentary for the component props,
// in alphabetical order (for consistency).
// See https://www.npmjs.com/package/prop-types#usage.
exports.ConditionBuilder.propTypes = {
/**
* optional array of actions
*/
/**@ts-ignore */
actions: index.default.arrayOf(index.default.shape({
id: index.default.oneOfType([index.default.string, index.default.number]).isRequired,
label: index.default.string.isRequired
})),
/**
* Provide an optional class to be applied to the containing node.
*/
className: index.default.string,
/**
* This is a callback that gives back the updated action state
*/
getActionsState: index.default.func,
/**
* This is a callback that gives back updated condition state
*/
getConditionState: index.default.func.isRequired,
/**
* Callback triggered to dynamically fetch options for a property of type 'option'.
* This is invoked when no static options array is provided in the input config.
* The function should return a Promise that resolves with an array of options in the required format.
*/
getOptions: index.default.func,
/**
* Optional prop if you want to pass a saved condition state, pass as "initialState.state".
* "initialState.enabledDefault" will populate the builder with the provided initial state before clicking Add Condition button.
*
* This state should respect the structure of condition state that is available in getConditionState callback
*/
/**@ts-ignore */
initialState: index.default.shape({
state: index.default.shape({
groups: index.default.arrayOf(index.default.shape({
groupOperator: index.default.string,
statement: index.default.string,
conditions: index.default.arrayOf(index.default.oneOfType([index.default.shape({
property: index.default.string,
operator: index.default.string,
value: index.default.oneOfType([index.default.string, index.default.arrayOf(index.default.shape({
id: index.default.string,
label: index.default.string
})), index.default.shape({
id: index.default.string,
label: index.default.string
})])
}), index.default.object]))
})),
operator: index.default.string
}),
enabledDefault: index.default.bool
}),
/**
* This is a mandatory prop that defines the input to the condition builder.
*/
/**@ts-ignore */
inputConfig: index.default.shape({
properties: index.default.arrayOf(index.default.shape({
id: index.default.string.isRequired,
label: index.default.string.isRequired,
icon: index.default.oneOfType([index.default.func, index.default.object]),
type: index.default.oneOf(['text', 'textarea', 'number', 'date', 'option', 'time', 'custom']).isRequired,
description: index.default.string,
//will be displayed on hover of property field
config: index.default.shape({
options: index.default.arrayOf(index.default.shape({
id: index.default.string.isRequired,
label: index.default.string.isRequired,
icon: index.default.oneOfType([index.default.func, index.default.object])
})),
component: index.default.func,
operators: index.default.arrayOf(index.default.shape({
id: index.default.string.isRequired,
label: index.default.string.isRequired
})),
valueFormatter: index.default.func
})
}))
}).isRequired,
/**
* this is an optional callback triggered before adding any condition , subgroup or group.
* User can optionally perform any validation and can stop add action if they return back {preventAdd:true}
*/
onAddItem: index.default.func,
/**
* Provide an mandatory numeric value that will be used to enable search option in the popovers with list.
*/
popOverSearchThreshold: index.default.number.isRequired,
/**
* Provide a label to the button that starts condition builder
*/
startConditionLabel: index.default.string,
/**
* Optional prop for passing custom configuration for statement option from default op
*/
/**@ts-ignore */
statementConfigCustom: index.default.arrayOf(index.default.shape({
id: index.default.string.isRequired,
connector: index.default.oneOf(['and', 'or']).isRequired,
label: index.default.string.isRequired,
secondaryLabel: index.default.string
})),
/**
* Optional prop, if you need to pass translations to the texts on the component instead of the defined defaults.
* This callback function will receive the message id and you need to return the corresponding text for that id.
*/
/**@ts-ignore */
translateWithId: index.default.func,
/* TODO: add types and DocGen for all props. */
/**
* Provide the condition builder variant: Non-Hierarchical/ Hierarchical
*/
variant: index.default.oneOf(['Non-Hierarchical', 'Hierarchical'])
};