@trackunit/react-form-components 2.4.10 → 2.4.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs.js
CHANGED
|
@@ -783,7 +783,7 @@ const BaseInput = ({ className, isInvalid = false, "data-testid": dataTestId, pr
|
|
|
783
783
|
}), "data-testid": dataTestId, placeholder: Boolean(disabled) ? undefined : placeholder, ref: innerRef, required: required, style: {
|
|
784
784
|
paddingLeft: `calc(var(--before-width, 0px) + ${uiDesignTokens.themeSpacing[2]})`,
|
|
785
785
|
paddingRight: `calc(var(--after-width, 0px) + ${uiDesignTokens.themeSpacing[2]})`,
|
|
786
|
-
}, type: type, ...rest, disabled: Boolean(disabled), readOnly: Boolean(readOnly) }), jsxRuntime.jsxs("div", { className: cvaAccessoriesContainer({ className: cvaInputItemPlacementManager({ position: "after" }) }), "data-testid": dataTestId ? `${dataTestId}-after-container` : undefined, ref: afterContainerRef, children: [jsxRuntime.jsx(LockReasonRenderer, { "data-testid": dataTestId
|
|
786
|
+
}, type: type, ...rest, disabled: Boolean(disabled), readOnly: Boolean(readOnly) }), jsxRuntime.jsxs("div", { className: cvaAccessoriesContainer({ className: cvaInputItemPlacementManager({ position: "after" }) }), "data-testid": dataTestId ? `${dataTestId}-after-container` : undefined, ref: afterContainerRef, children: [jsxRuntime.jsx(LockReasonRenderer, { "data-testid": `${dataTestId}-disabled`, lockReason: disabled }), jsxRuntime.jsx(LockReasonRenderer, { "data-testid": `${dataTestId}-readonly`, lockReason: Boolean(readOnly) && !Boolean(disabled) ? readOnly : undefined }), jsxRuntime.jsx(GenericActionsRenderer, { fieldSize: fieldSize, genericAction: genericAction, innerRef: innerRef }), jsxRuntime.jsx(SuffixRenderer, { "data-testid": dataTestId, disabled: Boolean(disabled), isInvalid: isInvalid, isWarning: isWarning, suffix: suffix }), actions, jsxRuntime.jsx(AddonRenderer, { addon: addonAfter, "data-testid": dataTestId, fieldSize: fieldSize, position: "after" })] })] }));
|
|
787
787
|
};
|
|
788
788
|
BaseInput.displayName = "BaseInput";
|
|
789
789
|
|
|
@@ -1972,7 +1972,7 @@ const Checkbox = ({ className, "data-testid": dataTestId = "checkbox", onChange,
|
|
|
1972
1972
|
}), "data-testid": dataTestId, disabled: disabled, onChange: onChange, readOnly: readOnly, ref: ref, tabIndex: isReadonly ? -1 : tabIndex, type: "checkbox", ...rest }), checked || indeterminate ? (jsxRuntime.jsx("div", { className: cvaCheckboxIconOverlay(), children: indeterminate ? (jsxRuntime.jsx(IndeterminateIcon, { className: cvaCheckboxIcon() })) : (jsxRuntime.jsx(CheckIcon, { className: cvaCheckboxIcon() })) })) : null] }), hasLabel ? (jsxRuntime.jsx(reactComponents.Tooltip, { disabled: !isLabelCutOff, label: label, placement: "top", children: jsxRuntime.jsx("div", { className: cvaBinaryControlLabelTooltip(), children: jsxRuntime.jsx("span", { className: tailwindMerge.twMerge(cvaLabel({
|
|
1973
1973
|
invalid: isReadonly ? false : isInvalid,
|
|
1974
1974
|
disabled: isReadonly,
|
|
1975
|
-
}), "block w-full"), id: `checkbox-label-${label}`, ref: labelRef, children: label }) }) },
|
|
1975
|
+
}), "block w-full"), id: `checkbox-label-${label}`, ref: labelRef, children: label }) }) }, `tooltip-${rest.name}`)) : null, suffix !== undefined && suffix !== null && suffix !== "" ? (jsxRuntime.jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": dataTestId ? `${dataTestId}-suffix-container` : undefined, children: suffix })) : null] }));
|
|
1976
1976
|
};
|
|
1977
1977
|
Checkbox.displayName = "Checkbox";
|
|
1978
1978
|
|
|
@@ -2503,7 +2503,7 @@ formatOptionLabel, getMenuGeometry, }) => {
|
|
|
2503
2503
|
const optionLabelDescription = getOptionLabelDescriptionRef.current?.(selectSingleValue.data);
|
|
2504
2504
|
return (jsxRuntime.jsx(ReactSelect.components.SingleValue, { ...selectSingleValue, className: cvaSelectSingleValue({
|
|
2505
2505
|
className: selectSingleValue.className,
|
|
2506
|
-
}), getStyles: getNoStyles, children: jsxRuntime.jsxs("div", { className: "flex items-center gap-1", "data-testid": dataTestId
|
|
2506
|
+
}), getStyles: getNoStyles, children: jsxRuntime.jsxs("div", { className: "flex items-center gap-1", "data-testid": `${dataTestId}-singleValue`, children: [optionPrefix !== null ? optionPrefix : null, selectSingleValue.children, optionLabelDescription !== undefined && optionLabelDescription !== "" ? (jsxRuntime.jsxs("span", { className: "ml-1 text-neutral-400", children: ["(", optionLabelDescription, ")"] })) : null] }) }));
|
|
2507
2507
|
},
|
|
2508
2508
|
MultiValueContainer: ({ children }) => children, // Just pass on the children
|
|
2509
2509
|
MultiValueRemove: () => null, // is built-in to the MultiValue (tag) component
|
|
@@ -3122,7 +3122,7 @@ const FormGroup = ({ isInvalid = false, isWarning = false, helpText, helpAddon,
|
|
|
3122
3122
|
const color = isInvalid ? "danger" : isWarning ? "warning" : null;
|
|
3123
3123
|
return color ? jsxRuntime.jsx(reactComponents.Icon, { color: color, name: "ExclamationTriangle", size: "small" }) : null;
|
|
3124
3124
|
}, [isInvalid, isWarning]);
|
|
3125
|
-
return (jsxRuntime.jsxs("div", { className: cvaFormGroup({ className }), "data-testid": dataTestId, ref: ref, style: style, children: [label !== undefined && label !== null ? (jsxRuntime.jsxs("div", { className: cvaFormGroupContainerBefore(), children: [jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Label, { className: "component-formGroup-font", "data-testid": dataTestId ? `${dataTestId}-label` : undefined, htmlFor: htmlFor, id: htmlFor
|
|
3125
|
+
return (jsxRuntime.jsxs("div", { className: cvaFormGroup({ className }), "data-testid": dataTestId, ref: ref, style: style, children: [label !== undefined && label !== null ? (jsxRuntime.jsxs("div", { className: cvaFormGroupContainerBefore(), children: [jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Label, { className: "component-formGroup-font", "data-testid": dataTestId ? `${dataTestId}-label` : undefined, htmlFor: htmlFor, id: `${htmlFor}-label`, children: label }), required ? (jsxRuntime.jsx(reactComponents.Tooltip, { "data-testid": "required-asterisk", label: t("field.required.asterisk.tooltip"), children: jsxRuntime.jsx("span", { children: "*" }) })) : null] }), tip !== undefined && tip !== null ? (jsxRuntime.jsx("span", { className: "ml-1 mt-1 flex items-center", children: jsxRuntime.jsx(reactComponents.Tooltip, { "data-testid": dataTestId ? `${dataTestId}-tooltip` : undefined, label: tip, placement: "bottom" }) })) : null] })) : null, children, (helpText !== undefined && helpText !== null) || (helpAddon !== undefined && helpAddon !== null) ? (jsxRuntime.jsxs("div", { className: cvaFormGroupContainerAfter({ invalid: isInvalid, isWarning: isWarning }), children: [helpText ? (jsxRuntime.jsxs("div", { className: "flex gap-1", children: [validationStateIcon, jsxRuntime.jsx("span", { "data-testid": dataTestId ? `${dataTestId}-helpText` : undefined, children: helpText })] })) : undefined, helpAddon !== undefined && helpAddon !== null ? (jsxRuntime.jsx("span", { className: cvaHelpAddon(), "data-testid": dataTestId ? `${dataTestId}-helpAddon` : null, children: helpAddon })) : null] })) : null] }));
|
|
3126
3126
|
};
|
|
3127
3127
|
|
|
3128
3128
|
/**
|
|
@@ -3156,7 +3156,7 @@ const FormGroup = ({ isInvalid = false, isWarning = false, helpText, helpAddon,
|
|
|
3156
3156
|
* @param {CheckboxFieldProps} props - The props for the CheckboxField component
|
|
3157
3157
|
*/
|
|
3158
3158
|
const CheckboxField = ({ label, id, tip, helpText, helpAddon, isInvalid, className, checked, "data-testid": dataTestId, checkboxLabel, onChange, ref, disabled = false, readOnly = false, required = false, ...rest }) => {
|
|
3159
|
-
const htmlForId = id ? id :
|
|
3159
|
+
const htmlForId = id ? id : `checkboxField-${sharedUtils.uuidv4()}`;
|
|
3160
3160
|
return (jsxRuntime.jsx(FormGroup, { className: "flex flex-col gap-1", "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: helpText, htmlFor: htmlForId, label: label, required: required ? !(disabled || readOnly) : false, tip: tip, children: jsxRuntime.jsx(Checkbox, { checked: checked, className: className, "data-testid": dataTestId, disabled: disabled, id: htmlForId, label: checkboxLabel, onChange: onChange, readOnly: readOnly, ref: ref, required: required, ...rest }) }));
|
|
3161
3161
|
};
|
|
3162
3162
|
CheckboxField.displayName = "CheckboxField";
|
|
@@ -3270,7 +3270,7 @@ const isValidHEXColor = (value) => {
|
|
|
3270
3270
|
const ColorField = ({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, "data-testid": dataTestId, value: propValue, onChange, isInvalid = undefined, onBlur, fieldSize = "medium", style, disabled, readOnly, isWarning = false, inputClassName, ref, required = false, ...inputProps }) => {
|
|
3271
3271
|
const renderAsDisabled = Boolean(disabled);
|
|
3272
3272
|
const renderAsReadonly = Boolean(readOnly);
|
|
3273
|
-
const htmlForId = react.useMemo(() => (id ? id :
|
|
3273
|
+
const htmlForId = react.useMemo(() => (id ? id : `colorField-${sharedUtils.uuidv4()}`), [id]);
|
|
3274
3274
|
const innerRef = react.useRef(null);
|
|
3275
3275
|
const mergedRef = reactComponents.useMergeRefs([ref, innerRef]);
|
|
3276
3276
|
const [t] = useTranslation();
|
|
@@ -3317,7 +3317,7 @@ const ColorField = ({ label, id, tip, helpText, errorMessage, helpAddon, classNa
|
|
|
3317
3317
|
readOnly: renderAsReadonly,
|
|
3318
3318
|
isWarning,
|
|
3319
3319
|
className,
|
|
3320
|
-
}), "data-testid": dataTestId ? `${dataTestId}-container` : undefined, style: style, children: [jsxRuntime.jsx("input", { "aria-labelledby": htmlForId
|
|
3320
|
+
}), "data-testid": dataTestId ? `${dataTestId}-container` : undefined, style: style, children: [jsxRuntime.jsx("input", { "aria-labelledby": `${htmlForId}-label`, className: cvaInputColorField({ readOnly: renderAsReadonly }), "data-testid": dataTestId, defaultValue: defaultValue, disabled: renderAsDisabled, id: htmlForId, onBlur: handleBlur, onChange: handleInputChange, readOnly: renderAsReadonly, ref: mergedRef, type: "color", value: innerValue }), jsxRuntime.jsx("input", { "aria-labelledby": `${htmlForId}-label-text`, className: cvaInputElement({
|
|
3321
3321
|
className: tailwindMerge.twMerge("focus-visible:outline-hidden px-1", inputClassName),
|
|
3322
3322
|
}), "data-testid": dataTestId ? `${dataTestId}-textField` : undefined, disabled: renderAsDisabled, onBlur: handleBlur, onChange: handleInputChange, readOnly: renderAsReadonly, required: required, type: "text", value: innerValue, ...inputProps }), jsxRuntime.jsx(GenericActionsRenderer, { disabled: renderAsDisabled || renderAsReadonly, fieldSize: fieldSize, genericAction: "edit", innerRef: innerRef, tooltipLabel: t("colorField.tooltip") })] }) }));
|
|
3323
3323
|
};
|
|
@@ -3396,8 +3396,8 @@ ColorField.displayName = "ColorField";
|
|
|
3396
3396
|
*/
|
|
3397
3397
|
const DateField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid = undefined, className, defaultValue, "data-testid": dataTestId, ref, required = false, ...rest }) => {
|
|
3398
3398
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
3399
|
-
const htmlForId = id ? id :
|
|
3400
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(DateBaseInput, { ...rest, "aria-labelledby": htmlForId
|
|
3399
|
+
const htmlForId = id ? id : `dateField-${sharedUtils.uuidv4()}`;
|
|
3400
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(DateBaseInput, { ...rest, "aria-labelledby": `${htmlForId}-label`, className: className, "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref, required: required }) }));
|
|
3401
3401
|
};
|
|
3402
3402
|
DateField.displayName = "DateField";
|
|
3403
3403
|
|
|
@@ -3678,7 +3678,7 @@ const EmailBaseInput = ({ fieldSize = "medium", disabled = false, "data-testid":
|
|
|
3678
3678
|
* ```
|
|
3679
3679
|
*/
|
|
3680
3680
|
const EmailField = ({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, "data-testid": dataTestId, value, onChange, onBlur, isInvalid = false, ref, required = false, ...rest }) => {
|
|
3681
|
-
const htmlForId = id ? id :
|
|
3681
|
+
const htmlForId = id ? id : `emailField-${sharedUtils.uuidv4()}`;
|
|
3682
3682
|
const [t] = useTranslation();
|
|
3683
3683
|
const [innerValue, setInnerValue] = react.useState(() => {
|
|
3684
3684
|
return (value?.toString() || defaultValue?.toString()) ?? "";
|
|
@@ -3698,7 +3698,7 @@ const EmailField = ({ label, id, tip, helpText, errorMessage, helpAddon, classNa
|
|
|
3698
3698
|
onChange(event);
|
|
3699
3699
|
}
|
|
3700
3700
|
}, [onChange]);
|
|
3701
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(EmailBaseInput, { ...rest, "aria-labelledby": htmlForId
|
|
3701
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(EmailBaseInput, { ...rest, "aria-labelledby": `${htmlForId}-label`, className: className, "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, onChange: handleChange, ref: ref, required: required, value: value }) }));
|
|
3702
3702
|
};
|
|
3703
3703
|
EmailField.displayName = "EmailField";
|
|
3704
3704
|
|
|
@@ -3736,7 +3736,7 @@ const FormFieldSelectAdapterMulti = (props) => {
|
|
|
3736
3736
|
// Determine invalid state
|
|
3737
3737
|
const renderAsInvalid = react.useMemo(() => (isInvalid === undefined ? Boolean(errorMessage) : isInvalid), [errorMessage, isInvalid]);
|
|
3738
3738
|
// id to connect label and control
|
|
3739
|
-
const controlId = react.useMemo(() => htmlForProp ?? id ??
|
|
3739
|
+
const controlId = react.useMemo(() => htmlForProp ?? id ?? `multiSelectField-${sharedUtils.uuidv4()}`, [htmlForProp, id]);
|
|
3740
3740
|
// If consumers provided getOptionValue (from BaseSelect props),
|
|
3741
3741
|
// we can render hidden inputs for native form submit / RHF.
|
|
3742
3742
|
const selectPropsWithAccessors = selectProps;
|
|
@@ -3956,7 +3956,7 @@ const validateNumber = (number, required = false, min, max) => {
|
|
|
3956
3956
|
* ```
|
|
3957
3957
|
*/
|
|
3958
3958
|
const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid = undefined, maxLength, className, value, "data-testid": dataTestId, defaultValue, onBlur, onChange, ref, required = false, ...rest }) => {
|
|
3959
|
-
const htmlForId = id ? id :
|
|
3959
|
+
const htmlForId = id ? id : `numberField-${sharedUtils.uuidv4()}`;
|
|
3960
3960
|
const [t] = useTranslation();
|
|
3961
3961
|
const [innerValue, setInnerValue] = react.useState(() => {
|
|
3962
3962
|
return Number(value?.toString()) || Number(defaultValue?.toString());
|
|
@@ -3997,7 +3997,7 @@ const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInva
|
|
|
3997
3997
|
onChange(event);
|
|
3998
3998
|
}
|
|
3999
3999
|
}, [onChange]);
|
|
4000
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(NumberBaseInput, { "aria-labelledby": htmlForId
|
|
4000
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(NumberBaseInput, { "aria-labelledby": `${htmlForId}-label`, id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, onBlur: handleBlur, onChange: handleChange, ref: ref, required: required, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
4001
4001
|
};
|
|
4002
4002
|
NumberField.displayName = "NumberField";
|
|
4003
4003
|
|
|
@@ -4081,11 +4081,15 @@ const cvaTag = cssClassVarianceUtilities.cvaMerge([], {
|
|
|
4081
4081
|
* A card version of a radio button that includes an icon, headings and a description.
|
|
4082
4082
|
*/
|
|
4083
4083
|
const OptionCard = ({ icon, heading, subheading, description, disabled = false, id, value, className, contentClassName, "data-testid": dataTestId, customImage, layout = "default", ref, tagProps, ...rest }) => {
|
|
4084
|
-
const htmlForId = id ??
|
|
4084
|
+
const htmlForId = id ?? `option-card-${sharedUtils.uuidv4()}`;
|
|
4085
4085
|
const subContent = react.useMemo(() => (jsxRuntime.jsxs("div", { className: cvaOptionCardContent({ className: contentClassName }), children: [subheading !== undefined && subheading !== null ? (jsxRuntime.jsx(reactComponents.Text, { align: "center", className: cvaOptionCardText({ type: "subheading", disabled }), type: "span", children: subheading })) : null, description !== undefined && description !== null ? (jsxRuntime.jsx(reactComponents.Text, { align: "center", className: cvaOptionCardText({ type: "description", disabled }), type: "span", children: description })) : null] })), [subheading, description, contentClassName, disabled]);
|
|
4086
|
-
return (jsxRuntime.jsx(reactComponents.Tooltip, { disabled: layout !== "compact" ||
|
|
4086
|
+
return (jsxRuntime.jsx(reactComponents.Tooltip, { disabled: layout !== "compact" ||
|
|
4087
|
+
((subheading === undefined || subheading === null) && (description === undefined || description === null)), label: subContent, mode: "light", placement: "top", children: jsxRuntime.jsxs("div", { className: cvaOptionCardContainer(), "data-testid": dataTestId, children: [jsxRuntime.jsx("input", { className: cvaInput(), "data-testid": dataTestId ? `${dataTestId}-option-card` : undefined, disabled: disabled, id: htmlForId, ref: ref, type: "radio", value: value, ...rest }), jsxRuntime.jsxs("label", { className: cvaOptionCardLabel({ className, disabled, layout }), "data-testid": dataTestId ? `${dataTestId}-option-card-label` : undefined, htmlFor: htmlForId, children: [disabled && icon && !customImage
|
|
4087
4088
|
? react.cloneElement(icon, { className: cvaCustomImage({ disabled, className: icon.props.className }) })
|
|
4088
|
-
: null, disabled && customImage ? jsxRuntime.jsx("img", { alt: "logo", className: customImage.className, src: customImage.src }) : null, !disabled && !customImage && icon, !disabled && customImage ? jsxRuntime.jsx("img", { alt: "logo", className: customImage.className, src: customImage.src }) : null, heading ? (layout === "default" ? (jsxRuntime.jsx(reactComponents.Heading, { className: cvaOptionCardTitle({ disabled, layout }), subtle: disabled, variant: "secondary", children: heading })) : (jsxRuntime.jsx(reactComponents.Text, { align: "center", className: cvaOptionCardTitle({ disabled, layout }), subtle: disabled, type: "span", weight: "thick", children: heading }))) : null, layout === "default" &&
|
|
4089
|
+
: null, disabled && customImage ? jsxRuntime.jsx("img", { alt: "logo", className: customImage.className, src: customImage.src }) : null, !disabled && !customImage && icon, !disabled && customImage ? jsxRuntime.jsx("img", { alt: "logo", className: customImage.className, src: customImage.src }) : null, heading ? (layout === "default" ? (jsxRuntime.jsx(reactComponents.Heading, { className: cvaOptionCardTitle({ disabled, layout }), subtle: disabled, variant: "secondary", children: heading })) : (jsxRuntime.jsx(reactComponents.Text, { align: "center", className: cvaOptionCardTitle({ disabled, layout }), subtle: disabled, type: "span", weight: "thick", children: heading }))) : null, layout === "default" &&
|
|
4090
|
+
((subheading !== undefined && subheading !== null) || (description !== undefined && description !== null))
|
|
4091
|
+
? subContent
|
|
4092
|
+
: null, tagProps ? jsxRuntime.jsx(reactComponents.Tag, { className: cvaTag({ className: tagProps.className, layout }), ...tagProps }) : null] })] }) }));
|
|
4089
4093
|
};
|
|
4090
4094
|
OptionCard.displayName = "OptionCard";
|
|
4091
4095
|
|
|
@@ -4158,11 +4162,11 @@ const PasswordBaseInput = ({ ref, fieldSize = undefined, ...rest }) => {
|
|
|
4158
4162
|
*/
|
|
4159
4163
|
const PasswordField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid = undefined, maxLength, onChange, className, value, "data-testid": dataTestId, ref, required = false, ...rest }) => {
|
|
4160
4164
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
4161
|
-
const htmlFor = id ? id :
|
|
4165
|
+
const htmlFor = id ? id : `passwordField-${sharedUtils.uuidv4()}`;
|
|
4162
4166
|
const handleChange = react.useCallback((event) => {
|
|
4163
4167
|
onChange?.(event);
|
|
4164
4168
|
}, [onChange]);
|
|
4165
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(PasswordBaseInput, { ...rest, "aria-labelledby": htmlFor
|
|
4169
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(PasswordBaseInput, { ...rest, "aria-labelledby": `${htmlFor}-label`, className: className, "data-testid": dataTestId, disabled: rest.readOnly, id: htmlFor, isInvalid: renderAsInvalid, maxLength: maxLength, onChange: handleChange, ref: ref, required: required, value: value }) }));
|
|
4166
4170
|
};
|
|
4167
4171
|
PasswordField.displayName = "PasswordField";
|
|
4168
4172
|
|
|
@@ -4265,13 +4269,12 @@ const phoneErrorMessage = (phoneNumber, required) => {
|
|
|
4265
4269
|
* ```
|
|
4266
4270
|
*/
|
|
4267
4271
|
const PhoneField = ({ label, id, tip, helpText, isInvalid = undefined, errorMessage, value, helpAddon, className, defaultValue, "data-testid": dataTestId, name, onBlur, ref, required = false, ...rest }) => {
|
|
4268
|
-
const htmlForId = id ? id :
|
|
4272
|
+
const htmlForId = id ? id : `phoneField-${sharedUtils.uuidv4()}`;
|
|
4269
4273
|
const [t] = useTranslation();
|
|
4270
4274
|
const [innerValue, setInnerValue] = react.useState(() => {
|
|
4271
4275
|
return (value?.toString() || defaultValue?.toString()) ?? undefined;
|
|
4272
4276
|
});
|
|
4273
|
-
const [renderAsInvalid, setRenderAsInvalid] = react.useState((isInvalid === undefined ? Boolean(errorMessage) : isInvalid) ||
|
|
4274
|
-
!!phoneErrorMessage(value?.toString(), required));
|
|
4277
|
+
const [renderAsInvalid, setRenderAsInvalid] = react.useState((isInvalid === undefined ? Boolean(errorMessage) : isInvalid) || !!phoneErrorMessage(value?.toString(), required));
|
|
4275
4278
|
const errorType = react.useMemo(() => phoneErrorMessage(innerValue, required), [innerValue, required]);
|
|
4276
4279
|
const error = react.useMemo(() => {
|
|
4277
4280
|
// for the case when a custom error message is provided
|
|
@@ -4298,7 +4301,7 @@ const PhoneField = ({ label, id, tip, helpText, isInvalid = undefined, errorMess
|
|
|
4298
4301
|
}
|
|
4299
4302
|
onBlur?.(event);
|
|
4300
4303
|
}, [errorMessage, onBlur, required]);
|
|
4301
|
-
return (jsxRuntime.jsx(FormGroup, { className: className, "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(PhoneBaseInput, { "aria-labelledby": htmlForId
|
|
4304
|
+
return (jsxRuntime.jsx(FormGroup, { className: className, "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(PhoneBaseInput, { "aria-labelledby": `${htmlForId}-label`, "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, name: name, onBlur: handleBlur, ref: ref, required: required, value: value, ...rest }) }));
|
|
4302
4305
|
};
|
|
4303
4306
|
PhoneField.displayName = "PhoneField";
|
|
4304
4307
|
|
|
@@ -4510,7 +4513,7 @@ const RadioItem = ({ label, value, "data-testid": dataTestId, className, descrip
|
|
|
4510
4513
|
}), "data-testid": dataTestId, disabled: isDisabled, id: inputId, name: groupCtx?.name ?? name, onChange: groupCtx?.onChange ?? onChange, readOnly: shouldRenderReadOnly, ref: inputRef, tabIndex: tabIndex ?? (isDisabled ? -1 : isRenderedChecked ? 0 : hasGroupValue ? -1 : 0), type: "radio", value: value, ...rest }), hasLabel ? (jsxRuntime.jsx(reactComponents.Tooltip, { "data-testid": dataTestId ? `${dataTestId}-Label-Tooltip` : undefined, disabled: !isLabelTruncated, label: label, placement: "top", children: jsxRuntime.jsx("span", { className: cvaBinaryControlLabelTooltip(), children: jsxRuntime.jsx("span", { className: tailwindMerge.twMerge(cvaLabel({
|
|
4511
4514
|
invalid: groupCtx?.isInvalid,
|
|
4512
4515
|
disabled: isDisabled,
|
|
4513
|
-
}), "block w-full"), "data-testid": dataTestId ? `${dataTestId}-Label` : undefined, ref: labelRef, children: label }) }) },
|
|
4516
|
+
}), "block w-full"), "data-testid": dataTestId ? `${dataTestId}-Label` : undefined, ref: labelRef, children: label }) }) }, `tooltip-${groupCtx?.name ?? name}`)) : null, suffix !== undefined && suffix !== null && suffix !== "" ? (jsxRuntime.jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": dataTestId ? `${dataTestId}-suffix-container` : undefined, children: suffix })) : null, description ? (jsxRuntime.jsx(reactComponents.Tooltip, { "data-testid": dataTestId ? `${dataTestId}-Description-Tooltip` : undefined, disabled: !isDescriptionTruncated, label: description, placement: "top", children: jsxRuntime.jsx("span", { className: cvaBinaryControlDescriptionTooltip(), children: jsxRuntime.jsx("span", { className: cvaBinaryControlDescription({ disabled: isDisabled }), "data-testid": dataTestId ? `${dataTestId}-Description` : undefined, id: descriptionId, ref: descriptionRef, children: description }) }) }, `description-tooltip-${groupCtx?.name ?? name}`)) : null] }));
|
|
4514
4517
|
};
|
|
4515
4518
|
|
|
4516
4519
|
/**
|
|
@@ -4869,7 +4872,7 @@ const FormFieldSelectAdapter = ({ className, "data-testid": dataTestId, helpText
|
|
|
4869
4872
|
});
|
|
4870
4873
|
}, [value, defaultValue]);
|
|
4871
4874
|
const renderAsInvalid = isInvalid || Boolean(errorMessage);
|
|
4872
|
-
const htmlFor = react.useMemo(() => htmlForProp ?? id ??
|
|
4875
|
+
const htmlFor = react.useMemo(() => htmlForProp ?? id ?? `selectField-${sharedUtils.uuidv4()}`, [htmlForProp, id]);
|
|
4873
4876
|
const innerRef = react.useRef(null);
|
|
4874
4877
|
// eslint-disable-next-line @trackunit/no-typescript-assertion, @typescript-eslint/no-non-null-assertion
|
|
4875
4878
|
react.useImperativeHandle(ref, () => innerRef.current, []);
|
|
@@ -5083,7 +5086,7 @@ const TextLengthIndicator = ({ length, maxLength }) => {
|
|
|
5083
5086
|
const TextAreaField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid = false, maxLength, onChange, className, value, "data-testid": dataTestId, ref, disabled = false, readOnly = false, required = false, ...rest }) => {
|
|
5084
5087
|
const [valueLength, setValueLength] = react.useState(value !== undefined ? `${value}`.length : 0);
|
|
5085
5088
|
const renderAsInvalid = isInvalid || Boolean(errorMessage);
|
|
5086
|
-
const htmlForId = id ? id :
|
|
5089
|
+
const htmlForId = id ? id : `textAreaField-${sharedUtils.uuidv4()}`;
|
|
5087
5090
|
const handleChange = react.useCallback((event) => {
|
|
5088
5091
|
setValueLength(event.target.value.length);
|
|
5089
5092
|
if (onChange) {
|
|
@@ -5091,7 +5094,7 @@ const TextAreaField = ({ id, label, tip, helpText, helpAddon, errorMessage, isIn
|
|
|
5091
5094
|
}
|
|
5092
5095
|
}, [onChange]);
|
|
5093
5096
|
return (jsxRuntime.jsx(FormGroup, { className: tailwindMerge.twMerge(className, "grid", "grid-rows-[auto_1fr_auto]"), "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon ??
|
|
5094
|
-
(typeof maxLength === "number" && jsxRuntime.jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(disabled || readOnly) : false, tip: tip, children: jsxRuntime.jsx(TextAreaBaseInput, { "aria-labelledby": htmlForId
|
|
5097
|
+
(typeof maxLength === "number" && jsxRuntime.jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(disabled || readOnly) : false, tip: tip, children: jsxRuntime.jsx(TextAreaBaseInput, { "aria-labelledby": `${htmlForId}-label`, disabled: disabled, id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, readOnly: readOnly, ref: ref, required: required, value: value, ...rest, className: "h-auto", "data-testid": dataTestId, onChange: handleChange }) }));
|
|
5095
5098
|
};
|
|
5096
5099
|
TextAreaField.displayName = "TextAreaField";
|
|
5097
5100
|
|
|
@@ -5156,7 +5159,7 @@ TextAreaField.displayName = "TextAreaField";
|
|
|
5156
5159
|
const TextField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid = undefined, maxLength, onChange, className, value, "data-testid": dataTestId, isWarning = false, ref, required = false, ...rest }) => {
|
|
5157
5160
|
const [valueLength, setValueLength] = react.useState(value !== undefined ? `${value}`.length : 0);
|
|
5158
5161
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
5159
|
-
const htmlFor = id ? id :
|
|
5162
|
+
const htmlFor = id ? id : `textField-${sharedUtils.uuidv4()}`;
|
|
5160
5163
|
const handleChange = react.useCallback((event) => {
|
|
5161
5164
|
setValueLength(event.target.value.length);
|
|
5162
5165
|
if (onChange) {
|
|
@@ -5164,7 +5167,7 @@ const TextField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvali
|
|
|
5164
5167
|
}
|
|
5165
5168
|
}, [onChange]);
|
|
5166
5169
|
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon ??
|
|
5167
|
-
(typeof maxLength === "number" && jsxRuntime.jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(TextBaseInput, { "aria-labelledby": htmlFor
|
|
5170
|
+
(typeof maxLength === "number" && jsxRuntime.jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(TextBaseInput, { "aria-labelledby": `${htmlFor}-label`, id: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, maxLength: maxLength, ref: ref, required: required, value: value, ...rest, className: className, "data-testid": dataTestId, onChange: handleChange }) }));
|
|
5168
5171
|
};
|
|
5169
5172
|
TextField.displayName = "TextField";
|
|
5170
5173
|
|
|
@@ -5209,7 +5212,7 @@ TextField.displayName = "TextField";
|
|
|
5209
5212
|
*/
|
|
5210
5213
|
const TimeRangeField = ({ className, "data-testid": dataTestId, onChange, isInvalid = undefined, errorMessage, label, tip, children, helpText, id, style, ref, ...rest }) => {
|
|
5211
5214
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
5212
|
-
const htmlFor = id ? id :
|
|
5215
|
+
const htmlFor = id ? id : `timeRangeField-${sharedUtils.uuidv4()}`;
|
|
5213
5216
|
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, ref: ref, style: style, tip: tip, children: jsxRuntime.jsx(TimeRange, { className: className, "data-testid": dataTestId, isInvalid: renderAsInvalid, onChange: onChange, ...rest, children: children }) }));
|
|
5214
5217
|
};
|
|
5215
5218
|
|
|
@@ -5549,8 +5552,8 @@ UploadInput.displayName = "UploadInput";
|
|
|
5549
5552
|
*/
|
|
5550
5553
|
const UploadField = ({ label, id, tip, helpText, errorMessage, isInvalid = false, className, value, "data-testid": dataTestId, ref, disabled = false, required = false, ...rest }) => {
|
|
5551
5554
|
const renderAsInvalid = isInvalid || Boolean(errorMessage);
|
|
5552
|
-
const htmlForId = id ? id :
|
|
5553
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": `${dataTestId}-FormGroup`, helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(disabled || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(UploadInput, { "aria-labelledby": htmlForId
|
|
5555
|
+
const htmlForId = id ? id : `uploadField-${sharedUtils.uuidv4()}`;
|
|
5556
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": `${dataTestId}-FormGroup`, helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(disabled || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(UploadInput, { "aria-labelledby": `${htmlForId}-label`, disabled: disabled, id: htmlForId, isInvalid: renderAsInvalid, ref: ref, required: required, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
5554
5557
|
};
|
|
5555
5558
|
UploadField.displayName = "UploadField";
|
|
5556
5559
|
|
|
@@ -5647,7 +5650,7 @@ const UrlBaseInput = ({ isInvalid = false, "data-testid": dataTestId, disabled =
|
|
|
5647
5650
|
* ```
|
|
5648
5651
|
*/
|
|
5649
5652
|
const UrlField = ({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, "data-testid": dataTestId, isInvalid = false, value, onBlur, ref, required = false, ...rest }) => {
|
|
5650
|
-
const htmlForId = id ? id :
|
|
5653
|
+
const htmlForId = id ? id : `urlField-${sharedUtils.uuidv4()}`;
|
|
5651
5654
|
const [t] = useTranslation();
|
|
5652
5655
|
const [innerValue, setInnerValue] = react.useState(() => {
|
|
5653
5656
|
return (value?.toString() || defaultValue?.toString()) ?? "";
|
|
@@ -5661,7 +5664,7 @@ const UrlField = ({ label, id, tip, helpText, errorMessage, helpAddon, className
|
|
|
5661
5664
|
setRenderAsInvalid(!!validateUrl(newValue, required));
|
|
5662
5665
|
onBlur?.(event);
|
|
5663
5666
|
}, [onBlur, required]);
|
|
5664
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? error : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(UrlBaseInput, { ...rest, "aria-labelledby": htmlForId
|
|
5667
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? error : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(UrlBaseInput, { ...rest, "aria-labelledby": `${htmlForId}-label`, className: className, "data-testid": dataTestId, id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, ref: ref, required: required, value: value ?? defaultValue }) }));
|
|
5665
5668
|
};
|
|
5666
5669
|
UrlField.displayName = "UrlField";
|
|
5667
5670
|
|
package/index.esm.js
CHANGED
|
@@ -782,7 +782,7 @@ const BaseInput = ({ className, isInvalid = false, "data-testid": dataTestId, pr
|
|
|
782
782
|
}), "data-testid": dataTestId, placeholder: Boolean(disabled) ? undefined : placeholder, ref: innerRef, required: required, style: {
|
|
783
783
|
paddingLeft: `calc(var(--before-width, 0px) + ${themeSpacing[2]})`,
|
|
784
784
|
paddingRight: `calc(var(--after-width, 0px) + ${themeSpacing[2]})`,
|
|
785
|
-
}, type: type, ...rest, disabled: Boolean(disabled), readOnly: Boolean(readOnly) }), jsxs("div", { className: cvaAccessoriesContainer({ className: cvaInputItemPlacementManager({ position: "after" }) }), "data-testid": dataTestId ? `${dataTestId}-after-container` : undefined, ref: afterContainerRef, children: [jsx(LockReasonRenderer, { "data-testid": dataTestId
|
|
785
|
+
}, type: type, ...rest, disabled: Boolean(disabled), readOnly: Boolean(readOnly) }), jsxs("div", { className: cvaAccessoriesContainer({ className: cvaInputItemPlacementManager({ position: "after" }) }), "data-testid": dataTestId ? `${dataTestId}-after-container` : undefined, ref: afterContainerRef, children: [jsx(LockReasonRenderer, { "data-testid": `${dataTestId}-disabled`, lockReason: disabled }), jsx(LockReasonRenderer, { "data-testid": `${dataTestId}-readonly`, lockReason: Boolean(readOnly) && !Boolean(disabled) ? readOnly : undefined }), jsx(GenericActionsRenderer, { fieldSize: fieldSize, genericAction: genericAction, innerRef: innerRef }), jsx(SuffixRenderer, { "data-testid": dataTestId, disabled: Boolean(disabled), isInvalid: isInvalid, isWarning: isWarning, suffix: suffix }), actions, jsx(AddonRenderer, { addon: addonAfter, "data-testid": dataTestId, fieldSize: fieldSize, position: "after" })] })] }));
|
|
786
786
|
};
|
|
787
787
|
BaseInput.displayName = "BaseInput";
|
|
788
788
|
|
|
@@ -1971,7 +1971,7 @@ const Checkbox = ({ className, "data-testid": dataTestId = "checkbox", onChange,
|
|
|
1971
1971
|
}), "data-testid": dataTestId, disabled: disabled, onChange: onChange, readOnly: readOnly, ref: ref, tabIndex: isReadonly ? -1 : tabIndex, type: "checkbox", ...rest }), checked || indeterminate ? (jsx("div", { className: cvaCheckboxIconOverlay(), children: indeterminate ? (jsx(IndeterminateIcon, { className: cvaCheckboxIcon() })) : (jsx(CheckIcon, { className: cvaCheckboxIcon() })) })) : null] }), hasLabel ? (jsx(Tooltip, { disabled: !isLabelCutOff, label: label, placement: "top", children: jsx("div", { className: cvaBinaryControlLabelTooltip(), children: jsx("span", { className: twMerge(cvaLabel({
|
|
1972
1972
|
invalid: isReadonly ? false : isInvalid,
|
|
1973
1973
|
disabled: isReadonly,
|
|
1974
|
-
}), "block w-full"), id: `checkbox-label-${label}`, ref: labelRef, children: label }) }) },
|
|
1974
|
+
}), "block w-full"), id: `checkbox-label-${label}`, ref: labelRef, children: label }) }) }, `tooltip-${rest.name}`)) : null, suffix !== undefined && suffix !== null && suffix !== "" ? (jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": dataTestId ? `${dataTestId}-suffix-container` : undefined, children: suffix })) : null] }));
|
|
1975
1975
|
};
|
|
1976
1976
|
Checkbox.displayName = "Checkbox";
|
|
1977
1977
|
|
|
@@ -2502,7 +2502,7 @@ formatOptionLabel, getMenuGeometry, }) => {
|
|
|
2502
2502
|
const optionLabelDescription = getOptionLabelDescriptionRef.current?.(selectSingleValue.data);
|
|
2503
2503
|
return (jsx(components.SingleValue, { ...selectSingleValue, className: cvaSelectSingleValue({
|
|
2504
2504
|
className: selectSingleValue.className,
|
|
2505
|
-
}), getStyles: getNoStyles, children: jsxs("div", { className: "flex items-center gap-1", "data-testid": dataTestId
|
|
2505
|
+
}), getStyles: getNoStyles, children: jsxs("div", { className: "flex items-center gap-1", "data-testid": `${dataTestId}-singleValue`, children: [optionPrefix !== null ? optionPrefix : null, selectSingleValue.children, optionLabelDescription !== undefined && optionLabelDescription !== "" ? (jsxs("span", { className: "ml-1 text-neutral-400", children: ["(", optionLabelDescription, ")"] })) : null] }) }));
|
|
2506
2506
|
},
|
|
2507
2507
|
MultiValueContainer: ({ children }) => children, // Just pass on the children
|
|
2508
2508
|
MultiValueRemove: () => null, // is built-in to the MultiValue (tag) component
|
|
@@ -3121,7 +3121,7 @@ const FormGroup = ({ isInvalid = false, isWarning = false, helpText, helpAddon,
|
|
|
3121
3121
|
const color = isInvalid ? "danger" : isWarning ? "warning" : null;
|
|
3122
3122
|
return color ? jsx(Icon, { color: color, name: "ExclamationTriangle", size: "small" }) : null;
|
|
3123
3123
|
}, [isInvalid, isWarning]);
|
|
3124
|
-
return (jsxs("div", { className: cvaFormGroup({ className }), "data-testid": dataTestId, ref: ref, style: style, children: [label !== undefined && label !== null ? (jsxs("div", { className: cvaFormGroupContainerBefore(), children: [jsxs(Fragment, { children: [jsx(Label, { className: "component-formGroup-font", "data-testid": dataTestId ? `${dataTestId}-label` : undefined, htmlFor: htmlFor, id: htmlFor
|
|
3124
|
+
return (jsxs("div", { className: cvaFormGroup({ className }), "data-testid": dataTestId, ref: ref, style: style, children: [label !== undefined && label !== null ? (jsxs("div", { className: cvaFormGroupContainerBefore(), children: [jsxs(Fragment, { children: [jsx(Label, { className: "component-formGroup-font", "data-testid": dataTestId ? `${dataTestId}-label` : undefined, htmlFor: htmlFor, id: `${htmlFor}-label`, children: label }), required ? (jsx(Tooltip, { "data-testid": "required-asterisk", label: t("field.required.asterisk.tooltip"), children: jsx("span", { children: "*" }) })) : null] }), tip !== undefined && tip !== null ? (jsx("span", { className: "ml-1 mt-1 flex items-center", children: jsx(Tooltip, { "data-testid": dataTestId ? `${dataTestId}-tooltip` : undefined, label: tip, placement: "bottom" }) })) : null] })) : null, children, (helpText !== undefined && helpText !== null) || (helpAddon !== undefined && helpAddon !== null) ? (jsxs("div", { className: cvaFormGroupContainerAfter({ invalid: isInvalid, isWarning: isWarning }), children: [helpText ? (jsxs("div", { className: "flex gap-1", children: [validationStateIcon, jsx("span", { "data-testid": dataTestId ? `${dataTestId}-helpText` : undefined, children: helpText })] })) : undefined, helpAddon !== undefined && helpAddon !== null ? (jsx("span", { className: cvaHelpAddon(), "data-testid": dataTestId ? `${dataTestId}-helpAddon` : null, children: helpAddon })) : null] })) : null] }));
|
|
3125
3125
|
};
|
|
3126
3126
|
|
|
3127
3127
|
/**
|
|
@@ -3155,7 +3155,7 @@ const FormGroup = ({ isInvalid = false, isWarning = false, helpText, helpAddon,
|
|
|
3155
3155
|
* @param {CheckboxFieldProps} props - The props for the CheckboxField component
|
|
3156
3156
|
*/
|
|
3157
3157
|
const CheckboxField = ({ label, id, tip, helpText, helpAddon, isInvalid, className, checked, "data-testid": dataTestId, checkboxLabel, onChange, ref, disabled = false, readOnly = false, required = false, ...rest }) => {
|
|
3158
|
-
const htmlForId = id ? id :
|
|
3158
|
+
const htmlForId = id ? id : `checkboxField-${uuidv4()}`;
|
|
3159
3159
|
return (jsx(FormGroup, { className: "flex flex-col gap-1", "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: helpText, htmlFor: htmlForId, label: label, required: required ? !(disabled || readOnly) : false, tip: tip, children: jsx(Checkbox, { checked: checked, className: className, "data-testid": dataTestId, disabled: disabled, id: htmlForId, label: checkboxLabel, onChange: onChange, readOnly: readOnly, ref: ref, required: required, ...rest }) }));
|
|
3160
3160
|
};
|
|
3161
3161
|
CheckboxField.displayName = "CheckboxField";
|
|
@@ -3269,7 +3269,7 @@ const isValidHEXColor = (value) => {
|
|
|
3269
3269
|
const ColorField = ({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, "data-testid": dataTestId, value: propValue, onChange, isInvalid = undefined, onBlur, fieldSize = "medium", style, disabled, readOnly, isWarning = false, inputClassName, ref, required = false, ...inputProps }) => {
|
|
3270
3270
|
const renderAsDisabled = Boolean(disabled);
|
|
3271
3271
|
const renderAsReadonly = Boolean(readOnly);
|
|
3272
|
-
const htmlForId = useMemo(() => (id ? id :
|
|
3272
|
+
const htmlForId = useMemo(() => (id ? id : `colorField-${uuidv4()}`), [id]);
|
|
3273
3273
|
const innerRef = useRef(null);
|
|
3274
3274
|
const mergedRef = useMergeRefs([ref, innerRef]);
|
|
3275
3275
|
const [t] = useTranslation();
|
|
@@ -3316,7 +3316,7 @@ const ColorField = ({ label, id, tip, helpText, errorMessage, helpAddon, classNa
|
|
|
3316
3316
|
readOnly: renderAsReadonly,
|
|
3317
3317
|
isWarning,
|
|
3318
3318
|
className,
|
|
3319
|
-
}), "data-testid": dataTestId ? `${dataTestId}-container` : undefined, style: style, children: [jsx("input", { "aria-labelledby": htmlForId
|
|
3319
|
+
}), "data-testid": dataTestId ? `${dataTestId}-container` : undefined, style: style, children: [jsx("input", { "aria-labelledby": `${htmlForId}-label`, className: cvaInputColorField({ readOnly: renderAsReadonly }), "data-testid": dataTestId, defaultValue: defaultValue, disabled: renderAsDisabled, id: htmlForId, onBlur: handleBlur, onChange: handleInputChange, readOnly: renderAsReadonly, ref: mergedRef, type: "color", value: innerValue }), jsx("input", { "aria-labelledby": `${htmlForId}-label-text`, className: cvaInputElement({
|
|
3320
3320
|
className: twMerge("focus-visible:outline-hidden px-1", inputClassName),
|
|
3321
3321
|
}), "data-testid": dataTestId ? `${dataTestId}-textField` : undefined, disabled: renderAsDisabled, onBlur: handleBlur, onChange: handleInputChange, readOnly: renderAsReadonly, required: required, type: "text", value: innerValue, ...inputProps }), jsx(GenericActionsRenderer, { disabled: renderAsDisabled || renderAsReadonly, fieldSize: fieldSize, genericAction: "edit", innerRef: innerRef, tooltipLabel: t("colorField.tooltip") })] }) }));
|
|
3322
3322
|
};
|
|
@@ -3395,8 +3395,8 @@ ColorField.displayName = "ColorField";
|
|
|
3395
3395
|
*/
|
|
3396
3396
|
const DateField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid = undefined, className, defaultValue, "data-testid": dataTestId, ref, required = false, ...rest }) => {
|
|
3397
3397
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
3398
|
-
const htmlForId = id ? id :
|
|
3399
|
-
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(DateBaseInput, { ...rest, "aria-labelledby": htmlForId
|
|
3398
|
+
const htmlForId = id ? id : `dateField-${uuidv4()}`;
|
|
3399
|
+
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(DateBaseInput, { ...rest, "aria-labelledby": `${htmlForId}-label`, className: className, "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref, required: required }) }));
|
|
3400
3400
|
};
|
|
3401
3401
|
DateField.displayName = "DateField";
|
|
3402
3402
|
|
|
@@ -3677,7 +3677,7 @@ const EmailBaseInput = ({ fieldSize = "medium", disabled = false, "data-testid":
|
|
|
3677
3677
|
* ```
|
|
3678
3678
|
*/
|
|
3679
3679
|
const EmailField = ({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, "data-testid": dataTestId, value, onChange, onBlur, isInvalid = false, ref, required = false, ...rest }) => {
|
|
3680
|
-
const htmlForId = id ? id :
|
|
3680
|
+
const htmlForId = id ? id : `emailField-${uuidv4()}`;
|
|
3681
3681
|
const [t] = useTranslation();
|
|
3682
3682
|
const [innerValue, setInnerValue] = useState(() => {
|
|
3683
3683
|
return (value?.toString() || defaultValue?.toString()) ?? "";
|
|
@@ -3697,7 +3697,7 @@ const EmailField = ({ label, id, tip, helpText, errorMessage, helpAddon, classNa
|
|
|
3697
3697
|
onChange(event);
|
|
3698
3698
|
}
|
|
3699
3699
|
}, [onChange]);
|
|
3700
|
-
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(EmailBaseInput, { ...rest, "aria-labelledby": htmlForId
|
|
3700
|
+
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(EmailBaseInput, { ...rest, "aria-labelledby": `${htmlForId}-label`, className: className, "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, onChange: handleChange, ref: ref, required: required, value: value }) }));
|
|
3701
3701
|
};
|
|
3702
3702
|
EmailField.displayName = "EmailField";
|
|
3703
3703
|
|
|
@@ -3735,7 +3735,7 @@ const FormFieldSelectAdapterMulti = (props) => {
|
|
|
3735
3735
|
// Determine invalid state
|
|
3736
3736
|
const renderAsInvalid = useMemo(() => (isInvalid === undefined ? Boolean(errorMessage) : isInvalid), [errorMessage, isInvalid]);
|
|
3737
3737
|
// id to connect label and control
|
|
3738
|
-
const controlId = useMemo(() => htmlForProp ?? id ??
|
|
3738
|
+
const controlId = useMemo(() => htmlForProp ?? id ?? `multiSelectField-${uuidv4()}`, [htmlForProp, id]);
|
|
3739
3739
|
// If consumers provided getOptionValue (from BaseSelect props),
|
|
3740
3740
|
// we can render hidden inputs for native form submit / RHF.
|
|
3741
3741
|
const selectPropsWithAccessors = selectProps;
|
|
@@ -3955,7 +3955,7 @@ const validateNumber = (number, required = false, min, max) => {
|
|
|
3955
3955
|
* ```
|
|
3956
3956
|
*/
|
|
3957
3957
|
const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid = undefined, maxLength, className, value, "data-testid": dataTestId, defaultValue, onBlur, onChange, ref, required = false, ...rest }) => {
|
|
3958
|
-
const htmlForId = id ? id :
|
|
3958
|
+
const htmlForId = id ? id : `numberField-${uuidv4()}`;
|
|
3959
3959
|
const [t] = useTranslation();
|
|
3960
3960
|
const [innerValue, setInnerValue] = useState(() => {
|
|
3961
3961
|
return Number(value?.toString()) || Number(defaultValue?.toString());
|
|
@@ -3996,7 +3996,7 @@ const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInva
|
|
|
3996
3996
|
onChange(event);
|
|
3997
3997
|
}
|
|
3998
3998
|
}, [onChange]);
|
|
3999
|
-
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(NumberBaseInput, { "aria-labelledby": htmlForId
|
|
3999
|
+
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(NumberBaseInput, { "aria-labelledby": `${htmlForId}-label`, id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, onBlur: handleBlur, onChange: handleChange, ref: ref, required: required, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
4000
4000
|
};
|
|
4001
4001
|
NumberField.displayName = "NumberField";
|
|
4002
4002
|
|
|
@@ -4080,11 +4080,15 @@ const cvaTag = cvaMerge([], {
|
|
|
4080
4080
|
* A card version of a radio button that includes an icon, headings and a description.
|
|
4081
4081
|
*/
|
|
4082
4082
|
const OptionCard = ({ icon, heading, subheading, description, disabled = false, id, value, className, contentClassName, "data-testid": dataTestId, customImage, layout = "default", ref, tagProps, ...rest }) => {
|
|
4083
|
-
const htmlForId = id ??
|
|
4083
|
+
const htmlForId = id ?? `option-card-${uuidv4()}`;
|
|
4084
4084
|
const subContent = useMemo(() => (jsxs("div", { className: cvaOptionCardContent({ className: contentClassName }), children: [subheading !== undefined && subheading !== null ? (jsx(Text, { align: "center", className: cvaOptionCardText({ type: "subheading", disabled }), type: "span", children: subheading })) : null, description !== undefined && description !== null ? (jsx(Text, { align: "center", className: cvaOptionCardText({ type: "description", disabled }), type: "span", children: description })) : null] })), [subheading, description, contentClassName, disabled]);
|
|
4085
|
-
return (jsx(Tooltip, { disabled: layout !== "compact" ||
|
|
4085
|
+
return (jsx(Tooltip, { disabled: layout !== "compact" ||
|
|
4086
|
+
((subheading === undefined || subheading === null) && (description === undefined || description === null)), label: subContent, mode: "light", placement: "top", children: jsxs("div", { className: cvaOptionCardContainer(), "data-testid": dataTestId, children: [jsx("input", { className: cvaInput(), "data-testid": dataTestId ? `${dataTestId}-option-card` : undefined, disabled: disabled, id: htmlForId, ref: ref, type: "radio", value: value, ...rest }), jsxs("label", { className: cvaOptionCardLabel({ className, disabled, layout }), "data-testid": dataTestId ? `${dataTestId}-option-card-label` : undefined, htmlFor: htmlForId, children: [disabled && icon && !customImage
|
|
4086
4087
|
? cloneElement(icon, { className: cvaCustomImage({ disabled, className: icon.props.className }) })
|
|
4087
|
-
: null, disabled && customImage ? jsx("img", { alt: "logo", className: customImage.className, src: customImage.src }) : null, !disabled && !customImage && icon, !disabled && customImage ? jsx("img", { alt: "logo", className: customImage.className, src: customImage.src }) : null, heading ? (layout === "default" ? (jsx(Heading, { className: cvaOptionCardTitle({ disabled, layout }), subtle: disabled, variant: "secondary", children: heading })) : (jsx(Text, { align: "center", className: cvaOptionCardTitle({ disabled, layout }), subtle: disabled, type: "span", weight: "thick", children: heading }))) : null, layout === "default" &&
|
|
4088
|
+
: null, disabled && customImage ? jsx("img", { alt: "logo", className: customImage.className, src: customImage.src }) : null, !disabled && !customImage && icon, !disabled && customImage ? jsx("img", { alt: "logo", className: customImage.className, src: customImage.src }) : null, heading ? (layout === "default" ? (jsx(Heading, { className: cvaOptionCardTitle({ disabled, layout }), subtle: disabled, variant: "secondary", children: heading })) : (jsx(Text, { align: "center", className: cvaOptionCardTitle({ disabled, layout }), subtle: disabled, type: "span", weight: "thick", children: heading }))) : null, layout === "default" &&
|
|
4089
|
+
((subheading !== undefined && subheading !== null) || (description !== undefined && description !== null))
|
|
4090
|
+
? subContent
|
|
4091
|
+
: null, tagProps ? jsx(Tag, { className: cvaTag({ className: tagProps.className, layout }), ...tagProps }) : null] })] }) }));
|
|
4088
4092
|
};
|
|
4089
4093
|
OptionCard.displayName = "OptionCard";
|
|
4090
4094
|
|
|
@@ -4157,11 +4161,11 @@ const PasswordBaseInput = ({ ref, fieldSize = undefined, ...rest }) => {
|
|
|
4157
4161
|
*/
|
|
4158
4162
|
const PasswordField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid = undefined, maxLength, onChange, className, value, "data-testid": dataTestId, ref, required = false, ...rest }) => {
|
|
4159
4163
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
4160
|
-
const htmlFor = id ? id :
|
|
4164
|
+
const htmlFor = id ? id : `passwordField-${uuidv4()}`;
|
|
4161
4165
|
const handleChange = useCallback((event) => {
|
|
4162
4166
|
onChange?.(event);
|
|
4163
4167
|
}, [onChange]);
|
|
4164
|
-
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(PasswordBaseInput, { ...rest, "aria-labelledby": htmlFor
|
|
4168
|
+
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(PasswordBaseInput, { ...rest, "aria-labelledby": `${htmlFor}-label`, className: className, "data-testid": dataTestId, disabled: rest.readOnly, id: htmlFor, isInvalid: renderAsInvalid, maxLength: maxLength, onChange: handleChange, ref: ref, required: required, value: value }) }));
|
|
4165
4169
|
};
|
|
4166
4170
|
PasswordField.displayName = "PasswordField";
|
|
4167
4171
|
|
|
@@ -4264,13 +4268,12 @@ const phoneErrorMessage = (phoneNumber, required) => {
|
|
|
4264
4268
|
* ```
|
|
4265
4269
|
*/
|
|
4266
4270
|
const PhoneField = ({ label, id, tip, helpText, isInvalid = undefined, errorMessage, value, helpAddon, className, defaultValue, "data-testid": dataTestId, name, onBlur, ref, required = false, ...rest }) => {
|
|
4267
|
-
const htmlForId = id ? id :
|
|
4271
|
+
const htmlForId = id ? id : `phoneField-${uuidv4()}`;
|
|
4268
4272
|
const [t] = useTranslation();
|
|
4269
4273
|
const [innerValue, setInnerValue] = useState(() => {
|
|
4270
4274
|
return (value?.toString() || defaultValue?.toString()) ?? undefined;
|
|
4271
4275
|
});
|
|
4272
|
-
const [renderAsInvalid, setRenderAsInvalid] = useState((isInvalid === undefined ? Boolean(errorMessage) : isInvalid) ||
|
|
4273
|
-
!!phoneErrorMessage(value?.toString(), required));
|
|
4276
|
+
const [renderAsInvalid, setRenderAsInvalid] = useState((isInvalid === undefined ? Boolean(errorMessage) : isInvalid) || !!phoneErrorMessage(value?.toString(), required));
|
|
4274
4277
|
const errorType = useMemo(() => phoneErrorMessage(innerValue, required), [innerValue, required]);
|
|
4275
4278
|
const error = useMemo(() => {
|
|
4276
4279
|
// for the case when a custom error message is provided
|
|
@@ -4297,7 +4300,7 @@ const PhoneField = ({ label, id, tip, helpText, isInvalid = undefined, errorMess
|
|
|
4297
4300
|
}
|
|
4298
4301
|
onBlur?.(event);
|
|
4299
4302
|
}, [errorMessage, onBlur, required]);
|
|
4300
|
-
return (jsx(FormGroup, { className: className, "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(PhoneBaseInput, { "aria-labelledby": htmlForId
|
|
4303
|
+
return (jsx(FormGroup, { className: className, "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(PhoneBaseInput, { "aria-labelledby": `${htmlForId}-label`, "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, name: name, onBlur: handleBlur, ref: ref, required: required, value: value, ...rest }) }));
|
|
4301
4304
|
};
|
|
4302
4305
|
PhoneField.displayName = "PhoneField";
|
|
4303
4306
|
|
|
@@ -4509,7 +4512,7 @@ const RadioItem = ({ label, value, "data-testid": dataTestId, className, descrip
|
|
|
4509
4512
|
}), "data-testid": dataTestId, disabled: isDisabled, id: inputId, name: groupCtx?.name ?? name, onChange: groupCtx?.onChange ?? onChange, readOnly: shouldRenderReadOnly, ref: inputRef, tabIndex: tabIndex ?? (isDisabled ? -1 : isRenderedChecked ? 0 : hasGroupValue ? -1 : 0), type: "radio", value: value, ...rest }), hasLabel ? (jsx(Tooltip, { "data-testid": dataTestId ? `${dataTestId}-Label-Tooltip` : undefined, disabled: !isLabelTruncated, label: label, placement: "top", children: jsx("span", { className: cvaBinaryControlLabelTooltip(), children: jsx("span", { className: twMerge(cvaLabel({
|
|
4510
4513
|
invalid: groupCtx?.isInvalid,
|
|
4511
4514
|
disabled: isDisabled,
|
|
4512
|
-
}), "block w-full"), "data-testid": dataTestId ? `${dataTestId}-Label` : undefined, ref: labelRef, children: label }) }) },
|
|
4515
|
+
}), "block w-full"), "data-testid": dataTestId ? `${dataTestId}-Label` : undefined, ref: labelRef, children: label }) }) }, `tooltip-${groupCtx?.name ?? name}`)) : null, suffix !== undefined && suffix !== null && suffix !== "" ? (jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": dataTestId ? `${dataTestId}-suffix-container` : undefined, children: suffix })) : null, description ? (jsx(Tooltip, { "data-testid": dataTestId ? `${dataTestId}-Description-Tooltip` : undefined, disabled: !isDescriptionTruncated, label: description, placement: "top", children: jsx("span", { className: cvaBinaryControlDescriptionTooltip(), children: jsx("span", { className: cvaBinaryControlDescription({ disabled: isDisabled }), "data-testid": dataTestId ? `${dataTestId}-Description` : undefined, id: descriptionId, ref: descriptionRef, children: description }) }) }, `description-tooltip-${groupCtx?.name ?? name}`)) : null] }));
|
|
4513
4516
|
};
|
|
4514
4517
|
|
|
4515
4518
|
/**
|
|
@@ -4868,7 +4871,7 @@ const FormFieldSelectAdapter = ({ className, "data-testid": dataTestId, helpText
|
|
|
4868
4871
|
});
|
|
4869
4872
|
}, [value, defaultValue]);
|
|
4870
4873
|
const renderAsInvalid = isInvalid || Boolean(errorMessage);
|
|
4871
|
-
const htmlFor = useMemo(() => htmlForProp ?? id ??
|
|
4874
|
+
const htmlFor = useMemo(() => htmlForProp ?? id ?? `selectField-${uuidv4()}`, [htmlForProp, id]);
|
|
4872
4875
|
const innerRef = useRef(null);
|
|
4873
4876
|
// eslint-disable-next-line @trackunit/no-typescript-assertion, @typescript-eslint/no-non-null-assertion
|
|
4874
4877
|
useImperativeHandle(ref, () => innerRef.current, []);
|
|
@@ -5082,7 +5085,7 @@ const TextLengthIndicator = ({ length, maxLength }) => {
|
|
|
5082
5085
|
const TextAreaField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid = false, maxLength, onChange, className, value, "data-testid": dataTestId, ref, disabled = false, readOnly = false, required = false, ...rest }) => {
|
|
5083
5086
|
const [valueLength, setValueLength] = useState(value !== undefined ? `${value}`.length : 0);
|
|
5084
5087
|
const renderAsInvalid = isInvalid || Boolean(errorMessage);
|
|
5085
|
-
const htmlForId = id ? id :
|
|
5088
|
+
const htmlForId = id ? id : `textAreaField-${uuidv4()}`;
|
|
5086
5089
|
const handleChange = useCallback((event) => {
|
|
5087
5090
|
setValueLength(event.target.value.length);
|
|
5088
5091
|
if (onChange) {
|
|
@@ -5090,7 +5093,7 @@ const TextAreaField = ({ id, label, tip, helpText, helpAddon, errorMessage, isIn
|
|
|
5090
5093
|
}
|
|
5091
5094
|
}, [onChange]);
|
|
5092
5095
|
return (jsx(FormGroup, { className: twMerge(className, "grid", "grid-rows-[auto_1fr_auto]"), "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon ??
|
|
5093
|
-
(typeof maxLength === "number" && jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(disabled || readOnly) : false, tip: tip, children: jsx(TextAreaBaseInput, { "aria-labelledby": htmlForId
|
|
5096
|
+
(typeof maxLength === "number" && jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(disabled || readOnly) : false, tip: tip, children: jsx(TextAreaBaseInput, { "aria-labelledby": `${htmlForId}-label`, disabled: disabled, id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, readOnly: readOnly, ref: ref, required: required, value: value, ...rest, className: "h-auto", "data-testid": dataTestId, onChange: handleChange }) }));
|
|
5094
5097
|
};
|
|
5095
5098
|
TextAreaField.displayName = "TextAreaField";
|
|
5096
5099
|
|
|
@@ -5155,7 +5158,7 @@ TextAreaField.displayName = "TextAreaField";
|
|
|
5155
5158
|
const TextField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid = undefined, maxLength, onChange, className, value, "data-testid": dataTestId, isWarning = false, ref, required = false, ...rest }) => {
|
|
5156
5159
|
const [valueLength, setValueLength] = useState(value !== undefined ? `${value}`.length : 0);
|
|
5157
5160
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
5158
|
-
const htmlFor = id ? id :
|
|
5161
|
+
const htmlFor = id ? id : `textField-${uuidv4()}`;
|
|
5159
5162
|
const handleChange = useCallback((event) => {
|
|
5160
5163
|
setValueLength(event.target.value.length);
|
|
5161
5164
|
if (onChange) {
|
|
@@ -5163,7 +5166,7 @@ const TextField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvali
|
|
|
5163
5166
|
}
|
|
5164
5167
|
}, [onChange]);
|
|
5165
5168
|
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon ??
|
|
5166
|
-
(typeof maxLength === "number" && jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(TextBaseInput, { "aria-labelledby": htmlFor
|
|
5169
|
+
(typeof maxLength === "number" && jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(TextBaseInput, { "aria-labelledby": `${htmlFor}-label`, id: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, maxLength: maxLength, ref: ref, required: required, value: value, ...rest, className: className, "data-testid": dataTestId, onChange: handleChange }) }));
|
|
5167
5170
|
};
|
|
5168
5171
|
TextField.displayName = "TextField";
|
|
5169
5172
|
|
|
@@ -5208,7 +5211,7 @@ TextField.displayName = "TextField";
|
|
|
5208
5211
|
*/
|
|
5209
5212
|
const TimeRangeField = ({ className, "data-testid": dataTestId, onChange, isInvalid = undefined, errorMessage, label, tip, children, helpText, id, style, ref, ...rest }) => {
|
|
5210
5213
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
5211
|
-
const htmlFor = id ? id :
|
|
5214
|
+
const htmlFor = id ? id : `timeRangeField-${uuidv4()}`;
|
|
5212
5215
|
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, ref: ref, style: style, tip: tip, children: jsx(TimeRange, { className: className, "data-testid": dataTestId, isInvalid: renderAsInvalid, onChange: onChange, ...rest, children: children }) }));
|
|
5213
5216
|
};
|
|
5214
5217
|
|
|
@@ -5548,8 +5551,8 @@ UploadInput.displayName = "UploadInput";
|
|
|
5548
5551
|
*/
|
|
5549
5552
|
const UploadField = ({ label, id, tip, helpText, errorMessage, isInvalid = false, className, value, "data-testid": dataTestId, ref, disabled = false, required = false, ...rest }) => {
|
|
5550
5553
|
const renderAsInvalid = isInvalid || Boolean(errorMessage);
|
|
5551
|
-
const htmlForId = id ? id :
|
|
5552
|
-
return (jsx(FormGroup, { "data-testid": `${dataTestId}-FormGroup`, helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(disabled || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(UploadInput, { "aria-labelledby": htmlForId
|
|
5554
|
+
const htmlForId = id ? id : `uploadField-${uuidv4()}`;
|
|
5555
|
+
return (jsx(FormGroup, { "data-testid": `${dataTestId}-FormGroup`, helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(disabled || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(UploadInput, { "aria-labelledby": `${htmlForId}-label`, disabled: disabled, id: htmlForId, isInvalid: renderAsInvalid, ref: ref, required: required, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
5553
5556
|
};
|
|
5554
5557
|
UploadField.displayName = "UploadField";
|
|
5555
5558
|
|
|
@@ -5646,7 +5649,7 @@ const UrlBaseInput = ({ isInvalid = false, "data-testid": dataTestId, disabled =
|
|
|
5646
5649
|
* ```
|
|
5647
5650
|
*/
|
|
5648
5651
|
const UrlField = ({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, "data-testid": dataTestId, isInvalid = false, value, onBlur, ref, required = false, ...rest }) => {
|
|
5649
|
-
const htmlForId = id ? id :
|
|
5652
|
+
const htmlForId = id ? id : `urlField-${uuidv4()}`;
|
|
5650
5653
|
const [t] = useTranslation();
|
|
5651
5654
|
const [innerValue, setInnerValue] = useState(() => {
|
|
5652
5655
|
return (value?.toString() || defaultValue?.toString()) ?? "";
|
|
@@ -5660,7 +5663,7 @@ const UrlField = ({ label, id, tip, helpText, errorMessage, helpAddon, className
|
|
|
5660
5663
|
setRenderAsInvalid(!!validateUrl(newValue, required));
|
|
5661
5664
|
onBlur?.(event);
|
|
5662
5665
|
}, [onBlur, required]);
|
|
5663
|
-
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? error : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(UrlBaseInput, { ...rest, "aria-labelledby": htmlForId
|
|
5666
|
+
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? error : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(UrlBaseInput, { ...rest, "aria-labelledby": `${htmlForId}-label`, className: className, "data-testid": dataTestId, id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, ref: ref, required: required, value: value ?? defaultValue }) }));
|
|
5664
5667
|
};
|
|
5665
5668
|
UrlField.displayName = "UrlField";
|
|
5666
5669
|
|
|
@@ -197,7 +197,7 @@ exports.logSummary = logSummary;
|
|
|
197
197
|
const insertAttributeIntoOpeningTag = (content, openingElement, attributeText) => {
|
|
198
198
|
const tagName = openingElement.tagName;
|
|
199
199
|
const insertPos = tagName.getEnd();
|
|
200
|
-
return content.slice(0, insertPos)
|
|
200
|
+
return `${content.slice(0, insertPos)} ${attributeText}${content.slice(insertPos)}`;
|
|
201
201
|
};
|
|
202
202
|
exports.insertAttributeIntoOpeningTag = insertAttributeIntoOpeningTag;
|
|
203
203
|
//# sourceMappingURL=jsx-utils.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-form-components",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.12",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"migrations": "./migrations.json",
|
|
@@ -10,17 +10,17 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"react-calendar": "^6.0.0",
|
|
12
12
|
"react-select": "^5.10.2",
|
|
13
|
-
"@trackunit/date-and-time-utils": "1.14.
|
|
13
|
+
"@trackunit/date-and-time-utils": "1.14.7",
|
|
14
14
|
"usehooks-ts": "^3.1.0",
|
|
15
15
|
"libphonenumber-js": "^1.13.6",
|
|
16
16
|
"zod": "^3.25.76",
|
|
17
17
|
"tailwind-merge": "^2.0.0",
|
|
18
|
-
"@trackunit/css-class-variance-utilities": "1.14.
|
|
19
|
-
"@trackunit/react-components": "2.
|
|
20
|
-
"@trackunit/ui-icons": "1.14.
|
|
21
|
-
"@trackunit/shared-utils": "1.16.
|
|
22
|
-
"@trackunit/ui-design-tokens": "1.14.
|
|
23
|
-
"@trackunit/i18n-library-translation": "2.3.
|
|
18
|
+
"@trackunit/css-class-variance-utilities": "1.14.6",
|
|
19
|
+
"@trackunit/react-components": "2.7.1",
|
|
20
|
+
"@trackunit/ui-icons": "1.14.6",
|
|
21
|
+
"@trackunit/shared-utils": "1.16.6",
|
|
22
|
+
"@trackunit/ui-design-tokens": "1.14.6",
|
|
23
|
+
"@trackunit/i18n-library-translation": "2.3.8",
|
|
24
24
|
"string-ts": "^2.0.0",
|
|
25
25
|
"es-toolkit": "^1.39.10"
|
|
26
26
|
},
|
package/migrations/entry.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../../libs/react/form-components/migrations/entry.ts"],"names":[],"mappings":"","sourcesContent":["// Migration entry point for @nx/js:tsc build target.\n// Migrations are registered in ../migrations.json and resolved by NX at runtime.\nexport {};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsx-utils.js","sourceRoot":"","sources":["../../../../../../libs/react/form-components/migrations/utils/jsx-utils.ts"],"names":[],"mappings":";;;;AAAA,uCAAqE;AACrE,uDAAoD;AA8L3C,wFA9LA,iBAAO,OA8LA;AA7LhB,uDAAiC;AAEjC,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,CAAU,CAAC;AACjD,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAEvD,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAW,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AACpG,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAW,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AAElG,MAAM,kBAAkB,GAAG,CAAC,QAAgB,EAAW,EAAE,CACvD,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AAE9E,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAW,EAAE,CAChD,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAE5F;;;;;GAKG;AACI,MAAM,aAAa,GAAG,CAC3B,IAAU,EACV,MAAc,EACd,QAA0E,EAClE,EAAE;IACV,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAA,6BAAoB,EAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE;QACzC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;YAAE,OAAO;QACjC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC;YAAE,OAAO;QAClE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO;QAC7B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO;QACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACrE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAnBW,QAAA,aAAa,iBAmBxB;AAEF;;;GAGG;AACI,MAAM,YAAY,GAAG,CAC1B,IAAU,EACV,MAAc,EACd,QAA0E,EAClE,EAAE;IACV,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAA,6BAAoB,EAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE;QACzC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,OAAO;QAChC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC;YAAE,OAAO;QAClE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO;QAC7B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO;QACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACrE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAnBW,QAAA,YAAY,gBAmBvB;AAEF;;;;;;;GAOG;AACI,MAAM,kBAAkB,GAAG,CAAC,UAAyB,EAAE,WAAmB,EAAiC,EAAE;IAClH,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QACzC,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC;YAAE,SAAS;QAC5C,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;QAC7C,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,eAAe,CAAC;YAAE,SAAS;QACnD,IAAI,eAAe,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QAEnD,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC;QACvD,IAAI,aAAa,KAAK,SAAS,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,aAAa,CAAC;YAAE,SAAS;QAE/E,KAAK,MAAM,OAAO,IAAI,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YACpC,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,IAAI,SAAS,CAAC;YAC7D,MAAM,CAAC,SAAS,CAAC,GAAG,YAAY,CAAC;YACjC,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC,CAAC;AAtBW,QAAA,kBAAkB,sBAsB7B;AAEF;;;GAGG;AACI,MAAM,gBAAgB,GAAG,CAC9B,UAAyB,EACzB,WAAmB,EACnB,YAAoB,EACL,EAAE;IACjB,MAAM,OAAO,GAAG,IAAA,0BAAkB,EAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAC5D,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,IAAI,QAAQ,KAAK,YAAY;YAAE,OAAO,KAAK,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAXW,QAAA,gBAAgB,oBAW3B;AASF;;;;;;;GAOG;AACI,MAAM,eAAe,GAAG,CAC7B,UAAyB,EACzB,QAA+B,EACC,EAAE;IAClC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEjC,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QACpC,IAAI,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnE,OAAO,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;aAAM,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC;YACpC,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzE,OAAO,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,KAAK,CAAC,UAAU,CAAC,CAAC;IAClB,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAvBW,QAAA,eAAe,mBAuB1B;AAEF;;;;GAIG;AACI,MAAM,gBAAgB,GAAG,CAC9B,cAA+D,EAC/D,aAAqB,EACG,EAAE;IAC1B,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;QACxD,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC;YAAE,SAAS;QACvC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAC1C,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa;YAAE,OAAO,IAAI,CAAC;IACpD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAVW,QAAA,gBAAgB,oBAU3B;AAEF;;;GAGG;AACI,MAAM,kBAAkB,GAAG,CAAC,cAA+D,EAAW,EAAE;IAC7G,OAAO,cAAc,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1F,CAAC,CAAC;AAFW,QAAA,kBAAkB,sBAE7B;AAEF;;;;GAIG;AACI,MAAM,QAAQ,GAAG,CAAC,OAAe,EAAE,QAAQ,GAAG,UAAU,EAAiB,EAAE,CAChF,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAD7E,QAAA,QAAQ,YACqE;AAK1F;;;GAGG;AACI,MAAM,UAAU,GAAG,CAAC,aAAqB,EAAE,OAAe,EAAE,kBAA2B,EAAQ,EAAE;IACtG,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,eAAM,CAAC,IAAI,CAAC,KAAK,aAAa,oBAAoB,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IACD,MAAM,YAAY,GAChB,kBAAkB,KAAK,SAAS,IAAI,kBAAkB,GAAG,CAAC;QACxD,CAAC,CAAC,KAAK,kBAAkB,kCAAkC;QAC3D,CAAC,CAAC,EAAE,CAAC;IACT,eAAM,CAAC,IAAI,CAAC,KAAK,aAAa,aAAa,OAAO,WAAW,YAAY,EAAE,CAAC,CAAC;AAC/E,CAAC,CAAC;AAVW,QAAA,UAAU,cAUrB;AAEF;;;;;;GAMG;AACI,MAAM,6BAA6B,GAAG,CAC3C,OAAe,EACf,cAA+D,EAC/D,aAAqB,EACb,EAAE;IACV,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC;IACvC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IACnC,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,aAAa,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AACtF,CAAC,CAAC;AARW,QAAA,6BAA6B,iCAQxC","sourcesContent":["import { logger, type Tree, visitNotIgnoredFiles } from \"@nx/devkit\";\nimport { tsquery } from \"@phenomnomnominal/tsquery\";\nimport * as ts from \"typescript\";\n\nconst TSX_EXTENSIONS = [\".tsx\", \".jsx\"] as const;\nconst TS_EXTENSIONS = [\".ts\", \".tsx\", \".jsx\"] as const;\n\nconst isTsxFile = (filePath: string): boolean => TSX_EXTENSIONS.some(ext => filePath.endsWith(ext));\nconst isTsFile = (filePath: string): boolean => TS_EXTENSIONS.some(ext => filePath.endsWith(ext));\n\nconst isUnderNodeModules = (filePath: string): boolean =>\n filePath.includes(\"/node_modules/\") || filePath.startsWith(\"node_modules/\");\n\nconst isUnderDist = (filePath: string): boolean =>\n filePath.includes(\"/dist/\") || filePath.startsWith(\"dist/\") || filePath.includes(\"/.nx/\");\n\n/**\n * Visits every `.tsx`/`.jsx` file under the workspace root and invokes the\n * callback with the file path and its current contents. Files that don't\n * include the marker substring are skipped, which makes large workspaces\n * cheap to scan.\n */\nexport const visitTsxFiles = (\n tree: Tree,\n marker: string,\n callback: (filePath: string, content: string) => string | null | undefined\n): number => {\n let touched = 0;\n visitNotIgnoredFiles(tree, \"/\", filePath => {\n if (!isTsxFile(filePath)) return;\n if (isUnderNodeModules(filePath) || isUnderDist(filePath)) return;\n const content = tree.read(filePath, \"utf-8\");\n if (content === null) return;\n if (!content.includes(marker)) return;\n const updated = callback(filePath, content);\n if (updated !== null && updated !== undefined && updated !== content) {\n tree.write(filePath, updated);\n touched += 1;\n }\n });\n return touched;\n};\n\n/**\n * Same as {@link visitTsxFiles} but also includes plain `.ts` files. Use this\n * when the codemod also rewrites non-JSX files such as helpers or hooks.\n */\nexport const visitTsFiles = (\n tree: Tree,\n marker: string,\n callback: (filePath: string, content: string) => string | null | undefined\n): number => {\n let touched = 0;\n visitNotIgnoredFiles(tree, \"/\", filePath => {\n if (!isTsFile(filePath)) return;\n if (isUnderNodeModules(filePath) || isUnderDist(filePath)) return;\n const content = tree.read(filePath, \"utf-8\");\n if (content === null) return;\n if (!content.includes(marker)) return;\n const updated = callback(filePath, content);\n if (updated !== null && updated !== undefined && updated !== content) {\n tree.write(filePath, updated);\n touched += 1;\n }\n });\n return touched;\n};\n\n/**\n * Mapping of imported component aliases to their original names for a given\n * package. For `import { IconButton as Btn } from \"@trackunit/react-components\"`\n * this returns `{ Btn: \"IconButton\" }`.\n *\n * Returns `null` when the file imports nothing from the package, which lets\n * callers short-circuit before parsing JSX.\n */\nexport const getImportedAliases = (sourceFile: ts.SourceFile, packageName: string): Record<string, string> | null => {\n const result: Record<string, string> = {};\n let found = false;\n\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpecifier = stmt.moduleSpecifier;\n if (!ts.isStringLiteral(moduleSpecifier)) continue;\n if (moduleSpecifier.text !== packageName) continue;\n\n const namedBindings = stmt.importClause?.namedBindings;\n if (namedBindings === undefined || !ts.isNamedImports(namedBindings)) continue;\n\n for (const element of namedBindings.elements) {\n const localName = element.name.text;\n const importedName = element.propertyName?.text ?? localName;\n result[localName] = importedName;\n found = true;\n }\n }\n\n return found ? result : null;\n};\n\n/**\n * Returns the local alias used in this file for `originalName` when imported\n * from `packageName`, or `null` if the component is not imported.\n */\nexport const getLocalAliasFor = (\n sourceFile: ts.SourceFile,\n packageName: string,\n originalName: string\n): string | null => {\n const aliases = getImportedAliases(sourceFile, packageName);\n if (aliases === null) return null;\n for (const [local, original] of Object.entries(aliases)) {\n if (original === originalName) return local;\n }\n return null;\n};\n\nexport type JsxElementMatch = {\n /** The opening JSX element (the one carrying the attributes). */\n openingElement: ts.JsxOpeningElement | ts.JsxSelfClosingElement;\n /** The full element including children, or the self-closing element. */\n element: ts.JsxElement | ts.JsxSelfClosingElement;\n};\n\n/**\n * Finds every JSX element whose tag name resolves to one of `tagNames`\n * (typically the local aliases returned by {@link getImportedAliases}).\n *\n * The result intentionally includes both opening and full elements so callers\n * can manipulate attributes (via `openingElement`) or wrap/replace the whole\n * element (via `element`).\n */\nexport const findJsxElements = (\n sourceFile: ts.SourceFile,\n tagNames: ReadonlyArray<string>\n): ReadonlyArray<JsxElementMatch> => {\n const matches: Array<JsxElementMatch> = [];\n const tagSet = new Set(tagNames);\n\n const visit = (node: ts.Node): void => {\n if (ts.isJsxSelfClosingElement(node)) {\n if (ts.isIdentifier(node.tagName) && tagSet.has(node.tagName.text)) {\n matches.push({ openingElement: node, element: node });\n }\n } else if (ts.isJsxElement(node)) {\n const opening = node.openingElement;\n if (ts.isIdentifier(opening.tagName) && tagSet.has(opening.tagName.text)) {\n matches.push({ openingElement: opening, element: node });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return matches;\n};\n\n/**\n * Looks up a named JSX attribute on the opening element. Returns `null` when\n * the attribute is missing or part of a spread attribute (which we cannot\n * statically inspect).\n */\nexport const findJsxAttribute = (\n openingElement: ts.JsxOpeningElement | ts.JsxSelfClosingElement,\n attributeName: string\n): ts.JsxAttribute | null => {\n for (const attr of openingElement.attributes.properties) {\n if (!ts.isJsxAttribute(attr)) continue;\n if (!ts.isIdentifier(attr.name)) continue;\n if (attr.name.text === attributeName) return attr;\n }\n return null;\n};\n\n/**\n * `true` when the element forwards a spread expression such as `{...rest}`,\n * which means we can't be sure which attributes are actually set.\n */\nexport const hasSpreadAttribute = (openingElement: ts.JsxOpeningElement | ts.JsxSelfClosingElement): boolean => {\n return openingElement.attributes.properties.some(prop => ts.isJsxSpreadAttribute(prop));\n};\n\n/**\n * Parses the file as TSX so JSX is recognised. We do not need a full program\n * here; tsquery's `ast` helper produces a script-kind source file which loses\n * JSX context, so we go through `createSourceFile` directly.\n */\nexport const parseTsx = (content: string, fileName = \"file.tsx\"): ts.SourceFile =>\n ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);\n\n/** Re-exported for codemods that need direct AST queries. */\nexport { tsquery };\n\n/**\n * Helper for codemods to log a one-line summary at the end of a run. Migration\n * runners aggregate logs per migration, so this keeps output focused.\n */\nexport const logSummary = (migrationName: string, touched: number, manualReviewNeeded?: number): void => {\n if (touched === 0) {\n logger.info(` ${migrationName}: no files changed`);\n return;\n }\n const reviewSuffix =\n manualReviewNeeded !== undefined && manualReviewNeeded > 0\n ? ` (${manualReviewNeeded} location(s) need manual review)`\n : \"\";\n logger.info(` ${migrationName}: updated ${touched} file(s)${reviewSuffix}`);\n};\n\n/**\n * Inserts an attribute string immediately after the tag name (so the new\n * attribute appears first). Returns the resulting source content.\n *\n * The added attribute is rendered verbatim, so callers are responsible for\n * including the leading space (e.g. ` title=\"Close\"`).\n */\nexport const insertAttributeIntoOpeningTag = (\n content: string,\n openingElement: ts.JsxOpeningElement | ts.JsxSelfClosingElement,\n attributeText: string\n): string => {\n const tagName = openingElement.tagName;\n const insertPos = tagName.getEnd();\n return content.slice(0, insertPos) + ` ${attributeText}` + content.slice(insertPos);\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"actionbutton-add-title.js","sourceRoot":"","sources":["../../../../../../libs/react/form-components/migrations/v2-0-0/actionbutton-add-title.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Tree, logger } from \"@nx/devkit\";\nimport * as ts from \"typescript\";\nimport {\n findJsxAttribute,\n findJsxElements,\n getImportedAliases,\n hasSpreadAttribute,\n logSummary,\n parseTsx,\n visitTsxFiles,\n} from \"../utils/jsx-utils\";\n\nconst PACKAGE_NAME = \"@trackunit/react-form-components\";\nconst COMPONENT_NAME = \"ActionButton\";\n\nconst ACTION_TYPE_TO_TITLE: Record<string, string> = {\n COPY: \"Copy value\",\n EDIT: \"Edit value\",\n EMAIL: \"Send email\",\n PHONE_NUMBER: \"Call number\",\n WEB_ADDRESS: \"Open link\",\n};\n\nconst DEFAULT_TITLE = \"Action\";\n\nconst resolveTitleForType = (typeAttr: ts.JsxAttribute | null): string => {\n if (typeAttr === null) return DEFAULT_TITLE;\n const initializer = typeAttr.initializer;\n if (initializer === undefined) return DEFAULT_TITLE;\n if (ts.isStringLiteral(initializer)) {\n return ACTION_TYPE_TO_TITLE[initializer.text] ?? DEFAULT_TITLE;\n }\n return DEFAULT_TITLE;\n};\n\nconst transformActionButtonUsage = (filePath: string, content: string): string | null => {\n const sourceFile = parseTsx(content, filePath);\n\n const aliases = getImportedAliases(sourceFile, PACKAGE_NAME);\n if (aliases === null) return null;\n\n const localAlias = Object.entries(aliases).find(([, name]) => name === COMPONENT_NAME)?.[0];\n if (localAlias === undefined) return null;\n\n const matches = findJsxElements(sourceFile, [localAlias]);\n if (matches.length === 0) return null;\n\n type Edit = { offset: number; text: string };\n const edits: Array<Edit> = [];\n\n for (const { openingElement } of matches) {\n if (hasSpreadAttribute(openingElement)) continue;\n if (findJsxAttribute(openingElement, \"title\") !== null) continue;\n\n const typeAttr = findJsxAttribute(openingElement, \"type\");\n const title = resolveTitleForType(typeAttr);\n edits.push({\n offset: openingElement.tagName.getEnd(),\n text: ` title=\"${title}\"`,\n });\n }\n\n if (edits.length === 0) return null;\n\n edits.sort((a, b) => (a.offset === b.offset ? 0 : b.offset - a.offset));\n\n let updated = content;\n for (const { offset, text } of edits) {\n updated = updated.slice(0, offset) + text + updated.slice(offset);\n }\n return updated;\n};\n\n/**\n * Adds the now-required `title` prop to `<ActionButton>` usages that don't\n * already provide one. The default value is derived from the `type` prop when\n * possible (e.g. `COPY` → \"Copy value\"); consumers should replace the\n * placeholders with their own localized strings.\n */\nexport const actionButtonAddTitle = (tree: Tree): void => {\n const touched = visitTsxFiles(tree, \"ActionButton\", transformActionButtonUsage);\n logSummary(\"actionbutton-add-title\", touched);\n if (touched > 0) {\n logger.info(` Replace placeholder ActionButton titles with your own localized strings.`);\n }\n};\n\nexport default actionButtonAddTitle;\n"]}
|