@boomerang-io/carbon-addons-boomerang-react
Version:
Carbon Addons for Boomerang apps
158 lines (151 loc) • 9.92 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var react = require('@carbon/react');
var icons = require('@carbon/react/icons');
var cx = require('classnames');
var TooltipHover = require('../TooltipHover/TooltipHover.js');
var accessibility = require('../../tools/accessibility.js');
var settings = require('../../internal/settings.js');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var React__default = /*#__PURE__*/_interopDefault(React);
var cx__default = /*#__PURE__*/_interopDefault(cx);
/*
IBM Confidential
694970X, 69497O0
© Copyright IBM Corp. 2022, 2024
*/
function CreatableComponent({ buttonClassName = `${settings.prefix}--bmrg-creatable__button`, buttonContent = "Add", buttonProps, createKeyValuePair = false, disabled, id, initialValues: externalInitialValues, invalid, invalidText, helperText, key, keyHelperText, keyLabel, keyLabelText, keyPlaceholder, label, labelText = "", max, nonDeletable = false, onKeyBlur, onValueBlur, onInputBlur, onChange, placeholder, tagProps, tagType = "teal", textInputProps, tooltipClassName = `${settings.prefix}--bmrg-creatable__tooltip`, tooltipContent, tooltipProps = { direction: "top" }, type = "text", valueHelperText, valueLabel, valueLabelText, valuePlaceholder, value: externalValues, values, trimInput = false, removeOnlyFirst = false, }) {
const [keyValue, setKeyValue] = React.useState("");
const [value, setValue] = React.useState("");
const [input, setInput] = React.useState("");
const inputRef = React__default.default.useRef(null);
const inputLabel = labelText || label;
const inputKeyLabel = keyLabelText || keyLabel;
const inputValueLabel = valueLabelText || valueLabel;
const [createdItems, setCreatedItems] = React.useState([]);
const createButtonClassName = cx__default.default(buttonClassName, {
"--no-label": (!createKeyValuePair && !inputLabel && !tooltipContent) ||
(createKeyValuePair && !inputKeyLabel && !inputValueLabel),
});
/** Add support for csv strings */
let finalValues;
let finalExternalValues;
let finalExternalInitialValues;
if (typeof values === "string") {
finalValues = values === "" ? [] : values.split(",");
}
else {
finalValues = values;
}
if (typeof externalValues === "string") {
finalExternalValues = externalValues === "" ? [] : externalValues.split(",");
}
else {
finalExternalValues = externalValues;
}
if (typeof externalInitialValues === "string") {
finalExternalInitialValues = externalInitialValues.split(",");
}
else {
finalExternalInitialValues = externalInitialValues;
}
const [initialItems] = React.useState(finalValues || finalExternalValues ? finalValues || finalExternalValues : []);
const tagItems = (finalValues || finalExternalValues ? finalValues || finalExternalValues : createdItems); // Externally controlled if values props exists
const initialTagItems = finalExternalInitialValues || initialItems || []; // Externally controlled if initialValues props exists
const existValue = (keyValue && value) || (trimInput ? input?.trim() : input);
const hasBothHelperText = keyHelperText && valueHelperText;
const hasBothLabelText = inputKeyLabel && inputValueLabel;
const tagsToShow = finalExternalInitialValues ? [...initialTagItems, ...tagItems] : [...tagItems];
const disableInputs = disabled || (max && tagsToShow.length >= max && max > 0);
// Check if key value pair has colon
const keyInputHasColon = keyValue?.includes(":");
const valueInputHasColon = value?.includes(":");
const isKeyInputValid = invalid || keyInputHasColon;
const isValueInputValid = invalid || valueInputHasColon;
const keyInputInvalidText = keyInputHasColon ? '":" is not allowed' : invalidText;
const valueInputInvalidText = valueInputHasColon ? '":" is not allowed' : invalidText;
const isAddButtonDisabled = disabled || !existValue || keyInputHasColon || valueInputHasColon;
const onInputChange = (e) => {
setInput(e.target.value);
};
const onKeyChange = (e) => {
setKeyValue(e.target.value);
};
const onValueChange = (e) => {
setValue(e.target.value);
};
const addValue = (e) => {
e.preventDefault();
const items = [...tagItems];
if (createKeyValuePair && keyValue && value) {
items.push(`${keyValue}:${value}`);
setKeyValue("");
setValue("");
}
else {
if (input) {
// Check if input is a JSON object
const inputToTest = input.trim();
if (inputToTest.slice(0, 1) === "{" && inputToTest.slice(-1) === "}") {
const inputJsonObject = JSON.parse(input);
if (typeof inputJsonObject === "object" && inputJsonObject !== null) {
for (const [key, values] of Object.entries(inputJsonObject)) {
const valuesArray = [...values];
valuesArray.forEach((value) => items.push(`${key}:${value}`));
}
}
}
else {
items.push(input);
}
}
setInput("");
}
setCreatedItems(items);
if (onChange)
onChange(items);
inputRef.current?.focus();
};
const removeValue = (value) => {
let items;
if (removeOnlyFirst) {
items = [...tagItems];
const index = items.indexOf(value);
if (index !== -1) {
items.splice(index, 1);
}
}
else {
items = tagItems.filter((item) => item !== value);
}
setCreatedItems(items);
if (onChange)
onChange(items);
};
return (React__default.default.createElement("div", { key: key, className: `${settings.prefix}--bmrg-creatable` },
React__default.default.createElement("div", { className: `${settings.prefix}--bmrg-creatable__input` },
createKeyValuePair ? (React__default.default.createElement("div", { className: `${settings.prefix}--bmrg-creatable__key-value-inputs` },
React__default.default.createElement("div", { style: {
marginBottom: hasBothHelperText || keyHelperText ? "0" : valueHelperText ? "1.5rem" : "0rem",
marginTop: hasBothLabelText || inputKeyLabel ? "0" : inputValueLabel ? "1.5rem" : "0.5rem",
} },
React__default.default.createElement(react.TextInput, { disabled: disableInputs, id: `${id}-key`, invalid: isKeyInputValid, invalidText: keyInputInvalidText, helperText: keyHelperText, labelText: inputKeyLabel, onBlur: onKeyBlur, onChange: onKeyChange, placeholder: keyPlaceholder, ref: inputRef, type: type, value: keyValue, ...textInputProps })),
React__default.default.createElement("span", { className: `${settings.prefix}--bmrg-creatable__colon`, style: {
marginTop: inputKeyLabel || inputValueLabel ? "2.25rem" : "1.25rem",
} }, ":"),
React__default.default.createElement("div", { style: {
marginBottom: hasBothHelperText || valueHelperText ? "0" : keyHelperText ? "1.5rem" : "0rem",
marginTop: hasBothLabelText || inputValueLabel ? "0" : inputKeyLabel ? "1.5rem" : "0.5rem",
} },
React__default.default.createElement(react.TextInput, { disabled: disableInputs, id: `${id}-value`, invalid: isValueInputValid, invalidText: valueInputInvalidText, helperText: valueHelperText, labelText: inputValueLabel, onBlur: onValueBlur, onChange: onValueChange, placeholder: valuePlaceholder, type: type, value: value, ...textInputProps })))) : (React__default.default.createElement(react.TextInput, { disabled: disableInputs, id: id, invalid: invalid, invalidText: invalidText, helperText: helperText, labelText: React__default.default.createElement("div", { style: { display: "flex" } },
React__default.default.createElement("div", null, inputLabel),
tooltipContent && (React__default.default.createElement("div", { className: tooltipClassName },
React__default.default.createElement(TooltipHover.default, { ...tooltipProps, tooltipText: tooltipContent },
React__default.default.createElement(icons.Information, { size: 16, fill: "currentColor" }))))), onBlur: onInputBlur, onChange: onInputChange, placeholder: placeholder, ref: inputRef, type: type, value: input, ...textInputProps })),
React__default.default.createElement(react.Button, { className: createButtonClassName, disabled: isAddButtonDisabled, onClick: addValue, iconDescription: "Add", renderIcon: icons.Add, size: "md", type: "button", ...buttonProps }, buttonContent)),
React__default.default.createElement("div", { className: `${settings.prefix}--bmrg-creatable__tags` }, tagsToShow.map((item, index) => (React__default.default.createElement(react.Tag, { key: `${item}-${index}`, disabled: disabled, type: tagType, onClick: nonDeletable && initialTagItems.includes(item) ? undefined : () => removeValue(item), onKeyDown: nonDeletable && initialTagItems.includes(item)
? undefined
: (e) => accessibility.isAccessibleKeyDownEvent(e) && removeValue(item), filter: !nonDeletable || (nonDeletable && !initialTagItems.includes(item)), ...tagProps }, item))))));
}
exports.default = CreatableComponent;