@trackunit/react-form-components 1.15.8 → 1.16.0
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 +43 -38
- package/index.esm.js +43 -38
- package/package.json +8 -8
package/index.cjs.js
CHANGED
|
@@ -279,7 +279,7 @@ const cvaInputSuffix = cssClassVarianceUtilities.cvaMerge(["flex", "justify-cent
|
|
|
279
279
|
* Renders the addon element if provided
|
|
280
280
|
*/
|
|
281
281
|
const AddonRenderer = ({ addon, "data-testid": dataTestId, className, fieldSize, position, }) => {
|
|
282
|
-
if (
|
|
282
|
+
if (addon === undefined || addon === null) {
|
|
283
283
|
return null;
|
|
284
284
|
}
|
|
285
285
|
return (jsxRuntime.jsx("div", { className: cvaInputAddon({ size: fieldSize, position, className }), "data-testid": dataTestId ? `${dataTestId}-addon${stringTs.titleCase(position)}` : null, children: addon }));
|
|
@@ -407,8 +407,8 @@ const PrefixRenderer = ({ prefix, type, "data-testid": dataTestId, disabled, ref
|
|
|
407
407
|
url: jsxRuntime.jsx(reactComponents.Icon, { name: "Link", size: "small" }),
|
|
408
408
|
};
|
|
409
409
|
// Decide what to show as prefix
|
|
410
|
-
const resolvedPrefix = prefix
|
|
411
|
-
if (
|
|
410
|
+
const resolvedPrefix = prefix ?? (type !== undefined && type !== "text" ? (defaultPrefixMap[type] ?? null) : null);
|
|
411
|
+
if (resolvedPrefix === null) {
|
|
412
412
|
return null;
|
|
413
413
|
}
|
|
414
414
|
return (jsxRuntime.jsx("div", { className: cvaInputPrefix({ disabled }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: ref, children: resolvedPrefix }));
|
|
@@ -417,7 +417,7 @@ const PrefixRenderer = ({ prefix, type, "data-testid": dataTestId, disabled, ref
|
|
|
417
417
|
// Renders the suffix element or shows an icon if invalid/warning
|
|
418
418
|
const SuffixRenderer = ({ suffix, isInvalid, isWarning, "data-testid": dataTestId, disabled, }) => {
|
|
419
419
|
// If user provided suffix that's not identical to addonBefore, render it
|
|
420
|
-
if (suffix) {
|
|
420
|
+
if (suffix !== undefined && suffix !== null) {
|
|
421
421
|
return (jsxRuntime.jsx("div", { className: cvaInputSuffix({
|
|
422
422
|
disabled,
|
|
423
423
|
}), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix }));
|
|
@@ -2087,7 +2087,7 @@ const FormGroup = ({ isInvalid = false, isWarning = false, helpText, helpAddon,
|
|
|
2087
2087
|
const color = isInvalid ? "danger" : isWarning ? "warning" : null;
|
|
2088
2088
|
return color ? jsxRuntime.jsx(reactComponents.Icon, { color: color, name: "ExclamationTriangle", size: "small" }) : null;
|
|
2089
2089
|
}, [isInvalid, isWarning]);
|
|
2090
|
-
return (jsxRuntime.jsxs("div", { className: cvaFormGroup({ className }), "data-testid": dataTestId, ref: ref, children: [label ? (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 ? (jsxRuntime.jsx("span", { className: "ml-1", children: jsxRuntime.jsx(reactComponents.Tooltip, { "data-testid": dataTestId ? `${dataTestId}-tooltip` : undefined, label: tip, placement: "bottom" }) })) : null] })) : null, children, helpText || helpAddon ? (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 ? (jsxRuntime.jsx("span", { className: cvaHelpAddon(), "data-testid": dataTestId ? `${dataTestId}-helpAddon` : null, children: helpAddon })) : null] })) : null] }));
|
|
2090
|
+
return (jsxRuntime.jsxs("div", { className: cvaFormGroup({ className }), "data-testid": dataTestId, ref: ref, 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", 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] }));
|
|
2091
2091
|
};
|
|
2092
2092
|
|
|
2093
2093
|
/**
|
|
@@ -2147,13 +2147,13 @@ const isNumber = (inputValue) => {
|
|
|
2147
2147
|
* Validates a url
|
|
2148
2148
|
*/
|
|
2149
2149
|
const validateColorCode = (colorCode, required) => {
|
|
2150
|
-
if (
|
|
2150
|
+
if ((colorCode === undefined || colorCode === "" || colorCode === 0) && !required) {
|
|
2151
2151
|
return undefined;
|
|
2152
2152
|
}
|
|
2153
|
-
if (
|
|
2153
|
+
if ((colorCode === undefined || colorCode === "" || colorCode === 0) && required) {
|
|
2154
2154
|
return "REQUIRED";
|
|
2155
2155
|
}
|
|
2156
|
-
if (colorCode && isString(colorCode) && isValidHEXColor(colorCode)) {
|
|
2156
|
+
if (colorCode !== undefined && colorCode !== "" && colorCode !== 0 && isString(colorCode) && isValidHEXColor(colorCode)) {
|
|
2157
2157
|
return undefined;
|
|
2158
2158
|
}
|
|
2159
2159
|
return "INVALID_HEX_CODE";
|
|
@@ -2339,7 +2339,7 @@ ColorField.displayName = "ColorField";
|
|
|
2339
2339
|
const DateField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid, className, defaultValue, "data-testid": dataTestId, ref, ...rest }) => {
|
|
2340
2340
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
2341
2341
|
const htmlForId = id ? id : "dateField-" + sharedUtils.uuidv4();
|
|
2342
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsxRuntime.jsx(DateBaseInput, { "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2342
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(DateBaseInput, { "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2343
2343
|
};
|
|
2344
2344
|
DateField.displayName = "DateField";
|
|
2345
2345
|
|
|
@@ -2533,13 +2533,13 @@ const validateEmailAddress = (email) => {
|
|
|
2533
2533
|
* Validates a email id
|
|
2534
2534
|
*/
|
|
2535
2535
|
const validateEmailId = (emailId, required) => {
|
|
2536
|
-
if (
|
|
2536
|
+
if ((emailId === undefined || emailId === "" || emailId === 0) && !required) {
|
|
2537
2537
|
return undefined;
|
|
2538
2538
|
}
|
|
2539
|
-
if (
|
|
2539
|
+
if ((emailId === undefined || emailId === "" || emailId === 0) && required) {
|
|
2540
2540
|
return "REQUIRED";
|
|
2541
2541
|
}
|
|
2542
|
-
if (emailId && isString(emailId) && validateEmailAddress(emailId)) {
|
|
2542
|
+
if (emailId !== undefined && emailId !== "" && emailId !== 0 && isString(emailId) && validateEmailAddress(emailId)) {
|
|
2543
2543
|
return undefined;
|
|
2544
2544
|
}
|
|
2545
2545
|
return "INVALID_EMAIL";
|
|
@@ -2624,7 +2624,7 @@ const EmailField = ({ label, id, tip, helpText, errorMessage, helpAddon, classNa
|
|
|
2624
2624
|
const [innerValue, setInnerValue] = react.useState(() => {
|
|
2625
2625
|
return (value?.toString() || defaultValue?.toString()) ?? "";
|
|
2626
2626
|
});
|
|
2627
|
-
const [renderAsInvalid, setRenderAsInvalid] = react.useState(!!errorMessage || (value &&
|
|
2627
|
+
const [renderAsInvalid, setRenderAsInvalid] = react.useState(!!errorMessage || (typeof value === "string" && value !== "" && !validateEmailAddress(value)) || isInvalid);
|
|
2628
2628
|
const errorType = react.useMemo(() => validateEmailId(innerValue ?? "", rest.required), [rest.required, innerValue]);
|
|
2629
2629
|
const error = react.useMemo(() => (errorType ? t(`emailField.error.${errorType}`) : errorMessage), [errorType, errorMessage, t]);
|
|
2630
2630
|
const handleBlur = react.useCallback(event => {
|
|
@@ -2639,7 +2639,7 @@ const EmailField = ({ label, id, tip, helpText, errorMessage, helpAddon, classNa
|
|
|
2639
2639
|
onChange(event);
|
|
2640
2640
|
}
|
|
2641
2641
|
}, [onChange]);
|
|
2642
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsxRuntime.jsx(EmailBaseInput, { "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, onChange: handleChange, ref: ref, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2642
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(EmailBaseInput, { "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, onChange: handleChange, ref: ref, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2643
2643
|
};
|
|
2644
2644
|
EmailField.displayName = "EmailField";
|
|
2645
2645
|
|
|
@@ -2810,19 +2810,24 @@ const validateNumber = (number, required = false, min, max) => {
|
|
|
2810
2810
|
return undefined;
|
|
2811
2811
|
}
|
|
2812
2812
|
// if the value is a string eg:'test'
|
|
2813
|
-
if (number && !isNaN(+number) === false) {
|
|
2813
|
+
if (number !== "" && number !== 0 && !isNaN(+number) === false) {
|
|
2814
2814
|
return "INVALID_NUMBER";
|
|
2815
2815
|
}
|
|
2816
2816
|
// if the value is empty and not required
|
|
2817
|
-
if (
|
|
2817
|
+
if ((parsedNumber === 0 || Number.isNaN(parsedNumber)) &&
|
|
2818
|
+
!required &&
|
|
2819
|
+
(min === undefined || min === "" || min === 0) &&
|
|
2820
|
+
(max === undefined || max === "" || max === 0) &&
|
|
2821
|
+
number !== "" &&
|
|
2822
|
+
number !== 0) {
|
|
2818
2823
|
return undefined;
|
|
2819
2824
|
}
|
|
2820
2825
|
// if the value is empty and required
|
|
2821
|
-
if (required &&
|
|
2826
|
+
if (required && (number === "" || number === 0)) {
|
|
2822
2827
|
return "REQUIRED";
|
|
2823
2828
|
}
|
|
2824
2829
|
// if the value is not in between min and max
|
|
2825
|
-
if (minValue && maxValue && isNumberValid(parsedNumber) && !(parsedNumber >= minValue && parsedNumber <= maxValue)) {
|
|
2830
|
+
if (minValue !== undefined && maxValue !== undefined && isNumberValid(parsedNumber) && !(parsedNumber >= minValue && parsedNumber <= maxValue)) {
|
|
2826
2831
|
return "NOT_IN_BETWEEN";
|
|
2827
2832
|
}
|
|
2828
2833
|
// if the value is less than min
|
|
@@ -2933,7 +2938,7 @@ const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInva
|
|
|
2933
2938
|
onChange(event);
|
|
2934
2939
|
}
|
|
2935
2940
|
}, [onChange]);
|
|
2936
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || 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, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2941
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.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, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2937
2942
|
};
|
|
2938
2943
|
NumberField.displayName = "NumberField";
|
|
2939
2944
|
|
|
@@ -3018,10 +3023,10 @@ const cvaTag = cssClassVarianceUtilities.cvaMerge([], {
|
|
|
3018
3023
|
*/
|
|
3019
3024
|
const OptionCard = ({ icon, heading, subheading, description, disabled, id, value, className, contentClassName, "data-testid": dataTestId, customImage, layout = "default", ref, tagProps, ...rest }) => {
|
|
3020
3025
|
const htmlForId = id ?? "option-card-" + sharedUtils.uuidv4();
|
|
3021
|
-
const subContent = react.useMemo(() => (jsxRuntime.jsxs("div", { className: cvaOptionCardContent({ className: contentClassName }), children: [subheading ? (jsxRuntime.jsx(reactComponents.Text, { align: "center", className: cvaOptionCardText({ type: "subheading", disabled }), type: "span", children: subheading })) : null, description ? (jsxRuntime.jsx(reactComponents.Text, { align: "center", className: cvaOptionCardText({ type: "description", disabled }), type: "span", children: description })) : null] })), [subheading, description, contentClassName, disabled]);
|
|
3022
|
-
return (jsxRuntime.jsx(reactComponents.Tooltip, { disabled: layout !== "compact" || (
|
|
3026
|
+
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]);
|
|
3027
|
+
return (jsxRuntime.jsx(reactComponents.Tooltip, { disabled: layout !== "compact" || ((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
|
|
3023
3028
|
? react.cloneElement(icon, { className: cvaCustomImage({ disabled, className: icon.props.className }) })
|
|
3024
|
-
: 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" && (subheading || description) ? subContent : null, tagProps ? jsxRuntime.jsx(reactComponents.Tag, { className: cvaTag({ className: tagProps.className, layout }), ...tagProps }) : null] })] }) }));
|
|
3029
|
+
: 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" && ((subheading !== undefined && subheading !== null) || (description !== undefined && description !== null)) ? subContent : null, tagProps ? jsxRuntime.jsx(reactComponents.Tag, { className: cvaTag({ className: tagProps.className, layout }), ...tagProps }) : null] })] }) }));
|
|
3025
3030
|
};
|
|
3026
3031
|
OptionCard.displayName = "OptionCard";
|
|
3027
3032
|
|
|
@@ -3097,7 +3102,7 @@ const PasswordField = ({ id, label, tip, helpText, helpAddon, errorMessage, isIn
|
|
|
3097
3102
|
const handleChange = react.useCallback((event) => {
|
|
3098
3103
|
onChange?.(event);
|
|
3099
3104
|
}, [onChange]);
|
|
3100
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || 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, value: value }) }));
|
|
3105
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, required: rest.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, value: value }) }));
|
|
3101
3106
|
};
|
|
3102
3107
|
PasswordField.displayName = "PasswordField";
|
|
3103
3108
|
|
|
@@ -3233,7 +3238,7 @@ const PhoneField = ({ label, id, tip, helpText, isInvalid, errorMessage, value,
|
|
|
3233
3238
|
}
|
|
3234
3239
|
onBlur?.(event);
|
|
3235
3240
|
}, [errorMessage, onBlur, rest.required]);
|
|
3236
|
-
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: rest.required ? !(rest.disabled || 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, value: value, ...rest }) }));
|
|
3241
|
+
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: rest.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, value: value, ...rest }) }));
|
|
3237
3242
|
};
|
|
3238
3243
|
PhoneField.displayName = "PhoneField";
|
|
3239
3244
|
|
|
@@ -3653,7 +3658,7 @@ const parseSchedule = (scheduleString) => {
|
|
|
3653
3658
|
const serializeSchedule = (weekSchedule) => {
|
|
3654
3659
|
return weekSchedule.schedule
|
|
3655
3660
|
.filter(({ range, day, isAllDay }) => {
|
|
3656
|
-
const hasRange = range.timeFrom && range.timeTo;
|
|
3661
|
+
const hasRange = Boolean(range.timeFrom) && Boolean(range.timeTo);
|
|
3657
3662
|
switch (weekSchedule.variant) {
|
|
3658
3663
|
case exports.ScheduleVariant.WEEKDAYS:
|
|
3659
3664
|
return day <= 5 && hasRange;
|
|
@@ -3989,7 +3994,7 @@ const TextLengthIndicator = ({ length, maxLength }) => {
|
|
|
3989
3994
|
* @returns {ReactElement} TextAreaField component
|
|
3990
3995
|
*/
|
|
3991
3996
|
const TextAreaField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, "data-testid": dataTestId, ref, ...rest }) => {
|
|
3992
|
-
const [valueLength, setValueLength] = react.useState(value ? `${value}`.length : 0);
|
|
3997
|
+
const [valueLength, setValueLength] = react.useState(value !== undefined ? `${value}`.length : 0);
|
|
3993
3998
|
const renderAsInvalid = isInvalid || Boolean(errorMessage);
|
|
3994
3999
|
const htmlForId = id ? id : "textAreaField-" + sharedUtils.uuidv4();
|
|
3995
4000
|
const handleChange = react.useCallback((event) => {
|
|
@@ -3998,7 +4003,7 @@ const TextAreaField = ({ id, label, tip, helpText, helpAddon, errorMessage, isIn
|
|
|
3998
4003
|
onChange(event);
|
|
3999
4004
|
}
|
|
4000
4005
|
}, [onChange]);
|
|
4001
|
-
return (jsxRuntime.jsx(FormGroup, { className: tailwindMerge.twMerge(className, "grid", "grid-rows-[auto_1fr_auto]"), "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon
|
|
4006
|
+
return (jsxRuntime.jsx(FormGroup, { className: tailwindMerge.twMerge(className, "grid", "grid-rows-[auto_1fr_auto]"), "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon ??
|
|
4002
4007
|
(typeof maxLength === "number" && jsxRuntime.jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsxRuntime.jsx(TextAreaBaseInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, ref: ref, value: value, ...rest, className: "h-auto", "data-testid": dataTestId, onChange: handleChange }) }));
|
|
4003
4008
|
};
|
|
4004
4009
|
TextAreaField.displayName = "TextAreaField";
|
|
@@ -4062,7 +4067,7 @@ TextAreaField.displayName = "TextAreaField";
|
|
|
4062
4067
|
* ```
|
|
4063
4068
|
*/
|
|
4064
4069
|
const TextField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, "data-testid": dataTestId, isWarning, ref, ...rest }) => {
|
|
4065
|
-
const [valueLength, setValueLength] = react.useState(value ? `${value}`.length : 0);
|
|
4070
|
+
const [valueLength, setValueLength] = react.useState(value !== undefined ? `${value}`.length : 0);
|
|
4066
4071
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
4067
4072
|
const htmlFor = id ? id : "textField-" + sharedUtils.uuidv4();
|
|
4068
4073
|
const handleChange = react.useCallback((event) => {
|
|
@@ -4071,8 +4076,8 @@ const TextField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvali
|
|
|
4071
4076
|
onChange(event);
|
|
4072
4077
|
}
|
|
4073
4078
|
}, [onChange]);
|
|
4074
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon
|
|
4075
|
-
(typeof maxLength === "number" && jsxRuntime.jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsxRuntime.jsx(TextBaseInput, { "aria-labelledby": htmlFor + "-label", id: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, maxLength: maxLength, ref: ref, value: value, ...rest, className: className, "data-testid": dataTestId, onChange: handleChange }) }));
|
|
4079
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon ??
|
|
4080
|
+
(typeof maxLength === "number" && jsxRuntime.jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, label: label, required: rest.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, value: value, ...rest, className: className, "data-testid": dataTestId, onChange: handleChange }) }));
|
|
4076
4081
|
};
|
|
4077
4082
|
TextField.displayName = "TextField";
|
|
4078
4083
|
|
|
@@ -4260,7 +4265,7 @@ const ToggleSwitch = ({ onChange, onClick, preventDefaultOnClick, className, "da
|
|
|
4260
4265
|
}, {}), [rest]);
|
|
4261
4266
|
const handleWrapperClick = (e) => {
|
|
4262
4267
|
// Prevents double-toggling when wrapped in a label or if preventDefaultOnClick is true
|
|
4263
|
-
const isFromLabel = e.target instanceof Element
|
|
4268
|
+
const isFromLabel = e.target instanceof Element ? e.target.closest("label") : null;
|
|
4264
4269
|
if (!isFromLabel && !preventDefaultOnClick && !disabled && !readOnly) {
|
|
4265
4270
|
localInputRef.current?.click();
|
|
4266
4271
|
}
|
|
@@ -4360,7 +4365,7 @@ const ToggleSwitchOption = ({ label, className, description, suffix, id, "data-t
|
|
|
4360
4365
|
return (jsxRuntime.jsxs("label", { className: cvaBinaryControlWrapper({ className }), "data-testid": dataTestId, htmlFor: `${id}-toggle-switch`, ref: ref, tabIndex: -1, children: [jsxRuntime.jsx(ToggleSwitch, { "data-testid": `${dataTestId}-switcher`, id: `${id}-toggle-switch`, ...rest }), jsxRuntime.jsx(reactComponents.Tooltip, { "data-testid": `${dataTestId}-label-tooltip`, disabled: !isLabelTruncated, label: label, placement: "top", children: jsxRuntime.jsx("div", { className: cvaBinaryControlLabelTooltip(), children: jsxRuntime.jsx("span", { className: cvaLabel({
|
|
4361
4366
|
disabled: rest.disabled || rest.readOnly,
|
|
4362
4367
|
className: "select-none",
|
|
4363
|
-
}), "data-testid": `${dataTestId}-label`, ref: labelRef, children: label }) }) }, `${id}-label-tooltip`), suffix ? (jsxRuntime.jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": `${dataTestId}-suffix-container`, children: suffix })) : null, description ? (jsxRuntime.jsx(reactComponents.Tooltip, { "data-testid": `${dataTestId}-description-tooltip`, disabled: !isDescriptionTruncated, label: description, placement: "top", children: jsxRuntime.jsx("div", { className: cvaBinaryControlDescriptionTooltip(), children: jsxRuntime.jsx("span", { className: cvaBinaryControlDescription({ disabled: rest.disabled || rest.readOnly }), "data-testid": `${dataTestId}-description`, id: `${id}-description`, ref: descriptionRef, children: description }) }) }, `${id}-description-tooltip`)) : null] }));
|
|
4368
|
+
}), "data-testid": `${dataTestId}-label`, ref: labelRef, children: label }) }) }, `${id}-label-tooltip`), suffix ? (jsxRuntime.jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": `${dataTestId}-suffix-container`, children: suffix })) : null, description !== undefined ? (jsxRuntime.jsx(reactComponents.Tooltip, { "data-testid": `${dataTestId}-description-tooltip`, disabled: !isDescriptionTruncated, label: description, placement: "top", children: jsxRuntime.jsx("div", { className: cvaBinaryControlDescriptionTooltip(), children: jsxRuntime.jsx("span", { className: cvaBinaryControlDescription({ disabled: rest.disabled || rest.readOnly }), "data-testid": `${dataTestId}-description`, id: `${id}-description`, ref: descriptionRef, children: description }) }) }, `${id}-description-tooltip`)) : null] }));
|
|
4364
4369
|
};
|
|
4365
4370
|
ToggleSwitchOption.displayName = "ToggleSwitchOption";
|
|
4366
4371
|
|
|
@@ -4462,7 +4467,7 @@ UploadInput.displayName = "UploadInput";
|
|
|
4462
4467
|
const UploadField = ({ label, id, tip, helpText, errorMessage, isInvalid, className, value, "data-testid": dataTestId, ref, ...rest }) => {
|
|
4463
4468
|
const renderAsInvalid = isInvalid || Boolean(errorMessage);
|
|
4464
4469
|
const htmlForId = id ? id : "uploadField-" + sharedUtils.uuidv4();
|
|
4465
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": `${dataTestId}-FormGroup`, helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsxRuntime.jsx(UploadInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, ref: ref, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
4470
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": `${dataTestId}-FormGroup`, helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(UploadInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, ref: ref, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
4466
4471
|
};
|
|
4467
4472
|
UploadField.displayName = "UploadField";
|
|
4468
4473
|
|
|
@@ -4485,13 +4490,13 @@ const validateUrlAddress = (url) => {
|
|
|
4485
4490
|
* Validates a url
|
|
4486
4491
|
*/
|
|
4487
4492
|
const validateUrl = (url, required) => {
|
|
4488
|
-
if (
|
|
4493
|
+
if ((url === undefined || url === "" || url === 0) && !required) {
|
|
4489
4494
|
return undefined;
|
|
4490
4495
|
}
|
|
4491
|
-
if (
|
|
4496
|
+
if ((url === undefined || url === "" || url === 0) && required) {
|
|
4492
4497
|
return "REQUIRED";
|
|
4493
4498
|
}
|
|
4494
|
-
if (url && isString(url) && validateUrlAddress(url)) {
|
|
4499
|
+
if (url !== undefined && url !== "" && url !== 0 && isString(url) && validateUrlAddress(url)) {
|
|
4495
4500
|
return undefined;
|
|
4496
4501
|
}
|
|
4497
4502
|
return "INVALID_URL";
|
|
@@ -4563,7 +4568,7 @@ const UrlField = ({ label, id, tip, helpText, errorMessage, helpAddon, className
|
|
|
4563
4568
|
const [innerValue, setInnerValue] = react.useState(() => {
|
|
4564
4569
|
return (value?.toString() || defaultValue?.toString()) ?? "";
|
|
4565
4570
|
});
|
|
4566
|
-
const [renderAsInvalid, setRenderAsInvalid] = react.useState(!!errorMessage || (value &&
|
|
4571
|
+
const [renderAsInvalid, setRenderAsInvalid] = react.useState(!!errorMessage || (typeof value === "string" && value !== "" && !validateUrlAddress(value)) || isInvalid);
|
|
4567
4572
|
const errorType = react.useMemo(() => validateUrl(innerValue ?? "", rest.required), [rest.required, innerValue]);
|
|
4568
4573
|
const error = react.useMemo(() => (errorType ? t(`urlField.error.${errorType}`) : errorMessage), [errorType, errorMessage, t]);
|
|
4569
4574
|
const handleBlur = react.useCallback(event => {
|
|
@@ -4572,7 +4577,7 @@ const UrlField = ({ label, id, tip, helpText, errorMessage, helpAddon, className
|
|
|
4572
4577
|
setRenderAsInvalid(!!validateUrl(newValue, rest.required));
|
|
4573
4578
|
onBlur?.(event);
|
|
4574
4579
|
}, [onBlur, rest.required]);
|
|
4575
|
-
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? error : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsxRuntime.jsx(UrlBaseInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, ref: ref, value: value
|
|
4580
|
+
return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? error : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(UrlBaseInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, ref: ref, value: value ?? defaultValue, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
4576
4581
|
};
|
|
4577
4582
|
UrlField.displayName = "UrlField";
|
|
4578
4583
|
|
package/index.esm.js
CHANGED
|
@@ -278,7 +278,7 @@ const cvaInputSuffix = cvaMerge(["flex", "justify-center", "items-center", "text
|
|
|
278
278
|
* Renders the addon element if provided
|
|
279
279
|
*/
|
|
280
280
|
const AddonRenderer = ({ addon, "data-testid": dataTestId, className, fieldSize, position, }) => {
|
|
281
|
-
if (
|
|
281
|
+
if (addon === undefined || addon === null) {
|
|
282
282
|
return null;
|
|
283
283
|
}
|
|
284
284
|
return (jsx("div", { className: cvaInputAddon({ size: fieldSize, position, className }), "data-testid": dataTestId ? `${dataTestId}-addon${titleCase(position)}` : null, children: addon }));
|
|
@@ -406,8 +406,8 @@ const PrefixRenderer = ({ prefix, type, "data-testid": dataTestId, disabled, ref
|
|
|
406
406
|
url: jsx(Icon, { name: "Link", size: "small" }),
|
|
407
407
|
};
|
|
408
408
|
// Decide what to show as prefix
|
|
409
|
-
const resolvedPrefix = prefix
|
|
410
|
-
if (
|
|
409
|
+
const resolvedPrefix = prefix ?? (type !== undefined && type !== "text" ? (defaultPrefixMap[type] ?? null) : null);
|
|
410
|
+
if (resolvedPrefix === null) {
|
|
411
411
|
return null;
|
|
412
412
|
}
|
|
413
413
|
return (jsx("div", { className: cvaInputPrefix({ disabled }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: ref, children: resolvedPrefix }));
|
|
@@ -416,7 +416,7 @@ const PrefixRenderer = ({ prefix, type, "data-testid": dataTestId, disabled, ref
|
|
|
416
416
|
// Renders the suffix element or shows an icon if invalid/warning
|
|
417
417
|
const SuffixRenderer = ({ suffix, isInvalid, isWarning, "data-testid": dataTestId, disabled, }) => {
|
|
418
418
|
// If user provided suffix that's not identical to addonBefore, render it
|
|
419
|
-
if (suffix) {
|
|
419
|
+
if (suffix !== undefined && suffix !== null) {
|
|
420
420
|
return (jsx("div", { className: cvaInputSuffix({
|
|
421
421
|
disabled,
|
|
422
422
|
}), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix }));
|
|
@@ -2086,7 +2086,7 @@ const FormGroup = ({ isInvalid = false, isWarning = false, helpText, helpAddon,
|
|
|
2086
2086
|
const color = isInvalid ? "danger" : isWarning ? "warning" : null;
|
|
2087
2087
|
return color ? jsx(Icon, { color: color, name: "ExclamationTriangle", size: "small" }) : null;
|
|
2088
2088
|
}, [isInvalid, isWarning]);
|
|
2089
|
-
return (jsxs("div", { className: cvaFormGroup({ className }), "data-testid": dataTestId, ref: ref, children: [label ? (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 ? (jsx("span", { className: "ml-1", children: jsx(Tooltip, { "data-testid": dataTestId ? `${dataTestId}-tooltip` : undefined, label: tip, placement: "bottom" }) })) : null] })) : null, children, helpText || helpAddon ? (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 ? (jsx("span", { className: cvaHelpAddon(), "data-testid": dataTestId ? `${dataTestId}-helpAddon` : null, children: helpAddon })) : null] })) : null] }));
|
|
2089
|
+
return (jsxs("div", { className: cvaFormGroup({ className }), "data-testid": dataTestId, ref: ref, 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", 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] }));
|
|
2090
2090
|
};
|
|
2091
2091
|
|
|
2092
2092
|
/**
|
|
@@ -2146,13 +2146,13 @@ const isNumber = (inputValue) => {
|
|
|
2146
2146
|
* Validates a url
|
|
2147
2147
|
*/
|
|
2148
2148
|
const validateColorCode = (colorCode, required) => {
|
|
2149
|
-
if (
|
|
2149
|
+
if ((colorCode === undefined || colorCode === "" || colorCode === 0) && !required) {
|
|
2150
2150
|
return undefined;
|
|
2151
2151
|
}
|
|
2152
|
-
if (
|
|
2152
|
+
if ((colorCode === undefined || colorCode === "" || colorCode === 0) && required) {
|
|
2153
2153
|
return "REQUIRED";
|
|
2154
2154
|
}
|
|
2155
|
-
if (colorCode && isString(colorCode) && isValidHEXColor(colorCode)) {
|
|
2155
|
+
if (colorCode !== undefined && colorCode !== "" && colorCode !== 0 && isString(colorCode) && isValidHEXColor(colorCode)) {
|
|
2156
2156
|
return undefined;
|
|
2157
2157
|
}
|
|
2158
2158
|
return "INVALID_HEX_CODE";
|
|
@@ -2338,7 +2338,7 @@ ColorField.displayName = "ColorField";
|
|
|
2338
2338
|
const DateField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid, className, defaultValue, "data-testid": dataTestId, ref, ...rest }) => {
|
|
2339
2339
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
2340
2340
|
const htmlForId = id ? id : "dateField-" + uuidv4();
|
|
2341
|
-
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsx(DateBaseInput, { "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2341
|
+
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(DateBaseInput, { "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2342
2342
|
};
|
|
2343
2343
|
DateField.displayName = "DateField";
|
|
2344
2344
|
|
|
@@ -2532,13 +2532,13 @@ const validateEmailAddress = (email) => {
|
|
|
2532
2532
|
* Validates a email id
|
|
2533
2533
|
*/
|
|
2534
2534
|
const validateEmailId = (emailId, required) => {
|
|
2535
|
-
if (
|
|
2535
|
+
if ((emailId === undefined || emailId === "" || emailId === 0) && !required) {
|
|
2536
2536
|
return undefined;
|
|
2537
2537
|
}
|
|
2538
|
-
if (
|
|
2538
|
+
if ((emailId === undefined || emailId === "" || emailId === 0) && required) {
|
|
2539
2539
|
return "REQUIRED";
|
|
2540
2540
|
}
|
|
2541
|
-
if (emailId && isString(emailId) && validateEmailAddress(emailId)) {
|
|
2541
|
+
if (emailId !== undefined && emailId !== "" && emailId !== 0 && isString(emailId) && validateEmailAddress(emailId)) {
|
|
2542
2542
|
return undefined;
|
|
2543
2543
|
}
|
|
2544
2544
|
return "INVALID_EMAIL";
|
|
@@ -2623,7 +2623,7 @@ const EmailField = ({ label, id, tip, helpText, errorMessage, helpAddon, classNa
|
|
|
2623
2623
|
const [innerValue, setInnerValue] = useState(() => {
|
|
2624
2624
|
return (value?.toString() || defaultValue?.toString()) ?? "";
|
|
2625
2625
|
});
|
|
2626
|
-
const [renderAsInvalid, setRenderAsInvalid] = useState(!!errorMessage || (value &&
|
|
2626
|
+
const [renderAsInvalid, setRenderAsInvalid] = useState(!!errorMessage || (typeof value === "string" && value !== "" && !validateEmailAddress(value)) || isInvalid);
|
|
2627
2627
|
const errorType = useMemo(() => validateEmailId(innerValue ?? "", rest.required), [rest.required, innerValue]);
|
|
2628
2628
|
const error = useMemo(() => (errorType ? t(`emailField.error.${errorType}`) : errorMessage), [errorType, errorMessage, t]);
|
|
2629
2629
|
const handleBlur = useCallback(event => {
|
|
@@ -2638,7 +2638,7 @@ const EmailField = ({ label, id, tip, helpText, errorMessage, helpAddon, classNa
|
|
|
2638
2638
|
onChange(event);
|
|
2639
2639
|
}
|
|
2640
2640
|
}, [onChange]);
|
|
2641
|
-
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsx(EmailBaseInput, { "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, onChange: handleChange, ref: ref, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2641
|
+
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(EmailBaseInput, { "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, onChange: handleChange, ref: ref, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2642
2642
|
};
|
|
2643
2643
|
EmailField.displayName = "EmailField";
|
|
2644
2644
|
|
|
@@ -2809,19 +2809,24 @@ const validateNumber = (number, required = false, min, max) => {
|
|
|
2809
2809
|
return undefined;
|
|
2810
2810
|
}
|
|
2811
2811
|
// if the value is a string eg:'test'
|
|
2812
|
-
if (number && !isNaN(+number) === false) {
|
|
2812
|
+
if (number !== "" && number !== 0 && !isNaN(+number) === false) {
|
|
2813
2813
|
return "INVALID_NUMBER";
|
|
2814
2814
|
}
|
|
2815
2815
|
// if the value is empty and not required
|
|
2816
|
-
if (
|
|
2816
|
+
if ((parsedNumber === 0 || Number.isNaN(parsedNumber)) &&
|
|
2817
|
+
!required &&
|
|
2818
|
+
(min === undefined || min === "" || min === 0) &&
|
|
2819
|
+
(max === undefined || max === "" || max === 0) &&
|
|
2820
|
+
number !== "" &&
|
|
2821
|
+
number !== 0) {
|
|
2817
2822
|
return undefined;
|
|
2818
2823
|
}
|
|
2819
2824
|
// if the value is empty and required
|
|
2820
|
-
if (required &&
|
|
2825
|
+
if (required && (number === "" || number === 0)) {
|
|
2821
2826
|
return "REQUIRED";
|
|
2822
2827
|
}
|
|
2823
2828
|
// if the value is not in between min and max
|
|
2824
|
-
if (minValue && maxValue && isNumberValid(parsedNumber) && !(parsedNumber >= minValue && parsedNumber <= maxValue)) {
|
|
2829
|
+
if (minValue !== undefined && maxValue !== undefined && isNumberValid(parsedNumber) && !(parsedNumber >= minValue && parsedNumber <= maxValue)) {
|
|
2825
2830
|
return "NOT_IN_BETWEEN";
|
|
2826
2831
|
}
|
|
2827
2832
|
// if the value is less than min
|
|
@@ -2932,7 +2937,7 @@ const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInva
|
|
|
2932
2937
|
onChange(event);
|
|
2933
2938
|
}
|
|
2934
2939
|
}, [onChange]);
|
|
2935
|
-
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsx(NumberBaseInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, onBlur: handleBlur, onChange: handleChange, ref: ref, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2940
|
+
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.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, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
2936
2941
|
};
|
|
2937
2942
|
NumberField.displayName = "NumberField";
|
|
2938
2943
|
|
|
@@ -3017,10 +3022,10 @@ const cvaTag = cvaMerge([], {
|
|
|
3017
3022
|
*/
|
|
3018
3023
|
const OptionCard = ({ icon, heading, subheading, description, disabled, id, value, className, contentClassName, "data-testid": dataTestId, customImage, layout = "default", ref, tagProps, ...rest }) => {
|
|
3019
3024
|
const htmlForId = id ?? "option-card-" + uuidv4();
|
|
3020
|
-
const subContent = useMemo(() => (jsxs("div", { className: cvaOptionCardContent({ className: contentClassName }), children: [subheading ? (jsx(Text, { align: "center", className: cvaOptionCardText({ type: "subheading", disabled }), type: "span", children: subheading })) : null, description ? (jsx(Text, { align: "center", className: cvaOptionCardText({ type: "description", disabled }), type: "span", children: description })) : null] })), [subheading, description, contentClassName, disabled]);
|
|
3021
|
-
return (jsx(Tooltip, { disabled: layout !== "compact" || (
|
|
3025
|
+
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]);
|
|
3026
|
+
return (jsx(Tooltip, { disabled: layout !== "compact" || ((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
|
|
3022
3027
|
? cloneElement(icon, { className: cvaCustomImage({ disabled, className: icon.props.className }) })
|
|
3023
|
-
: 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" && (subheading || description) ? subContent : null, tagProps ? jsx(Tag, { className: cvaTag({ className: tagProps.className, layout }), ...tagProps }) : null] })] }) }));
|
|
3028
|
+
: 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" && ((subheading !== undefined && subheading !== null) || (description !== undefined && description !== null)) ? subContent : null, tagProps ? jsx(Tag, { className: cvaTag({ className: tagProps.className, layout }), ...tagProps }) : null] })] }) }));
|
|
3024
3029
|
};
|
|
3025
3030
|
OptionCard.displayName = "OptionCard";
|
|
3026
3031
|
|
|
@@ -3096,7 +3101,7 @@ const PasswordField = ({ id, label, tip, helpText, helpAddon, errorMessage, isIn
|
|
|
3096
3101
|
const handleChange = useCallback((event) => {
|
|
3097
3102
|
onChange?.(event);
|
|
3098
3103
|
}, [onChange]);
|
|
3099
|
-
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || 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, value: value }) }));
|
|
3104
|
+
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, required: rest.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, value: value }) }));
|
|
3100
3105
|
};
|
|
3101
3106
|
PasswordField.displayName = "PasswordField";
|
|
3102
3107
|
|
|
@@ -3232,7 +3237,7 @@ const PhoneField = ({ label, id, tip, helpText, isInvalid, errorMessage, value,
|
|
|
3232
3237
|
}
|
|
3233
3238
|
onBlur?.(event);
|
|
3234
3239
|
}, [errorMessage, onBlur, rest.required]);
|
|
3235
|
-
return (jsx(FormGroup, { className: className, "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || 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, value: value, ...rest }) }));
|
|
3240
|
+
return (jsx(FormGroup, { className: className, "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.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, value: value, ...rest }) }));
|
|
3236
3241
|
};
|
|
3237
3242
|
PhoneField.displayName = "PhoneField";
|
|
3238
3243
|
|
|
@@ -3652,7 +3657,7 @@ const parseSchedule = (scheduleString) => {
|
|
|
3652
3657
|
const serializeSchedule = (weekSchedule) => {
|
|
3653
3658
|
return weekSchedule.schedule
|
|
3654
3659
|
.filter(({ range, day, isAllDay }) => {
|
|
3655
|
-
const hasRange = range.timeFrom && range.timeTo;
|
|
3660
|
+
const hasRange = Boolean(range.timeFrom) && Boolean(range.timeTo);
|
|
3656
3661
|
switch (weekSchedule.variant) {
|
|
3657
3662
|
case ScheduleVariant.WEEKDAYS:
|
|
3658
3663
|
return day <= 5 && hasRange;
|
|
@@ -3988,7 +3993,7 @@ const TextLengthIndicator = ({ length, maxLength }) => {
|
|
|
3988
3993
|
* @returns {ReactElement} TextAreaField component
|
|
3989
3994
|
*/
|
|
3990
3995
|
const TextAreaField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, "data-testid": dataTestId, ref, ...rest }) => {
|
|
3991
|
-
const [valueLength, setValueLength] = useState(value ? `${value}`.length : 0);
|
|
3996
|
+
const [valueLength, setValueLength] = useState(value !== undefined ? `${value}`.length : 0);
|
|
3992
3997
|
const renderAsInvalid = isInvalid || Boolean(errorMessage);
|
|
3993
3998
|
const htmlForId = id ? id : "textAreaField-" + uuidv4();
|
|
3994
3999
|
const handleChange = useCallback((event) => {
|
|
@@ -3997,7 +4002,7 @@ const TextAreaField = ({ id, label, tip, helpText, helpAddon, errorMessage, isIn
|
|
|
3997
4002
|
onChange(event);
|
|
3998
4003
|
}
|
|
3999
4004
|
}, [onChange]);
|
|
4000
|
-
return (jsx(FormGroup, { className: twMerge(className, "grid", "grid-rows-[auto_1fr_auto]"), "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon
|
|
4005
|
+
return (jsx(FormGroup, { className: twMerge(className, "grid", "grid-rows-[auto_1fr_auto]"), "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon ??
|
|
4001
4006
|
(typeof maxLength === "number" && jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsx(TextAreaBaseInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, ref: ref, value: value, ...rest, className: "h-auto", "data-testid": dataTestId, onChange: handleChange }) }));
|
|
4002
4007
|
};
|
|
4003
4008
|
TextAreaField.displayName = "TextAreaField";
|
|
@@ -4061,7 +4066,7 @@ TextAreaField.displayName = "TextAreaField";
|
|
|
4061
4066
|
* ```
|
|
4062
4067
|
*/
|
|
4063
4068
|
const TextField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, "data-testid": dataTestId, isWarning, ref, ...rest }) => {
|
|
4064
|
-
const [valueLength, setValueLength] = useState(value ? `${value}`.length : 0);
|
|
4069
|
+
const [valueLength, setValueLength] = useState(value !== undefined ? `${value}`.length : 0);
|
|
4065
4070
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
4066
4071
|
const htmlFor = id ? id : "textField-" + uuidv4();
|
|
4067
4072
|
const handleChange = useCallback((event) => {
|
|
@@ -4070,8 +4075,8 @@ const TextField = ({ id, label, tip, helpText, helpAddon, errorMessage, isInvali
|
|
|
4070
4075
|
onChange(event);
|
|
4071
4076
|
}
|
|
4072
4077
|
}, [onChange]);
|
|
4073
|
-
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon
|
|
4074
|
-
(typeof maxLength === "number" && jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsx(TextBaseInput, { "aria-labelledby": htmlFor + "-label", id: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, maxLength: maxLength, ref: ref, value: value, ...rest, className: className, "data-testid": dataTestId, onChange: handleChange }) }));
|
|
4078
|
+
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon ??
|
|
4079
|
+
(typeof maxLength === "number" && jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, label: label, required: rest.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, value: value, ...rest, className: className, "data-testid": dataTestId, onChange: handleChange }) }));
|
|
4075
4080
|
};
|
|
4076
4081
|
TextField.displayName = "TextField";
|
|
4077
4082
|
|
|
@@ -4259,7 +4264,7 @@ const ToggleSwitch = ({ onChange, onClick, preventDefaultOnClick, className, "da
|
|
|
4259
4264
|
}, {}), [rest]);
|
|
4260
4265
|
const handleWrapperClick = (e) => {
|
|
4261
4266
|
// Prevents double-toggling when wrapped in a label or if preventDefaultOnClick is true
|
|
4262
|
-
const isFromLabel = e.target instanceof Element
|
|
4267
|
+
const isFromLabel = e.target instanceof Element ? e.target.closest("label") : null;
|
|
4263
4268
|
if (!isFromLabel && !preventDefaultOnClick && !disabled && !readOnly) {
|
|
4264
4269
|
localInputRef.current?.click();
|
|
4265
4270
|
}
|
|
@@ -4359,7 +4364,7 @@ const ToggleSwitchOption = ({ label, className, description, suffix, id, "data-t
|
|
|
4359
4364
|
return (jsxs("label", { className: cvaBinaryControlWrapper({ className }), "data-testid": dataTestId, htmlFor: `${id}-toggle-switch`, ref: ref, tabIndex: -1, children: [jsx(ToggleSwitch, { "data-testid": `${dataTestId}-switcher`, id: `${id}-toggle-switch`, ...rest }), jsx(Tooltip, { "data-testid": `${dataTestId}-label-tooltip`, disabled: !isLabelTruncated, label: label, placement: "top", children: jsx("div", { className: cvaBinaryControlLabelTooltip(), children: jsx("span", { className: cvaLabel({
|
|
4360
4365
|
disabled: rest.disabled || rest.readOnly,
|
|
4361
4366
|
className: "select-none",
|
|
4362
|
-
}), "data-testid": `${dataTestId}-label`, ref: labelRef, children: label }) }) }, `${id}-label-tooltip`), suffix ? (jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": `${dataTestId}-suffix-container`, children: suffix })) : null, description ? (jsx(Tooltip, { "data-testid": `${dataTestId}-description-tooltip`, disabled: !isDescriptionTruncated, label: description, placement: "top", children: jsx("div", { className: cvaBinaryControlDescriptionTooltip(), children: jsx("span", { className: cvaBinaryControlDescription({ disabled: rest.disabled || rest.readOnly }), "data-testid": `${dataTestId}-description`, id: `${id}-description`, ref: descriptionRef, children: description }) }) }, `${id}-description-tooltip`)) : null] }));
|
|
4367
|
+
}), "data-testid": `${dataTestId}-label`, ref: labelRef, children: label }) }) }, `${id}-label-tooltip`), suffix ? (jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": `${dataTestId}-suffix-container`, children: suffix })) : null, description !== undefined ? (jsx(Tooltip, { "data-testid": `${dataTestId}-description-tooltip`, disabled: !isDescriptionTruncated, label: description, placement: "top", children: jsx("div", { className: cvaBinaryControlDescriptionTooltip(), children: jsx("span", { className: cvaBinaryControlDescription({ disabled: rest.disabled || rest.readOnly }), "data-testid": `${dataTestId}-description`, id: `${id}-description`, ref: descriptionRef, children: description }) }) }, `${id}-description-tooltip`)) : null] }));
|
|
4363
4368
|
};
|
|
4364
4369
|
ToggleSwitchOption.displayName = "ToggleSwitchOption";
|
|
4365
4370
|
|
|
@@ -4461,7 +4466,7 @@ UploadInput.displayName = "UploadInput";
|
|
|
4461
4466
|
const UploadField = ({ label, id, tip, helpText, errorMessage, isInvalid, className, value, "data-testid": dataTestId, ref, ...rest }) => {
|
|
4462
4467
|
const renderAsInvalid = isInvalid || Boolean(errorMessage);
|
|
4463
4468
|
const htmlForId = id ? id : "uploadField-" + uuidv4();
|
|
4464
|
-
return (jsx(FormGroup, { "data-testid": `${dataTestId}-FormGroup`, helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsx(UploadInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, ref: ref, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
4469
|
+
return (jsx(FormGroup, { "data-testid": `${dataTestId}-FormGroup`, helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(UploadInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, ref: ref, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
4465
4470
|
};
|
|
4466
4471
|
UploadField.displayName = "UploadField";
|
|
4467
4472
|
|
|
@@ -4484,13 +4489,13 @@ const validateUrlAddress = (url) => {
|
|
|
4484
4489
|
* Validates a url
|
|
4485
4490
|
*/
|
|
4486
4491
|
const validateUrl = (url, required) => {
|
|
4487
|
-
if (
|
|
4492
|
+
if ((url === undefined || url === "" || url === 0) && !required) {
|
|
4488
4493
|
return undefined;
|
|
4489
4494
|
}
|
|
4490
|
-
if (
|
|
4495
|
+
if ((url === undefined || url === "" || url === 0) && required) {
|
|
4491
4496
|
return "REQUIRED";
|
|
4492
4497
|
}
|
|
4493
|
-
if (url && isString(url) && validateUrlAddress(url)) {
|
|
4498
|
+
if (url !== undefined && url !== "" && url !== 0 && isString(url) && validateUrlAddress(url)) {
|
|
4494
4499
|
return undefined;
|
|
4495
4500
|
}
|
|
4496
4501
|
return "INVALID_URL";
|
|
@@ -4562,7 +4567,7 @@ const UrlField = ({ label, id, tip, helpText, errorMessage, helpAddon, className
|
|
|
4562
4567
|
const [innerValue, setInnerValue] = useState(() => {
|
|
4563
4568
|
return (value?.toString() || defaultValue?.toString()) ?? "";
|
|
4564
4569
|
});
|
|
4565
|
-
const [renderAsInvalid, setRenderAsInvalid] = useState(!!errorMessage || (value &&
|
|
4570
|
+
const [renderAsInvalid, setRenderAsInvalid] = useState(!!errorMessage || (typeof value === "string" && value !== "" && !validateUrlAddress(value)) || isInvalid);
|
|
4566
4571
|
const errorType = useMemo(() => validateUrl(innerValue ?? "", rest.required), [rest.required, innerValue]);
|
|
4567
4572
|
const error = useMemo(() => (errorType ? t(`urlField.error.${errorType}`) : errorMessage), [errorType, errorMessage, t]);
|
|
4568
4573
|
const handleBlur = useCallback(event => {
|
|
@@ -4571,7 +4576,7 @@ const UrlField = ({ label, id, tip, helpText, errorMessage, helpAddon, className
|
|
|
4571
4576
|
setRenderAsInvalid(!!validateUrl(newValue, rest.required));
|
|
4572
4577
|
onBlur?.(event);
|
|
4573
4578
|
}, [onBlur, rest.required]);
|
|
4574
|
-
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? error : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsx(UrlBaseInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, ref: ref, value: value
|
|
4579
|
+
return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? error : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(UrlBaseInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, ref: ref, value: value ?? defaultValue, ...rest, className: className, "data-testid": dataTestId }) }));
|
|
4575
4580
|
};
|
|
4576
4581
|
UrlField.displayName = "UrlField";
|
|
4577
4582
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-form-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -9,18 +9,18 @@
|
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"react": "19.0.0",
|
|
11
11
|
"react-select": "^5.10.2",
|
|
12
|
-
"@trackunit/date-and-time-utils": "1.11.
|
|
12
|
+
"@trackunit/date-and-time-utils": "1.11.70",
|
|
13
13
|
"usehooks-ts": "^3.1.0",
|
|
14
14
|
"libphonenumber-js": "^1.12.22",
|
|
15
15
|
"zod": "^3.23.8",
|
|
16
16
|
"react-hook-form": "7.62.0",
|
|
17
17
|
"tailwind-merge": "^2.0.0",
|
|
18
|
-
"@trackunit/css-class-variance-utilities": "1.11.
|
|
19
|
-
"@trackunit/react-components": "1.18.
|
|
20
|
-
"@trackunit/ui-icons": "1.11.
|
|
21
|
-
"@trackunit/shared-utils": "1.13.
|
|
22
|
-
"@trackunit/ui-design-tokens": "1.11.
|
|
23
|
-
"@trackunit/i18n-library-translation": "1.
|
|
18
|
+
"@trackunit/css-class-variance-utilities": "1.11.68",
|
|
19
|
+
"@trackunit/react-components": "1.18.9",
|
|
20
|
+
"@trackunit/ui-icons": "1.11.66",
|
|
21
|
+
"@trackunit/shared-utils": "1.13.68",
|
|
22
|
+
"@trackunit/ui-design-tokens": "1.11.67",
|
|
23
|
+
"@trackunit/i18n-library-translation": "1.13.0",
|
|
24
24
|
"string-ts": "^2.0.0",
|
|
25
25
|
"es-toolkit": "^1.39.10"
|
|
26
26
|
},
|