UNPKG

@boomerang-io/carbon-addons-boomerang-react

Version:
158 lines (151 loc) 9.92 kB
'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;