@trackunit/react-form-components 0.1.1 → 0.1.2
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 +281 -57
- package/index.esm.js +282 -59
- package/package.json +1 -1
- package/src/components/EmailInput/EmailInput.d.ts +1 -1
- package/src/components/PhoneInput/PhoneInputValidationUtils.d.ts +4 -0
- package/src/translation.d.ts +2 -2
- package/src/utilities/ColorFieldValidationUtils.d.ts +5 -0
- package/src/utilities/EmailFieldValidationUtils.d.ts +5 -0
- package/src/utilities/NumberFieldValidationUtils.d.ts +6 -0
- package/src/utilities/UrlFieldValidationUtils.d.ts +5 -0
- package/src/utilities/typeUtils.d.ts +12 -0
package/index.cjs.js
CHANGED
|
@@ -39,10 +39,19 @@ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
|
39
39
|
|
|
40
40
|
var defaultTranslations = {
|
|
41
41
|
"clearIndicator.icon.tooltip.clearAll": "Clear all",
|
|
42
|
+
"colorField.error.INVALID_HEX_CODE": "Please enter a valid HEX code",
|
|
43
|
+
"colorField.error.REQUIRED": "This field is required",
|
|
42
44
|
"dropzone.input.title": "Drag-and-drop file input",
|
|
43
45
|
"dropzone.label.default": "<clickable>Browse</clickable> or drag files here...",
|
|
46
|
+
"emailField.error.INVALID_EMAIL": "Please enter a valid email address",
|
|
47
|
+
"emailField.error.REQUIRED": "The email address is required",
|
|
44
48
|
"field.notEditable.tooltip": "This field is not editable",
|
|
45
49
|
"field.required.asterisk.tooltip": "This field is required",
|
|
50
|
+
"numberField.error.GREATER_THAN": "Value must be greater than or equal to {{min}}",
|
|
51
|
+
"numberField.error.INVALID_NUMBER": "Please enter a valid number",
|
|
52
|
+
"numberField.error.LESS_THAN": "Value must be less than or equal to {{max}}",
|
|
53
|
+
"numberField.error.NOT_IN_BETWEEN": "Must be between {{min}} and {{max}}",
|
|
54
|
+
"numberField.error.REQUIRED": "This field is required",
|
|
46
55
|
"phoneField.error.INVALID_COUNTRY": "The country code is not valid",
|
|
47
56
|
"phoneField.error.INVALID_LENGTH": "The phone number is not valid",
|
|
48
57
|
"phoneField.error.INVALID_NUMBER": "The phone number is not valid",
|
|
@@ -51,7 +60,9 @@ var defaultTranslations = {
|
|
|
51
60
|
"phoneField.error.REQUIRED_COUNTRY": "The country code is required",
|
|
52
61
|
"phoneField.error.TOO_LONG": "The phone number is too long",
|
|
53
62
|
"phoneField.error.TOO_SHORT": "The phone number is too short",
|
|
54
|
-
"phoneField.error.undefined": ""
|
|
63
|
+
"phoneField.error.undefined": "",
|
|
64
|
+
"urlField.error.INVALID_URL": "Please enter a valid URL",
|
|
65
|
+
"urlField.error.REQUIRED": "The URL is required"
|
|
55
66
|
};
|
|
56
67
|
|
|
57
68
|
/** The translation namespace for this library */
|
|
@@ -630,6 +641,39 @@ const CheckboxField = React.forwardRef(({ label, id, tip, helpText, helpAddon, i
|
|
|
630
641
|
});
|
|
631
642
|
CheckboxField.displayName = "CheckboxField";
|
|
632
643
|
|
|
644
|
+
/**
|
|
645
|
+
*
|
|
646
|
+
* @param inputValue - value to check if it is a string
|
|
647
|
+
* @returns {boolean} - true if value is a string
|
|
648
|
+
*/
|
|
649
|
+
const isString = (inputValue) => {
|
|
650
|
+
return typeof inputValue === "string";
|
|
651
|
+
};
|
|
652
|
+
/**
|
|
653
|
+
*
|
|
654
|
+
* @param inputValue - value to check if it is a number
|
|
655
|
+
* @returns {boolean} - true if value is a number
|
|
656
|
+
*/
|
|
657
|
+
const isNumber = (inputValue) => {
|
|
658
|
+
return typeof inputValue === "number";
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Validates a url
|
|
663
|
+
*/
|
|
664
|
+
const validateColorCode = (colorCode, required) => {
|
|
665
|
+
if (!colorCode && !required) {
|
|
666
|
+
return undefined;
|
|
667
|
+
}
|
|
668
|
+
if (!colorCode && required) {
|
|
669
|
+
return "REQUIRED";
|
|
670
|
+
}
|
|
671
|
+
if (colorCode && isString(colorCode) && isValidHEXColor(colorCode)) {
|
|
672
|
+
return undefined;
|
|
673
|
+
}
|
|
674
|
+
return "INVALID_HEX_CODE";
|
|
675
|
+
};
|
|
676
|
+
|
|
633
677
|
/**
|
|
634
678
|
* Validates if the given value is a valid hex color.
|
|
635
679
|
*
|
|
@@ -645,25 +689,34 @@ const isValidHEXColor = (value) => {
|
|
|
645
689
|
* ColorField validates that user enters a valid color address.
|
|
646
690
|
*
|
|
647
691
|
*/
|
|
648
|
-
const ColorField = React.forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, value: propValue, onChange, isInvalid = false, ...rest }, ref) => {
|
|
692
|
+
const ColorField = React.forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, value: propValue, onChange, isInvalid = false, onBlur, ...rest }, ref) => {
|
|
649
693
|
const htmlForId = React.useMemo(() => (id ? id : "colorField-" + uuid.v4()), [id]);
|
|
650
694
|
const innerRef = React.useRef(null);
|
|
651
695
|
React.useImperativeHandle(ref, () => innerRef.current, []);
|
|
696
|
+
const [t] = useTranslation();
|
|
652
697
|
// Internal state for color value
|
|
653
|
-
const [
|
|
698
|
+
const [innerValue, setInnerValue] = React.useState(propValue || defaultValue || "");
|
|
699
|
+
const [renderAsInvalid, setRenderAsInvalid] = React.useState(!!errorMessage || (innerValue && typeof innerValue === "string" && !isValidHEXColor(innerValue)) || isInvalid);
|
|
700
|
+
const errorType = React.useMemo(() => validateColorCode(innerValue, rest.required), [rest.required, innerValue]);
|
|
701
|
+
const error = React.useMemo(() => (errorType ? t(`colorField.error.${errorType}`) : errorMessage), [errorType, errorMessage, t]);
|
|
702
|
+
const handleBlur = React.useCallback(event => {
|
|
703
|
+
const newValue = event.target.value;
|
|
704
|
+
setInnerValue(newValue);
|
|
705
|
+
setRenderAsInvalid(!!errorType);
|
|
706
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
707
|
+
}, [errorType, onBlur]);
|
|
654
708
|
const handleChange = React.useCallback((event) => {
|
|
655
709
|
const newValue = event.target.value;
|
|
656
|
-
|
|
710
|
+
setInnerValue(newValue);
|
|
657
711
|
if (onChange) {
|
|
658
712
|
onChange(event);
|
|
659
713
|
}
|
|
660
714
|
}, [onChange]);
|
|
661
|
-
|
|
662
|
-
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsxs("div", { className: cvaInput({
|
|
715
|
+
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsxs("div", { className: cvaInput({
|
|
663
716
|
disabled: false,
|
|
664
717
|
invalid: false,
|
|
665
718
|
className,
|
|
666
|
-
}), "data-testid": dataTestId ? `${dataTestId}-container` : undefined, children: [jsxRuntime.jsx("input", { "aria-labelledby": htmlForId + "-label", className: "ml-2 h-[30px] w-[40px] self-center rounded-full bg-inherit", "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, onChange: handleChange, ref: innerRef, type: "color", value:
|
|
719
|
+
}), "data-testid": dataTestId ? `${dataTestId}-container` : undefined, children: [jsxRuntime.jsx("input", { "aria-labelledby": htmlForId + "-label", className: "ml-2 h-[30px] w-[40px] self-center rounded-full bg-inherit", "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, onBlur: handleBlur, onChange: handleChange, ref: innerRef, type: "color", value: innerValue }), jsxRuntime.jsx("input", { "aria-labelledby": htmlForId + "-label-text", className: cvaInputField({ disabled: false }), "data-testid": dataTestId ? `${dataTestId}-textField` : undefined, onBlur: handleBlur, onChange: handleChange, type: "text", value: innerValue }), jsxRuntime.jsx(reactComponents.IconButton, { className: "mr-1 self-center", icon: jsxRuntime.jsx(reactComponents.Icon, { name: "Pencil", type: "outline" }), onClick: () => {
|
|
667
720
|
if (innerRef.current) {
|
|
668
721
|
innerRef.current.click();
|
|
669
722
|
}
|
|
@@ -824,6 +877,22 @@ const validateEmailAddress = (email) => {
|
|
|
824
877
|
return EMAIL_REGEX.test(email);
|
|
825
878
|
};
|
|
826
879
|
|
|
880
|
+
/**
|
|
881
|
+
* Validates a email id
|
|
882
|
+
*/
|
|
883
|
+
const validateEmailId = (emailId, required) => {
|
|
884
|
+
if (!emailId && !required) {
|
|
885
|
+
return undefined;
|
|
886
|
+
}
|
|
887
|
+
if (!emailId && required) {
|
|
888
|
+
return "REQUIRED";
|
|
889
|
+
}
|
|
890
|
+
if (emailId && isString(emailId) && validateEmailAddress(emailId)) {
|
|
891
|
+
return undefined;
|
|
892
|
+
}
|
|
893
|
+
return "INVALID_EMAIL";
|
|
894
|
+
};
|
|
895
|
+
|
|
827
896
|
/**
|
|
828
897
|
* A Email Input component is used for input of the type Email.
|
|
829
898
|
*
|
|
@@ -854,22 +923,82 @@ EmailInput.displayName = "EmailInput";
|
|
|
854
923
|
* EmailField validates that user enters a valid email address.
|
|
855
924
|
*
|
|
856
925
|
*/
|
|
857
|
-
const EmailField = React.forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, value, disabled, onChange, isInvalid = false, ...rest }, ref) => {
|
|
926
|
+
const EmailField = React.forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, value, disabled, onChange, onBlur, isInvalid = false, ...rest }, ref) => {
|
|
858
927
|
const htmlForId = id ? id : "emailField-" + uuid.v4();
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
928
|
+
const [t] = useTranslation();
|
|
929
|
+
const [innerValue, setInnerValue] = React.useState(() => {
|
|
930
|
+
var _a;
|
|
931
|
+
return (_a = ((value === null || value === void 0 ? void 0 : value.toString()) || (defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString()))) !== null && _a !== void 0 ? _a : "";
|
|
932
|
+
});
|
|
933
|
+
const [renderAsInvalid, setRenderAsInvalid] = React.useState(!!errorMessage || (value && isString(value) && !validateEmailAddress(value)) || isInvalid);
|
|
934
|
+
const errorType = React.useMemo(() => validateEmailId(innerValue !== null && innerValue !== void 0 ? innerValue : "", rest.required), [rest.required, innerValue]);
|
|
935
|
+
const error = React.useMemo(() => (errorType ? t(`emailField.error.${errorType}`) : errorMessage), [errorType, errorMessage, t]);
|
|
936
|
+
const handleBlur = React.useCallback(event => {
|
|
937
|
+
const newValue = event.target.value;
|
|
938
|
+
setInnerValue(newValue);
|
|
939
|
+
setRenderAsInvalid(!!errorType);
|
|
940
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
941
|
+
}, [errorType, onBlur]);
|
|
864
942
|
const handleChange = React.useCallback((event) => {
|
|
943
|
+
setInnerValue(event.target.value);
|
|
865
944
|
if (onChange) {
|
|
866
945
|
onChange(event);
|
|
867
946
|
}
|
|
868
947
|
}, [onChange]);
|
|
869
|
-
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid &&
|
|
948
|
+
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(EmailInput, { "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, disabled: disabled, id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, onChange: handleChange, ref: ref, value: value, ...rest, className: className, dataTestId: dataTestId }) }));
|
|
870
949
|
});
|
|
871
950
|
EmailField.displayName = "EmailField";
|
|
872
951
|
|
|
952
|
+
const isNumberValid = (number) => {
|
|
953
|
+
if (!isNaN(+number) === false) {
|
|
954
|
+
return false;
|
|
955
|
+
}
|
|
956
|
+
if (typeof number === "number") {
|
|
957
|
+
return true;
|
|
958
|
+
}
|
|
959
|
+
return /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/.test(number);
|
|
960
|
+
};
|
|
961
|
+
/**
|
|
962
|
+
* Validates a number
|
|
963
|
+
*/
|
|
964
|
+
const validateNumber = (number, required = false, min, max) => {
|
|
965
|
+
const parsedNumber = Number(number);
|
|
966
|
+
const minValue = typeof min === "string" ? parseFloat(min) : min;
|
|
967
|
+
const maxValue = typeof max === "string" ? parseFloat(max) : max;
|
|
968
|
+
if (number === undefined) {
|
|
969
|
+
return undefined;
|
|
970
|
+
}
|
|
971
|
+
// if the value is a string eg:'test'
|
|
972
|
+
if (number && !isNaN(+number) === false) {
|
|
973
|
+
return "INVALID_NUMBER";
|
|
974
|
+
}
|
|
975
|
+
// if the value is empty and not required
|
|
976
|
+
if (!Number.isNaN(parsedNumber) && !parsedNumber && !required && !min && !max) {
|
|
977
|
+
return undefined;
|
|
978
|
+
}
|
|
979
|
+
// if the value is empty and required
|
|
980
|
+
if (!Number.isNaN(parsedNumber) && !parsedNumber && required) {
|
|
981
|
+
return "REQUIRED";
|
|
982
|
+
}
|
|
983
|
+
// if the value is not in between min and max
|
|
984
|
+
if (minValue && maxValue && isNumberValid(parsedNumber) && !(parsedNumber >= minValue && parsedNumber <= maxValue)) {
|
|
985
|
+
return "NOT_IN_BETWEEN";
|
|
986
|
+
}
|
|
987
|
+
// if the value is less than min
|
|
988
|
+
if (isNumberValid(parsedNumber) && minValue !== undefined && parsedNumber < minValue) {
|
|
989
|
+
return "GREATER_THAN";
|
|
990
|
+
}
|
|
991
|
+
// if the value is greater than max
|
|
992
|
+
if (isNumberValid(parsedNumber) && maxValue !== undefined && parsedNumber > maxValue) {
|
|
993
|
+
return "LESS_THAN";
|
|
994
|
+
}
|
|
995
|
+
// if the value is a number and is valid
|
|
996
|
+
if (isNumber(parsedNumber) && isNumberValid(parsedNumber)) {
|
|
997
|
+
return undefined;
|
|
998
|
+
}
|
|
999
|
+
return "INVALID_NUMBER";
|
|
1000
|
+
};
|
|
1001
|
+
|
|
873
1002
|
/**
|
|
874
1003
|
* A thin wrapper around the `BaseInput` component for number input fields.
|
|
875
1004
|
*
|
|
@@ -887,10 +1016,39 @@ NumberInput.displayName = "NumberInput";
|
|
|
887
1016
|
*
|
|
888
1017
|
* _**Do not use**_ this fields for non-serialized numbers. Use TextField instead.
|
|
889
1018
|
*/
|
|
890
|
-
const NumberField = React.forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid, maxLength, className, value, dataTestId, ...rest }, ref) => {
|
|
891
|
-
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
1019
|
+
const NumberField = React.forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid, maxLength, className, value, dataTestId, defaultValue, onBlur, ...rest }, ref) => {
|
|
892
1020
|
const htmlForId = id ? id : "numberField-" + uuid.v4();
|
|
893
|
-
|
|
1021
|
+
const [t] = useTranslation();
|
|
1022
|
+
const [innerValue, setInnerValue] = React.useState(() => {
|
|
1023
|
+
return Number(value === null || value === void 0 ? void 0 : value.toString()) || Number(defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString());
|
|
1024
|
+
});
|
|
1025
|
+
const [renderAsInvalid, setRenderAsInvalid] = React.useState((isInvalid === undefined ? Boolean(errorMessage) : isInvalid) ||
|
|
1026
|
+
!!validateNumber(value === null || value === void 0 ? void 0 : value.toString(), rest.required, rest.min, rest.max));
|
|
1027
|
+
const errorType = React.useMemo(() => validateNumber(innerValue, rest.required, rest.min, rest.max), [innerValue, rest.max, rest.min, rest.required]);
|
|
1028
|
+
const error = React.useMemo(() => {
|
|
1029
|
+
// for the case when a custom error message is provided
|
|
1030
|
+
if (errorMessage) {
|
|
1031
|
+
setRenderAsInvalid(Boolean(errorMessage));
|
|
1032
|
+
return errorMessage;
|
|
1033
|
+
}
|
|
1034
|
+
else if (errorType) {
|
|
1035
|
+
return t(`numberField.error.${errorType}`, { min: rest.min, max: rest.max });
|
|
1036
|
+
}
|
|
1037
|
+
return errorMessage;
|
|
1038
|
+
}, [errorMessage, errorType, rest.max, rest.min, t]);
|
|
1039
|
+
const handleBlur = React.useCallback(event => {
|
|
1040
|
+
const newValue = event.target.value;
|
|
1041
|
+
setInnerValue(newValue.toString());
|
|
1042
|
+
// for the case when a custom error message is provided
|
|
1043
|
+
if (errorMessage && !validateNumber(newValue, rest.required, rest.min, rest.max)) {
|
|
1044
|
+
setRenderAsInvalid(Boolean(errorMessage));
|
|
1045
|
+
}
|
|
1046
|
+
else {
|
|
1047
|
+
setRenderAsInvalid(!!validateNumber(newValue, rest.required, rest.min, rest.max));
|
|
1048
|
+
}
|
|
1049
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
1050
|
+
}, [errorMessage, onBlur, rest.max, rest.min, rest.required]);
|
|
1051
|
+
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(NumberInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, onBlur: handleBlur, ref: ref, value: value, ...rest, className: className, dataTestId: dataTestId }) }));
|
|
894
1052
|
});
|
|
895
1053
|
NumberField.displayName = "NumberField";
|
|
896
1054
|
|
|
@@ -1071,39 +1229,6 @@ const PhoneInput = React.forwardRef(({ dataTestId, isInvalid, disabled = false,
|
|
|
1071
1229
|
});
|
|
1072
1230
|
PhoneInput.displayName = "PhoneInput";
|
|
1073
1231
|
|
|
1074
|
-
/**
|
|
1075
|
-
* The PhoneField component is used to enter phone number.
|
|
1076
|
-
* It is a wrapper around the PhoneInput component and the FormGroup component.
|
|
1077
|
-
* It is used to render a phone number field with a label, a tip, a help text, a help addon and an error message.
|
|
1078
|
-
*
|
|
1079
|
-
* @param {string} [label] - The label for the component.
|
|
1080
|
-
* @param {string} [tip] - The tip for the component.
|
|
1081
|
-
* @param {string} [helpText] - The help text for the component.
|
|
1082
|
-
* @param {string} [helpAddon] - The help addon for the component.
|
|
1083
|
-
* @param {string} [errorMessage] - The error message for the component.
|
|
1084
|
-
* @param {string} [defaultValue] - The default value for the component.
|
|
1085
|
-
* @param {boolean} [disabled=false] - Whether the component is disabled or not.
|
|
1086
|
-
* @param {string} [fieldSize="medium"] - The size of the input field.
|
|
1087
|
-
* @param {boolean} [disableAction=false] - Whether the action button is disabled or not.
|
|
1088
|
-
* @returns {JSX.Element} - The PhoneField component.
|
|
1089
|
-
*/
|
|
1090
|
-
const PhoneField = React.forwardRef(({ label, id, tip, helpText, isInvalid, errorMessage, value, helpAddon, className, defaultValue, dataTestId, name, onChange, onBlur, ...rest }, ref) => {
|
|
1091
|
-
const htmlForId = id ? id : "phoneField-" + uuid.v4();
|
|
1092
|
-
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
1093
|
-
return (jsxRuntime.jsx(FormGroup, { className: className, dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(PhoneInput, { "aria-labelledby": htmlForId + "-label", dataTestId: dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, name: name, onBlur: onBlur, onChange: onChange, ref: ref, value: value, ...rest }) }));
|
|
1094
|
-
});
|
|
1095
|
-
PhoneField.displayName = "PhoneField";
|
|
1096
|
-
|
|
1097
|
-
/**
|
|
1098
|
-
* The PhoneFieldWithController component is a wrapper for the PhoneField component to connect it to react-hook-form.
|
|
1099
|
-
*
|
|
1100
|
-
* @returns {JSX.Element} - The PhoneFieldWithController component.
|
|
1101
|
-
*/
|
|
1102
|
-
const PhoneFieldWithController = React.forwardRef(({ control, controllerProps, name, value, ...rest }, ref) => {
|
|
1103
|
-
return (jsxRuntime.jsx(reactHookForm.Controller, { control: control, defaultValue: value, name: name, ...controllerProps, render: ({ field }) => jsxRuntime.jsx(PhoneField, { ...rest, ...field, ref: ref }) }));
|
|
1104
|
-
});
|
|
1105
|
-
PhoneFieldWithController.displayName = "PhoneFieldWithController";
|
|
1106
|
-
|
|
1107
1232
|
/**
|
|
1108
1233
|
* Validates a phone number
|
|
1109
1234
|
*/
|
|
@@ -1143,6 +1268,79 @@ const isInvalidCountryCode = (error, required) => (!!required && error === "REQU
|
|
|
1143
1268
|
* Checks if the phone number is valid and required
|
|
1144
1269
|
*/
|
|
1145
1270
|
const isInvalidPhoneNumber = (error, required) => error !== "REQUIRED_COUNTRY" && ((!!error && error !== "REQUIRED") || (!!required && error === "REQUIRED"));
|
|
1271
|
+
/**
|
|
1272
|
+
* Checks if the phone number is valid and returns corresponding error message
|
|
1273
|
+
*/
|
|
1274
|
+
const phoneErrorMessage = (phoneNumber, required) => {
|
|
1275
|
+
if ((validatePhoneNumber(phoneNumber) === "REQUIRED" && !required) ||
|
|
1276
|
+
(validatePhoneNumber(phoneNumber) === "REQUIRED" && required && phoneNumber === undefined)) {
|
|
1277
|
+
return undefined;
|
|
1278
|
+
}
|
|
1279
|
+
return validatePhoneNumber(phoneNumber);
|
|
1280
|
+
};
|
|
1281
|
+
|
|
1282
|
+
/**
|
|
1283
|
+
* The PhoneField component is used to enter phone number.
|
|
1284
|
+
* It is a wrapper around the PhoneInput component and the FormGroup component.
|
|
1285
|
+
* It is used to render a phone number field with a label, a tip, a help text, a help addon and an error message.
|
|
1286
|
+
*
|
|
1287
|
+
* @param {string} [label] - The label for the component.
|
|
1288
|
+
* @param {string} [tip] - The tip for the component.
|
|
1289
|
+
* @param {string} [helpText] - The help text for the component.
|
|
1290
|
+
* @param {string} [helpAddon] - The help addon for the component.
|
|
1291
|
+
* @param {string} [errorMessage] - The error message for the component.
|
|
1292
|
+
* @param {string} [defaultValue] - The default value for the component.
|
|
1293
|
+
* @param {boolean} [disabled=false] - Whether the component is disabled or not.
|
|
1294
|
+
* @param {string} [fieldSize="medium"] - The size of the input field.
|
|
1295
|
+
* @param {boolean} [disableAction=false] - Whether the action button is disabled or not.
|
|
1296
|
+
* @returns {JSX.Element} - The PhoneField component.
|
|
1297
|
+
*/
|
|
1298
|
+
const PhoneField = React.forwardRef(({ label, id, tip, helpText, isInvalid, errorMessage, value, helpAddon, className, defaultValue, dataTestId, name, onBlur, ...rest }, ref) => {
|
|
1299
|
+
const htmlForId = id ? id : "phoneField-" + uuid.v4();
|
|
1300
|
+
const [t] = useTranslation();
|
|
1301
|
+
const [innerValue, setInnerValue] = React.useState(() => {
|
|
1302
|
+
var _a;
|
|
1303
|
+
return (_a = ((value === null || value === void 0 ? void 0 : value.toString()) || (defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString()))) !== null && _a !== void 0 ? _a : undefined;
|
|
1304
|
+
});
|
|
1305
|
+
const [renderAsInvalid, setRenderAsInvalid] = React.useState((isInvalid === undefined ? Boolean(errorMessage) : isInvalid) ||
|
|
1306
|
+
!!phoneErrorMessage(value === null || value === void 0 ? void 0 : value.toString(), rest.required));
|
|
1307
|
+
const errorType = React.useMemo(() => phoneErrorMessage(innerValue, rest.required), [innerValue, rest.required]);
|
|
1308
|
+
const error = React.useMemo(() => {
|
|
1309
|
+
// for the case when a custom error message is provided
|
|
1310
|
+
if (errorMessage) {
|
|
1311
|
+
setRenderAsInvalid(Boolean(errorMessage));
|
|
1312
|
+
return errorMessage;
|
|
1313
|
+
}
|
|
1314
|
+
else if (errorType) {
|
|
1315
|
+
return t(`phoneField.error.${errorType}`);
|
|
1316
|
+
}
|
|
1317
|
+
return errorMessage;
|
|
1318
|
+
}, [errorMessage, errorType, t]);
|
|
1319
|
+
const handleBlur = React.useCallback(event => {
|
|
1320
|
+
const newValue = event.target.value;
|
|
1321
|
+
setInnerValue(newValue);
|
|
1322
|
+
// for the case when a custom error message is provided
|
|
1323
|
+
if (errorMessage && !phoneErrorMessage(newValue.toString(), rest.required)) {
|
|
1324
|
+
setRenderAsInvalid(Boolean(errorMessage));
|
|
1325
|
+
}
|
|
1326
|
+
else {
|
|
1327
|
+
setRenderAsInvalid(!!phoneErrorMessage(newValue.toString(), rest.required));
|
|
1328
|
+
}
|
|
1329
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
1330
|
+
}, [errorMessage, onBlur, rest.required]);
|
|
1331
|
+
return (jsxRuntime.jsx(FormGroup, { className: className, dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(PhoneInput, { "aria-labelledby": htmlForId + "-label", dataTestId: dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, name: name, onBlur: handleBlur, ref: ref, value: value, ...rest }) }));
|
|
1332
|
+
});
|
|
1333
|
+
PhoneField.displayName = "PhoneField";
|
|
1334
|
+
|
|
1335
|
+
/**
|
|
1336
|
+
* The PhoneFieldWithController component is a wrapper for the PhoneField component to connect it to react-hook-form.
|
|
1337
|
+
*
|
|
1338
|
+
* @returns {JSX.Element} - The PhoneFieldWithController component.
|
|
1339
|
+
*/
|
|
1340
|
+
const PhoneFieldWithController = React.forwardRef(({ control, controllerProps, name, value, ...rest }, ref) => {
|
|
1341
|
+
return (jsxRuntime.jsx(reactHookForm.Controller, { control: control, defaultValue: value, name: name, ...controllerProps, render: ({ field }) => jsxRuntime.jsx(PhoneField, { ...rest, ...field, ref: ref }) }));
|
|
1342
|
+
});
|
|
1343
|
+
PhoneFieldWithController.displayName = "PhoneFieldWithController";
|
|
1146
1344
|
|
|
1147
1345
|
const cvaRadioGroup = cssClassVarianceUtilities.cvaMerge(["flex", "gap-2", "flex-col", "items-start"], {
|
|
1148
1346
|
variants: {
|
|
@@ -2454,6 +2652,22 @@ const validateUrlAddress = (url) => {
|
|
|
2454
2652
|
return urlPattern.test(url);
|
|
2455
2653
|
};
|
|
2456
2654
|
|
|
2655
|
+
/**
|
|
2656
|
+
* Validates a url
|
|
2657
|
+
*/
|
|
2658
|
+
const validateUrl = (url, required) => {
|
|
2659
|
+
if (!url && !required) {
|
|
2660
|
+
return undefined;
|
|
2661
|
+
}
|
|
2662
|
+
if (!url && required) {
|
|
2663
|
+
return "REQUIRED";
|
|
2664
|
+
}
|
|
2665
|
+
if (url && isString(url) && validateUrlAddress(url)) {
|
|
2666
|
+
return undefined;
|
|
2667
|
+
}
|
|
2668
|
+
return "INVALID_URL";
|
|
2669
|
+
};
|
|
2670
|
+
|
|
2457
2671
|
/**
|
|
2458
2672
|
* A thin wrapper around the `BaseInput` component for URL input fields.
|
|
2459
2673
|
*
|
|
@@ -2471,14 +2685,23 @@ UrlInput.displayName = "UrlField";
|
|
|
2471
2685
|
* UrlField validates that user enters a valid web address.
|
|
2472
2686
|
*
|
|
2473
2687
|
*/
|
|
2474
|
-
const UrlField = React.forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, isInvalid = false, value, ...rest }, ref) => {
|
|
2688
|
+
const UrlField = React.forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, isInvalid = false, value, onBlur, ...rest }, ref) => {
|
|
2475
2689
|
const htmlForId = id ? id : "urlField-" + uuid.v4();
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2690
|
+
const [t] = useTranslation();
|
|
2691
|
+
const [innerValue, setInnerValue] = React.useState(() => {
|
|
2692
|
+
var _a;
|
|
2693
|
+
return (_a = ((value === null || value === void 0 ? void 0 : value.toString()) || (defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString()))) !== null && _a !== void 0 ? _a : "";
|
|
2694
|
+
});
|
|
2695
|
+
const [renderAsInvalid, setRenderAsInvalid] = React.useState(!!errorMessage || (value && isString(value) && !validateUrlAddress(value)) || isInvalid);
|
|
2696
|
+
const errorType = React.useMemo(() => validateUrl(innerValue !== null && innerValue !== void 0 ? innerValue : "", rest.required), [rest.required, innerValue]);
|
|
2697
|
+
const error = React.useMemo(() => (errorType ? t(`urlField.error.${errorType}`) : errorMessage), [errorType, errorMessage, t]);
|
|
2698
|
+
const handleBlur = React.useCallback(event => {
|
|
2699
|
+
const newValue = event.target.value;
|
|
2700
|
+
setInnerValue(newValue);
|
|
2701
|
+
setRenderAsInvalid(!!validateUrl(newValue, rest.required));
|
|
2702
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
2703
|
+
}, [onBlur, rest.required]);
|
|
2704
|
+
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? error : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(UrlInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, ref: ref, value: value || defaultValue, ...rest, className: className, dataTestId: dataTestId }) }));
|
|
2482
2705
|
});
|
|
2483
2706
|
UrlField.displayName = "UrlField";
|
|
2484
2707
|
|
|
@@ -2667,6 +2890,7 @@ exports.isInvalidPhoneNumber = isInvalidPhoneNumber;
|
|
|
2667
2890
|
exports.isMultiValue = isMultiValue;
|
|
2668
2891
|
exports.isValidHEXColor = isValidHEXColor;
|
|
2669
2892
|
exports.parseSchedule = parseSchedule;
|
|
2893
|
+
exports.phoneErrorMessage = phoneErrorMessage;
|
|
2670
2894
|
exports.serializeSchedule = serializeSchedule;
|
|
2671
2895
|
exports.useCustomComponents = useCustomComponents;
|
|
2672
2896
|
exports.useGetPhoneValidationRules = useGetPhoneValidationRules;
|
package/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { useNamespaceTranslation, registerTranslations, NamespaceTrans } from '@trackunit/i18n-library-translation';
|
|
3
3
|
import { IconButton, Icon, Tooltip, Heading, Text, MenuItem, Tag, Spinner, useIsFirstRender } from '@trackunit/react-components';
|
|
4
4
|
import { useCopyToClipboard } from 'react-use';
|
|
5
5
|
import { cvaMerge } from '@trackunit/css-class-variance-utilities';
|
|
@@ -20,10 +20,19 @@ import { z } from 'zod';
|
|
|
20
20
|
|
|
21
21
|
var defaultTranslations = {
|
|
22
22
|
"clearIndicator.icon.tooltip.clearAll": "Clear all",
|
|
23
|
+
"colorField.error.INVALID_HEX_CODE": "Please enter a valid HEX code",
|
|
24
|
+
"colorField.error.REQUIRED": "This field is required",
|
|
23
25
|
"dropzone.input.title": "Drag-and-drop file input",
|
|
24
26
|
"dropzone.label.default": "<clickable>Browse</clickable> or drag files here...",
|
|
27
|
+
"emailField.error.INVALID_EMAIL": "Please enter a valid email address",
|
|
28
|
+
"emailField.error.REQUIRED": "The email address is required",
|
|
25
29
|
"field.notEditable.tooltip": "This field is not editable",
|
|
26
30
|
"field.required.asterisk.tooltip": "This field is required",
|
|
31
|
+
"numberField.error.GREATER_THAN": "Value must be greater than or equal to {{min}}",
|
|
32
|
+
"numberField.error.INVALID_NUMBER": "Please enter a valid number",
|
|
33
|
+
"numberField.error.LESS_THAN": "Value must be less than or equal to {{max}}",
|
|
34
|
+
"numberField.error.NOT_IN_BETWEEN": "Must be between {{min}} and {{max}}",
|
|
35
|
+
"numberField.error.REQUIRED": "This field is required",
|
|
27
36
|
"phoneField.error.INVALID_COUNTRY": "The country code is not valid",
|
|
28
37
|
"phoneField.error.INVALID_LENGTH": "The phone number is not valid",
|
|
29
38
|
"phoneField.error.INVALID_NUMBER": "The phone number is not valid",
|
|
@@ -32,7 +41,9 @@ var defaultTranslations = {
|
|
|
32
41
|
"phoneField.error.REQUIRED_COUNTRY": "The country code is required",
|
|
33
42
|
"phoneField.error.TOO_LONG": "The phone number is too long",
|
|
34
43
|
"phoneField.error.TOO_SHORT": "The phone number is too short",
|
|
35
|
-
"phoneField.error.undefined": ""
|
|
44
|
+
"phoneField.error.undefined": "",
|
|
45
|
+
"urlField.error.INVALID_URL": "Please enter a valid URL",
|
|
46
|
+
"urlField.error.REQUIRED": "The URL is required"
|
|
36
47
|
};
|
|
37
48
|
|
|
38
49
|
/** The translation namespace for this library */
|
|
@@ -611,6 +622,39 @@ const CheckboxField = forwardRef(({ label, id, tip, helpText, helpAddon, isInval
|
|
|
611
622
|
});
|
|
612
623
|
CheckboxField.displayName = "CheckboxField";
|
|
613
624
|
|
|
625
|
+
/**
|
|
626
|
+
*
|
|
627
|
+
* @param inputValue - value to check if it is a string
|
|
628
|
+
* @returns {boolean} - true if value is a string
|
|
629
|
+
*/
|
|
630
|
+
const isString = (inputValue) => {
|
|
631
|
+
return typeof inputValue === "string";
|
|
632
|
+
};
|
|
633
|
+
/**
|
|
634
|
+
*
|
|
635
|
+
* @param inputValue - value to check if it is a number
|
|
636
|
+
* @returns {boolean} - true if value is a number
|
|
637
|
+
*/
|
|
638
|
+
const isNumber = (inputValue) => {
|
|
639
|
+
return typeof inputValue === "number";
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Validates a url
|
|
644
|
+
*/
|
|
645
|
+
const validateColorCode = (colorCode, required) => {
|
|
646
|
+
if (!colorCode && !required) {
|
|
647
|
+
return undefined;
|
|
648
|
+
}
|
|
649
|
+
if (!colorCode && required) {
|
|
650
|
+
return "REQUIRED";
|
|
651
|
+
}
|
|
652
|
+
if (colorCode && isString(colorCode) && isValidHEXColor(colorCode)) {
|
|
653
|
+
return undefined;
|
|
654
|
+
}
|
|
655
|
+
return "INVALID_HEX_CODE";
|
|
656
|
+
};
|
|
657
|
+
|
|
614
658
|
/**
|
|
615
659
|
* Validates if the given value is a valid hex color.
|
|
616
660
|
*
|
|
@@ -626,25 +670,34 @@ const isValidHEXColor = (value) => {
|
|
|
626
670
|
* ColorField validates that user enters a valid color address.
|
|
627
671
|
*
|
|
628
672
|
*/
|
|
629
|
-
const ColorField = forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, value: propValue, onChange, isInvalid = false, ...rest }, ref) => {
|
|
673
|
+
const ColorField = forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, value: propValue, onChange, isInvalid = false, onBlur, ...rest }, ref) => {
|
|
630
674
|
const htmlForId = useMemo(() => (id ? id : "colorField-" + v4()), [id]);
|
|
631
675
|
const innerRef = React__default.useRef(null);
|
|
632
676
|
React__default.useImperativeHandle(ref, () => innerRef.current, []);
|
|
677
|
+
const [t] = useTranslation();
|
|
633
678
|
// Internal state for color value
|
|
634
|
-
const [
|
|
679
|
+
const [innerValue, setInnerValue] = useState(propValue || defaultValue || "");
|
|
680
|
+
const [renderAsInvalid, setRenderAsInvalid] = useState(!!errorMessage || (innerValue && typeof innerValue === "string" && !isValidHEXColor(innerValue)) || isInvalid);
|
|
681
|
+
const errorType = useMemo(() => validateColorCode(innerValue, rest.required), [rest.required, innerValue]);
|
|
682
|
+
const error = useMemo(() => (errorType ? t(`colorField.error.${errorType}`) : errorMessage), [errorType, errorMessage, t]);
|
|
683
|
+
const handleBlur = useCallback(event => {
|
|
684
|
+
const newValue = event.target.value;
|
|
685
|
+
setInnerValue(newValue);
|
|
686
|
+
setRenderAsInvalid(!!errorType);
|
|
687
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
688
|
+
}, [errorType, onBlur]);
|
|
635
689
|
const handleChange = useCallback((event) => {
|
|
636
690
|
const newValue = event.target.value;
|
|
637
|
-
|
|
691
|
+
setInnerValue(newValue);
|
|
638
692
|
if (onChange) {
|
|
639
693
|
onChange(event);
|
|
640
694
|
}
|
|
641
695
|
}, [onChange]);
|
|
642
|
-
|
|
643
|
-
return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxs("div", { className: cvaInput({
|
|
696
|
+
return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxs("div", { className: cvaInput({
|
|
644
697
|
disabled: false,
|
|
645
698
|
invalid: false,
|
|
646
699
|
className,
|
|
647
|
-
}), "data-testid": dataTestId ? `${dataTestId}-container` : undefined, children: [jsx("input", { "aria-labelledby": htmlForId + "-label", className: "ml-2 h-[30px] w-[40px] self-center rounded-full bg-inherit", "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, onChange: handleChange, ref: innerRef, type: "color", value:
|
|
700
|
+
}), "data-testid": dataTestId ? `${dataTestId}-container` : undefined, children: [jsx("input", { "aria-labelledby": htmlForId + "-label", className: "ml-2 h-[30px] w-[40px] self-center rounded-full bg-inherit", "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, onBlur: handleBlur, onChange: handleChange, ref: innerRef, type: "color", value: innerValue }), jsx("input", { "aria-labelledby": htmlForId + "-label-text", className: cvaInputField({ disabled: false }), "data-testid": dataTestId ? `${dataTestId}-textField` : undefined, onBlur: handleBlur, onChange: handleChange, type: "text", value: innerValue }), jsx(IconButton, { className: "mr-1 self-center", icon: jsx(Icon, { name: "Pencil", type: "outline" }), onClick: () => {
|
|
648
701
|
if (innerRef.current) {
|
|
649
702
|
innerRef.current.click();
|
|
650
703
|
}
|
|
@@ -805,6 +858,22 @@ const validateEmailAddress = (email) => {
|
|
|
805
858
|
return EMAIL_REGEX.test(email);
|
|
806
859
|
};
|
|
807
860
|
|
|
861
|
+
/**
|
|
862
|
+
* Validates a email id
|
|
863
|
+
*/
|
|
864
|
+
const validateEmailId = (emailId, required) => {
|
|
865
|
+
if (!emailId && !required) {
|
|
866
|
+
return undefined;
|
|
867
|
+
}
|
|
868
|
+
if (!emailId && required) {
|
|
869
|
+
return "REQUIRED";
|
|
870
|
+
}
|
|
871
|
+
if (emailId && isString(emailId) && validateEmailAddress(emailId)) {
|
|
872
|
+
return undefined;
|
|
873
|
+
}
|
|
874
|
+
return "INVALID_EMAIL";
|
|
875
|
+
};
|
|
876
|
+
|
|
808
877
|
/**
|
|
809
878
|
* A Email Input component is used for input of the type Email.
|
|
810
879
|
*
|
|
@@ -835,22 +904,82 @@ EmailInput.displayName = "EmailInput";
|
|
|
835
904
|
* EmailField validates that user enters a valid email address.
|
|
836
905
|
*
|
|
837
906
|
*/
|
|
838
|
-
const EmailField = forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, value, disabled, onChange, isInvalid = false, ...rest }, ref) => {
|
|
907
|
+
const EmailField = forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, value, disabled, onChange, onBlur, isInvalid = false, ...rest }, ref) => {
|
|
839
908
|
const htmlForId = id ? id : "emailField-" + v4();
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
909
|
+
const [t] = useTranslation();
|
|
910
|
+
const [innerValue, setInnerValue] = useState(() => {
|
|
911
|
+
var _a;
|
|
912
|
+
return (_a = ((value === null || value === void 0 ? void 0 : value.toString()) || (defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString()))) !== null && _a !== void 0 ? _a : "";
|
|
913
|
+
});
|
|
914
|
+
const [renderAsInvalid, setRenderAsInvalid] = useState(!!errorMessage || (value && isString(value) && !validateEmailAddress(value)) || isInvalid);
|
|
915
|
+
const errorType = useMemo(() => validateEmailId(innerValue !== null && innerValue !== void 0 ? innerValue : "", rest.required), [rest.required, innerValue]);
|
|
916
|
+
const error = useMemo(() => (errorType ? t(`emailField.error.${errorType}`) : errorMessage), [errorType, errorMessage, t]);
|
|
917
|
+
const handleBlur = useCallback(event => {
|
|
918
|
+
const newValue = event.target.value;
|
|
919
|
+
setInnerValue(newValue);
|
|
920
|
+
setRenderAsInvalid(!!errorType);
|
|
921
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
922
|
+
}, [errorType, onBlur]);
|
|
845
923
|
const handleChange = useCallback((event) => {
|
|
924
|
+
setInnerValue(event.target.value);
|
|
846
925
|
if (onChange) {
|
|
847
926
|
onChange(event);
|
|
848
927
|
}
|
|
849
928
|
}, [onChange]);
|
|
850
|
-
return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid &&
|
|
929
|
+
return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(EmailInput, { "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, disabled: disabled, id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, onChange: handleChange, ref: ref, value: value, ...rest, className: className, dataTestId: dataTestId }) }));
|
|
851
930
|
});
|
|
852
931
|
EmailField.displayName = "EmailField";
|
|
853
932
|
|
|
933
|
+
const isNumberValid = (number) => {
|
|
934
|
+
if (!isNaN(+number) === false) {
|
|
935
|
+
return false;
|
|
936
|
+
}
|
|
937
|
+
if (typeof number === "number") {
|
|
938
|
+
return true;
|
|
939
|
+
}
|
|
940
|
+
return /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/.test(number);
|
|
941
|
+
};
|
|
942
|
+
/**
|
|
943
|
+
* Validates a number
|
|
944
|
+
*/
|
|
945
|
+
const validateNumber = (number, required = false, min, max) => {
|
|
946
|
+
const parsedNumber = Number(number);
|
|
947
|
+
const minValue = typeof min === "string" ? parseFloat(min) : min;
|
|
948
|
+
const maxValue = typeof max === "string" ? parseFloat(max) : max;
|
|
949
|
+
if (number === undefined) {
|
|
950
|
+
return undefined;
|
|
951
|
+
}
|
|
952
|
+
// if the value is a string eg:'test'
|
|
953
|
+
if (number && !isNaN(+number) === false) {
|
|
954
|
+
return "INVALID_NUMBER";
|
|
955
|
+
}
|
|
956
|
+
// if the value is empty and not required
|
|
957
|
+
if (!Number.isNaN(parsedNumber) && !parsedNumber && !required && !min && !max) {
|
|
958
|
+
return undefined;
|
|
959
|
+
}
|
|
960
|
+
// if the value is empty and required
|
|
961
|
+
if (!Number.isNaN(parsedNumber) && !parsedNumber && required) {
|
|
962
|
+
return "REQUIRED";
|
|
963
|
+
}
|
|
964
|
+
// if the value is not in between min and max
|
|
965
|
+
if (minValue && maxValue && isNumberValid(parsedNumber) && !(parsedNumber >= minValue && parsedNumber <= maxValue)) {
|
|
966
|
+
return "NOT_IN_BETWEEN";
|
|
967
|
+
}
|
|
968
|
+
// if the value is less than min
|
|
969
|
+
if (isNumberValid(parsedNumber) && minValue !== undefined && parsedNumber < minValue) {
|
|
970
|
+
return "GREATER_THAN";
|
|
971
|
+
}
|
|
972
|
+
// if the value is greater than max
|
|
973
|
+
if (isNumberValid(parsedNumber) && maxValue !== undefined && parsedNumber > maxValue) {
|
|
974
|
+
return "LESS_THAN";
|
|
975
|
+
}
|
|
976
|
+
// if the value is a number and is valid
|
|
977
|
+
if (isNumber(parsedNumber) && isNumberValid(parsedNumber)) {
|
|
978
|
+
return undefined;
|
|
979
|
+
}
|
|
980
|
+
return "INVALID_NUMBER";
|
|
981
|
+
};
|
|
982
|
+
|
|
854
983
|
/**
|
|
855
984
|
* A thin wrapper around the `BaseInput` component for number input fields.
|
|
856
985
|
*
|
|
@@ -868,10 +997,39 @@ NumberInput.displayName = "NumberInput";
|
|
|
868
997
|
*
|
|
869
998
|
* _**Do not use**_ this fields for non-serialized numbers. Use TextField instead.
|
|
870
999
|
*/
|
|
871
|
-
const NumberField = forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid, maxLength, className, value, dataTestId, ...rest }, ref) => {
|
|
872
|
-
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
1000
|
+
const NumberField = forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid, maxLength, className, value, dataTestId, defaultValue, onBlur, ...rest }, ref) => {
|
|
873
1001
|
const htmlForId = id ? id : "numberField-" + v4();
|
|
874
|
-
|
|
1002
|
+
const [t] = useTranslation();
|
|
1003
|
+
const [innerValue, setInnerValue] = useState(() => {
|
|
1004
|
+
return Number(value === null || value === void 0 ? void 0 : value.toString()) || Number(defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString());
|
|
1005
|
+
});
|
|
1006
|
+
const [renderAsInvalid, setRenderAsInvalid] = useState((isInvalid === undefined ? Boolean(errorMessage) : isInvalid) ||
|
|
1007
|
+
!!validateNumber(value === null || value === void 0 ? void 0 : value.toString(), rest.required, rest.min, rest.max));
|
|
1008
|
+
const errorType = useMemo(() => validateNumber(innerValue, rest.required, rest.min, rest.max), [innerValue, rest.max, rest.min, rest.required]);
|
|
1009
|
+
const error = useMemo(() => {
|
|
1010
|
+
// for the case when a custom error message is provided
|
|
1011
|
+
if (errorMessage) {
|
|
1012
|
+
setRenderAsInvalid(Boolean(errorMessage));
|
|
1013
|
+
return errorMessage;
|
|
1014
|
+
}
|
|
1015
|
+
else if (errorType) {
|
|
1016
|
+
return t(`numberField.error.${errorType}`, { min: rest.min, max: rest.max });
|
|
1017
|
+
}
|
|
1018
|
+
return errorMessage;
|
|
1019
|
+
}, [errorMessage, errorType, rest.max, rest.min, t]);
|
|
1020
|
+
const handleBlur = useCallback(event => {
|
|
1021
|
+
const newValue = event.target.value;
|
|
1022
|
+
setInnerValue(newValue.toString());
|
|
1023
|
+
// for the case when a custom error message is provided
|
|
1024
|
+
if (errorMessage && !validateNumber(newValue, rest.required, rest.min, rest.max)) {
|
|
1025
|
+
setRenderAsInvalid(Boolean(errorMessage));
|
|
1026
|
+
}
|
|
1027
|
+
else {
|
|
1028
|
+
setRenderAsInvalid(!!validateNumber(newValue, rest.required, rest.min, rest.max));
|
|
1029
|
+
}
|
|
1030
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
1031
|
+
}, [errorMessage, onBlur, rest.max, rest.min, rest.required]);
|
|
1032
|
+
return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(NumberInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, onBlur: handleBlur, ref: ref, value: value, ...rest, className: className, dataTestId: dataTestId }) }));
|
|
875
1033
|
});
|
|
876
1034
|
NumberField.displayName = "NumberField";
|
|
877
1035
|
|
|
@@ -1052,39 +1210,6 @@ const PhoneInput = forwardRef(({ dataTestId, isInvalid, disabled = false, value,
|
|
|
1052
1210
|
});
|
|
1053
1211
|
PhoneInput.displayName = "PhoneInput";
|
|
1054
1212
|
|
|
1055
|
-
/**
|
|
1056
|
-
* The PhoneField component is used to enter phone number.
|
|
1057
|
-
* It is a wrapper around the PhoneInput component and the FormGroup component.
|
|
1058
|
-
* It is used to render a phone number field with a label, a tip, a help text, a help addon and an error message.
|
|
1059
|
-
*
|
|
1060
|
-
* @param {string} [label] - The label for the component.
|
|
1061
|
-
* @param {string} [tip] - The tip for the component.
|
|
1062
|
-
* @param {string} [helpText] - The help text for the component.
|
|
1063
|
-
* @param {string} [helpAddon] - The help addon for the component.
|
|
1064
|
-
* @param {string} [errorMessage] - The error message for the component.
|
|
1065
|
-
* @param {string} [defaultValue] - The default value for the component.
|
|
1066
|
-
* @param {boolean} [disabled=false] - Whether the component is disabled or not.
|
|
1067
|
-
* @param {string} [fieldSize="medium"] - The size of the input field.
|
|
1068
|
-
* @param {boolean} [disableAction=false] - Whether the action button is disabled or not.
|
|
1069
|
-
* @returns {JSX.Element} - The PhoneField component.
|
|
1070
|
-
*/
|
|
1071
|
-
const PhoneField = forwardRef(({ label, id, tip, helpText, isInvalid, errorMessage, value, helpAddon, className, defaultValue, dataTestId, name, onChange, onBlur, ...rest }, ref) => {
|
|
1072
|
-
const htmlForId = id ? id : "phoneField-" + v4();
|
|
1073
|
-
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
1074
|
-
return (jsx(FormGroup, { className: className, dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(PhoneInput, { "aria-labelledby": htmlForId + "-label", dataTestId: dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, name: name, onBlur: onBlur, onChange: onChange, ref: ref, value: value, ...rest }) }));
|
|
1075
|
-
});
|
|
1076
|
-
PhoneField.displayName = "PhoneField";
|
|
1077
|
-
|
|
1078
|
-
/**
|
|
1079
|
-
* The PhoneFieldWithController component is a wrapper for the PhoneField component to connect it to react-hook-form.
|
|
1080
|
-
*
|
|
1081
|
-
* @returns {JSX.Element} - The PhoneFieldWithController component.
|
|
1082
|
-
*/
|
|
1083
|
-
const PhoneFieldWithController = forwardRef(({ control, controllerProps, name, value, ...rest }, ref) => {
|
|
1084
|
-
return (jsx(Controller, { control: control, defaultValue: value, name: name, ...controllerProps, render: ({ field }) => jsx(PhoneField, { ...rest, ...field, ref: ref }) }));
|
|
1085
|
-
});
|
|
1086
|
-
PhoneFieldWithController.displayName = "PhoneFieldWithController";
|
|
1087
|
-
|
|
1088
1213
|
/**
|
|
1089
1214
|
* Validates a phone number
|
|
1090
1215
|
*/
|
|
@@ -1124,6 +1249,79 @@ const isInvalidCountryCode = (error, required) => (!!required && error === "REQU
|
|
|
1124
1249
|
* Checks if the phone number is valid and required
|
|
1125
1250
|
*/
|
|
1126
1251
|
const isInvalidPhoneNumber = (error, required) => error !== "REQUIRED_COUNTRY" && ((!!error && error !== "REQUIRED") || (!!required && error === "REQUIRED"));
|
|
1252
|
+
/**
|
|
1253
|
+
* Checks if the phone number is valid and returns corresponding error message
|
|
1254
|
+
*/
|
|
1255
|
+
const phoneErrorMessage = (phoneNumber, required) => {
|
|
1256
|
+
if ((validatePhoneNumber(phoneNumber) === "REQUIRED" && !required) ||
|
|
1257
|
+
(validatePhoneNumber(phoneNumber) === "REQUIRED" && required && phoneNumber === undefined)) {
|
|
1258
|
+
return undefined;
|
|
1259
|
+
}
|
|
1260
|
+
return validatePhoneNumber(phoneNumber);
|
|
1261
|
+
};
|
|
1262
|
+
|
|
1263
|
+
/**
|
|
1264
|
+
* The PhoneField component is used to enter phone number.
|
|
1265
|
+
* It is a wrapper around the PhoneInput component and the FormGroup component.
|
|
1266
|
+
* It is used to render a phone number field with a label, a tip, a help text, a help addon and an error message.
|
|
1267
|
+
*
|
|
1268
|
+
* @param {string} [label] - The label for the component.
|
|
1269
|
+
* @param {string} [tip] - The tip for the component.
|
|
1270
|
+
* @param {string} [helpText] - The help text for the component.
|
|
1271
|
+
* @param {string} [helpAddon] - The help addon for the component.
|
|
1272
|
+
* @param {string} [errorMessage] - The error message for the component.
|
|
1273
|
+
* @param {string} [defaultValue] - The default value for the component.
|
|
1274
|
+
* @param {boolean} [disabled=false] - Whether the component is disabled or not.
|
|
1275
|
+
* @param {string} [fieldSize="medium"] - The size of the input field.
|
|
1276
|
+
* @param {boolean} [disableAction=false] - Whether the action button is disabled or not.
|
|
1277
|
+
* @returns {JSX.Element} - The PhoneField component.
|
|
1278
|
+
*/
|
|
1279
|
+
const PhoneField = forwardRef(({ label, id, tip, helpText, isInvalid, errorMessage, value, helpAddon, className, defaultValue, dataTestId, name, onBlur, ...rest }, ref) => {
|
|
1280
|
+
const htmlForId = id ? id : "phoneField-" + v4();
|
|
1281
|
+
const [t] = useTranslation();
|
|
1282
|
+
const [innerValue, setInnerValue] = useState(() => {
|
|
1283
|
+
var _a;
|
|
1284
|
+
return (_a = ((value === null || value === void 0 ? void 0 : value.toString()) || (defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString()))) !== null && _a !== void 0 ? _a : undefined;
|
|
1285
|
+
});
|
|
1286
|
+
const [renderAsInvalid, setRenderAsInvalid] = useState((isInvalid === undefined ? Boolean(errorMessage) : isInvalid) ||
|
|
1287
|
+
!!phoneErrorMessage(value === null || value === void 0 ? void 0 : value.toString(), rest.required));
|
|
1288
|
+
const errorType = useMemo(() => phoneErrorMessage(innerValue, rest.required), [innerValue, rest.required]);
|
|
1289
|
+
const error = useMemo(() => {
|
|
1290
|
+
// for the case when a custom error message is provided
|
|
1291
|
+
if (errorMessage) {
|
|
1292
|
+
setRenderAsInvalid(Boolean(errorMessage));
|
|
1293
|
+
return errorMessage;
|
|
1294
|
+
}
|
|
1295
|
+
else if (errorType) {
|
|
1296
|
+
return t(`phoneField.error.${errorType}`);
|
|
1297
|
+
}
|
|
1298
|
+
return errorMessage;
|
|
1299
|
+
}, [errorMessage, errorType, t]);
|
|
1300
|
+
const handleBlur = useCallback(event => {
|
|
1301
|
+
const newValue = event.target.value;
|
|
1302
|
+
setInnerValue(newValue);
|
|
1303
|
+
// for the case when a custom error message is provided
|
|
1304
|
+
if (errorMessage && !phoneErrorMessage(newValue.toString(), rest.required)) {
|
|
1305
|
+
setRenderAsInvalid(Boolean(errorMessage));
|
|
1306
|
+
}
|
|
1307
|
+
else {
|
|
1308
|
+
setRenderAsInvalid(!!phoneErrorMessage(newValue.toString(), rest.required));
|
|
1309
|
+
}
|
|
1310
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
1311
|
+
}, [errorMessage, onBlur, rest.required]);
|
|
1312
|
+
return (jsx(FormGroup, { className: className, dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(PhoneInput, { "aria-labelledby": htmlForId + "-label", dataTestId: dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, name: name, onBlur: handleBlur, ref: ref, value: value, ...rest }) }));
|
|
1313
|
+
});
|
|
1314
|
+
PhoneField.displayName = "PhoneField";
|
|
1315
|
+
|
|
1316
|
+
/**
|
|
1317
|
+
* The PhoneFieldWithController component is a wrapper for the PhoneField component to connect it to react-hook-form.
|
|
1318
|
+
*
|
|
1319
|
+
* @returns {JSX.Element} - The PhoneFieldWithController component.
|
|
1320
|
+
*/
|
|
1321
|
+
const PhoneFieldWithController = forwardRef(({ control, controllerProps, name, value, ...rest }, ref) => {
|
|
1322
|
+
return (jsx(Controller, { control: control, defaultValue: value, name: name, ...controllerProps, render: ({ field }) => jsx(PhoneField, { ...rest, ...field, ref: ref }) }));
|
|
1323
|
+
});
|
|
1324
|
+
PhoneFieldWithController.displayName = "PhoneFieldWithController";
|
|
1127
1325
|
|
|
1128
1326
|
const cvaRadioGroup = cvaMerge(["flex", "gap-2", "flex-col", "items-start"], {
|
|
1129
1327
|
variants: {
|
|
@@ -2435,6 +2633,22 @@ const validateUrlAddress = (url) => {
|
|
|
2435
2633
|
return urlPattern.test(url);
|
|
2436
2634
|
};
|
|
2437
2635
|
|
|
2636
|
+
/**
|
|
2637
|
+
* Validates a url
|
|
2638
|
+
*/
|
|
2639
|
+
const validateUrl = (url, required) => {
|
|
2640
|
+
if (!url && !required) {
|
|
2641
|
+
return undefined;
|
|
2642
|
+
}
|
|
2643
|
+
if (!url && required) {
|
|
2644
|
+
return "REQUIRED";
|
|
2645
|
+
}
|
|
2646
|
+
if (url && isString(url) && validateUrlAddress(url)) {
|
|
2647
|
+
return undefined;
|
|
2648
|
+
}
|
|
2649
|
+
return "INVALID_URL";
|
|
2650
|
+
};
|
|
2651
|
+
|
|
2438
2652
|
/**
|
|
2439
2653
|
* A thin wrapper around the `BaseInput` component for URL input fields.
|
|
2440
2654
|
*
|
|
@@ -2452,14 +2666,23 @@ UrlInput.displayName = "UrlField";
|
|
|
2452
2666
|
* UrlField validates that user enters a valid web address.
|
|
2453
2667
|
*
|
|
2454
2668
|
*/
|
|
2455
|
-
const UrlField = forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, isInvalid = false, value, ...rest }, ref) => {
|
|
2669
|
+
const UrlField = forwardRef(({ label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, isInvalid = false, value, onBlur, ...rest }, ref) => {
|
|
2456
2670
|
const htmlForId = id ? id : "urlField-" + v4();
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2671
|
+
const [t] = useTranslation();
|
|
2672
|
+
const [innerValue, setInnerValue] = useState(() => {
|
|
2673
|
+
var _a;
|
|
2674
|
+
return (_a = ((value === null || value === void 0 ? void 0 : value.toString()) || (defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString()))) !== null && _a !== void 0 ? _a : "";
|
|
2675
|
+
});
|
|
2676
|
+
const [renderAsInvalid, setRenderAsInvalid] = useState(!!errorMessage || (value && isString(value) && !validateUrlAddress(value)) || isInvalid);
|
|
2677
|
+
const errorType = useMemo(() => validateUrl(innerValue !== null && innerValue !== void 0 ? innerValue : "", rest.required), [rest.required, innerValue]);
|
|
2678
|
+
const error = useMemo(() => (errorType ? t(`urlField.error.${errorType}`) : errorMessage), [errorType, errorMessage, t]);
|
|
2679
|
+
const handleBlur = useCallback(event => {
|
|
2680
|
+
const newValue = event.target.value;
|
|
2681
|
+
setInnerValue(newValue);
|
|
2682
|
+
setRenderAsInvalid(!!validateUrl(newValue, rest.required));
|
|
2683
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
2684
|
+
}, [onBlur, rest.required]);
|
|
2685
|
+
return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? error : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(UrlInput, { "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, onBlur: handleBlur, ref: ref, value: value || defaultValue, ...rest, className: className, dataTestId: dataTestId }) }));
|
|
2463
2686
|
});
|
|
2464
2687
|
UrlField.displayName = "UrlField";
|
|
2465
2688
|
|
|
@@ -2571,4 +2794,4 @@ const useZodValidators = () => {
|
|
|
2571
2794
|
*/
|
|
2572
2795
|
setupLibraryTranslations();
|
|
2573
2796
|
|
|
2574
|
-
export { ActionButton, BaseInput, Checkbox, CheckboxField, ColorField, CreatableSelect, CreatableSelectField, DateField, DateInput, DropZone, DropZoneDefaultLabel, EMAIL_REGEX, EmailField, EmailInput, FormFieldSelectAdapter, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PasswordField, PasswordInput, PhoneField, PhoneFieldWithController, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SelectField, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField, Toggle, UploadField, UploadInput, UrlField, UrlInput, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaActionButton, cvaActionContainer, cvaInput, cvaInputAction, cvaInputAddon, cvaInputAddonAfter, cvaInputAddonBefore, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputField, cvaInputPrefix, cvaInputSuffix, cvaSelect, cvaSelectControl, cvaSelectCounter, cvaSelectDynamicTagContainer, cvaSelectIcon, cvaSelectMenu, cvaSelectMenuList, cvaSelectPrefixSuffix, cvaSelectXIcon, getCountryAbbreviation, getOrderedOptions, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isMultiValue, isValidHEXColor, parseSchedule, serializeSchedule, useCustomComponents, useGetPhoneValidationRules, usePhoneInput, useZodValidators, validateEmailAddress, validatePhoneNumber, weekDay };
|
|
2797
|
+
export { ActionButton, BaseInput, Checkbox, CheckboxField, ColorField, CreatableSelect, CreatableSelectField, DateField, DateInput, DropZone, DropZoneDefaultLabel, EMAIL_REGEX, EmailField, EmailInput, FormFieldSelectAdapter, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PasswordField, PasswordInput, PhoneField, PhoneFieldWithController, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SelectField, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField, Toggle, UploadField, UploadInput, UrlField, UrlInput, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaActionButton, cvaActionContainer, cvaInput, cvaInputAction, cvaInputAddon, cvaInputAddonAfter, cvaInputAddonBefore, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputField, cvaInputPrefix, cvaInputSuffix, cvaSelect, cvaSelectControl, cvaSelectCounter, cvaSelectDynamicTagContainer, cvaSelectIcon, cvaSelectMenu, cvaSelectMenuList, cvaSelectPrefixSuffix, cvaSelectXIcon, getCountryAbbreviation, getOrderedOptions, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isMultiValue, isValidHEXColor, parseSchedule, phoneErrorMessage, serializeSchedule, useCustomComponents, useGetPhoneValidationRules, usePhoneInput, useZodValidators, validateEmailAddress, validatePhoneNumber, weekDay };
|
package/package.json
CHANGED
|
@@ -12,3 +12,7 @@ export declare const isInvalidCountryCode: (error: PhoneInputValidationError, re
|
|
|
12
12
|
* Checks if the phone number is valid and required
|
|
13
13
|
*/
|
|
14
14
|
export declare const isInvalidPhoneNumber: (error: PhoneInputValidationError, required?: boolean) => boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Checks if the phone number is valid and returns corresponding error message
|
|
17
|
+
*/
|
|
18
|
+
export declare const phoneErrorMessage: (phoneNumber: string | undefined, required?: boolean | undefined) => PhoneInputValidationError;
|
package/src/translation.d.ts
CHANGED
|
@@ -14,8 +14,8 @@ export declare const translations: TranslationResource<TranslationKeys>;
|
|
|
14
14
|
/**
|
|
15
15
|
* Local useTranslation for this specific library
|
|
16
16
|
*/
|
|
17
|
-
export declare const useTranslation: () => [TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "dropzone.input.title" | "dropzone.label.default" | "field.notEditable.tooltip" | "field.required.asterisk.tooltip" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined">, import("i18next").i18n, boolean] & {
|
|
18
|
-
t: TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "dropzone.input.title" | "dropzone.label.default" | "field.notEditable.tooltip" | "field.required.asterisk.tooltip" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined">;
|
|
17
|
+
export declare const useTranslation: () => [TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "colorField.error.INVALID_HEX_CODE" | "colorField.error.REQUIRED" | "dropzone.input.title" | "dropzone.label.default" | "emailField.error.INVALID_EMAIL" | "emailField.error.REQUIRED" | "field.notEditable.tooltip" | "field.required.asterisk.tooltip" | "numberField.error.GREATER_THAN" | "numberField.error.INVALID_NUMBER" | "numberField.error.LESS_THAN" | "numberField.error.NOT_IN_BETWEEN" | "numberField.error.REQUIRED" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined" | "urlField.error.INVALID_URL" | "urlField.error.REQUIRED">, import("i18next").i18n, boolean] & {
|
|
18
|
+
t: TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "colorField.error.INVALID_HEX_CODE" | "colorField.error.REQUIRED" | "dropzone.input.title" | "dropzone.label.default" | "emailField.error.INVALID_EMAIL" | "emailField.error.REQUIRED" | "field.notEditable.tooltip" | "field.required.asterisk.tooltip" | "numberField.error.GREATER_THAN" | "numberField.error.INVALID_NUMBER" | "numberField.error.LESS_THAN" | "numberField.error.NOT_IN_BETWEEN" | "numberField.error.REQUIRED" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined" | "urlField.error.INVALID_URL" | "urlField.error.REQUIRED">;
|
|
19
19
|
i18n: import("i18next").i18n;
|
|
20
20
|
ready: boolean;
|
|
21
21
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type NumberValidationErrorCode = "REQUIRED" | "INVALID_NUMBER" | "NOT_IN_BETWEEN" | "GREATER_THAN" | "LESS_THAN" | undefined;
|
|
2
|
+
/**
|
|
3
|
+
* Validates a number
|
|
4
|
+
*/
|
|
5
|
+
export declare const validateNumber: (number: string | number | undefined, required?: boolean, min?: number | string, max?: number | string) => NumberValidationErrorCode;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param inputValue - value to check if it is a string
|
|
4
|
+
* @returns {boolean} - true if value is a string
|
|
5
|
+
*/
|
|
6
|
+
export declare const isString: (inputValue: string | number | readonly string[] | undefined) => inputValue is string;
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param inputValue - value to check if it is a number
|
|
10
|
+
* @returns {boolean} - true if value is a number
|
|
11
|
+
*/
|
|
12
|
+
export declare const isNumber: (inputValue: string | number | undefined) => inputValue is number;
|