@trackunit/react-form-components 2.4.11 → 2.4.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs.js CHANGED
@@ -3955,7 +3955,7 @@ const validateNumber = (number, required = false, min, max) => {
3955
3955
  * };
3956
3956
  * ```
3957
3957
  */
3958
- const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid = undefined, maxLength, className, value, "data-testid": dataTestId, defaultValue, onBlur, onChange, ref, required = false, ...rest }) => {
3958
+ const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid = undefined, isWarning = false, maxLength, className, value, "data-testid": dataTestId, defaultValue, onBlur, onChange, ref, required = false, ...rest }) => {
3959
3959
  const htmlForId = id ? id : `numberField-${sharedUtils.uuidv4()}`;
3960
3960
  const [t] = useTranslation();
3961
3961
  const [innerValue, setInnerValue] = react.useState(() => {
@@ -3975,10 +3975,15 @@ const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInva
3975
3975
  return errorMessage;
3976
3976
  }, [errorMessage, errorType, rest.max, rest.min, t]);
3977
3977
  react.useEffect(() => {
3978
- if (errorMessage) {
3978
+ // A controlled isInvalid must be able to lower the invalid state too, not just raise it —
3979
+ // otherwise a consumer switching from invalid to warning keeps the error treatment until blur.
3980
+ if (isInvalid !== undefined) {
3981
+ setRenderAsInvalid(isInvalid);
3982
+ }
3983
+ else if (errorMessage) {
3979
3984
  setRenderAsInvalid(Boolean(errorMessage));
3980
3985
  }
3981
- }, [errorMessage]);
3986
+ }, [errorMessage, isInvalid]);
3982
3987
  const handleBlur = react.useCallback(event => {
3983
3988
  const newValue = event.target.value;
3984
3989
  setInnerValue(newValue.toString());
@@ -3997,7 +4002,7 @@ const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInva
3997
4002
  onChange(event);
3998
4003
  }
3999
4004
  }, [onChange]);
4000
- return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(NumberBaseInput, { "aria-labelledby": `${htmlForId}-label`, id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, onBlur: handleBlur, onChange: handleChange, ref: ref, required: required, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
4005
+ return (jsxRuntime.jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, isWarning: isWarning, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsxRuntime.jsx(NumberBaseInput, { "aria-labelledby": `${htmlForId}-label`, id: htmlForId, isInvalid: renderAsInvalid, isWarning: isWarning, maxLength: maxLength, onBlur: handleBlur, onChange: handleChange, ref: ref, required: required, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
4001
4006
  };
4002
4007
  NumberField.displayName = "NumberField";
4003
4008
 
package/index.esm.js CHANGED
@@ -3954,7 +3954,7 @@ const validateNumber = (number, required = false, min, max) => {
3954
3954
  * };
3955
3955
  * ```
3956
3956
  */
3957
- const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid = undefined, maxLength, className, value, "data-testid": dataTestId, defaultValue, onBlur, onChange, ref, required = false, ...rest }) => {
3957
+ const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid = undefined, isWarning = false, maxLength, className, value, "data-testid": dataTestId, defaultValue, onBlur, onChange, ref, required = false, ...rest }) => {
3958
3958
  const htmlForId = id ? id : `numberField-${uuidv4()}`;
3959
3959
  const [t] = useTranslation();
3960
3960
  const [innerValue, setInnerValue] = useState(() => {
@@ -3974,10 +3974,15 @@ const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInva
3974
3974
  return errorMessage;
3975
3975
  }, [errorMessage, errorType, rest.max, rest.min, t]);
3976
3976
  useEffect(() => {
3977
- if (errorMessage) {
3977
+ // A controlled isInvalid must be able to lower the invalid state too, not just raise it —
3978
+ // otherwise a consumer switching from invalid to warning keeps the error treatment until blur.
3979
+ if (isInvalid !== undefined) {
3980
+ setRenderAsInvalid(isInvalid);
3981
+ }
3982
+ else if (errorMessage) {
3978
3983
  setRenderAsInvalid(Boolean(errorMessage));
3979
3984
  }
3980
- }, [errorMessage]);
3985
+ }, [errorMessage, isInvalid]);
3981
3986
  const handleBlur = useCallback(event => {
3982
3987
  const newValue = event.target.value;
3983
3988
  setInnerValue(newValue.toString());
@@ -3996,7 +4001,7 @@ const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInva
3996
4001
  onChange(event);
3997
4002
  }
3998
4003
  }, [onChange]);
3999
- return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(NumberBaseInput, { "aria-labelledby": `${htmlForId}-label`, id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, onBlur: handleBlur, onChange: handleChange, ref: ref, required: required, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
4004
+ return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && error) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, isWarning: isWarning, label: label, required: required ? !(Boolean(rest.disabled) || Boolean(rest.readOnly)) : false, tip: tip, children: jsx(NumberBaseInput, { "aria-labelledby": `${htmlForId}-label`, id: htmlForId, isInvalid: renderAsInvalid, isWarning: isWarning, maxLength: maxLength, onBlur: handleBlur, onChange: handleChange, ref: ref, required: required, value: value, ...rest, className: className, "data-testid": dataTestId }) }));
4000
4005
  };
4001
4006
  NumberField.displayName = "NumberField";
4002
4007
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-form-components",
3
- "version": "2.4.11",
3
+ "version": "2.4.13",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "migrations": "./migrations.json",
@@ -10,17 +10,17 @@
10
10
  "dependencies": {
11
11
  "react-calendar": "^6.0.0",
12
12
  "react-select": "^5.10.2",
13
- "@trackunit/date-and-time-utils": "1.14.6",
13
+ "@trackunit/date-and-time-utils": "1.14.8",
14
14
  "usehooks-ts": "^3.1.0",
15
15
  "libphonenumber-js": "^1.13.6",
16
16
  "zod": "^3.25.76",
17
17
  "tailwind-merge": "^2.0.0",
18
- "@trackunit/css-class-variance-utilities": "1.14.5",
19
- "@trackunit/react-components": "2.7.0",
20
- "@trackunit/ui-icons": "1.14.5",
21
- "@trackunit/shared-utils": "1.16.5",
22
- "@trackunit/ui-design-tokens": "1.14.5",
23
- "@trackunit/i18n-library-translation": "2.3.7",
18
+ "@trackunit/css-class-variance-utilities": "1.14.7",
19
+ "@trackunit/react-components": "2.7.2",
20
+ "@trackunit/ui-icons": "1.14.7",
21
+ "@trackunit/shared-utils": "1.16.7",
22
+ "@trackunit/ui-design-tokens": "1.14.7",
23
+ "@trackunit/i18n-library-translation": "2.3.9",
24
24
  "string-ts": "^2.0.0",
25
25
  "es-toolkit": "^1.39.10"
26
26
  },
@@ -59,7 +59,7 @@ export interface NumberFieldProps extends NumberBaseInputProps, FormGroupExposed
59
59
  * ```
60
60
  */
61
61
  export declare const NumberField: {
62
- ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid, maxLength, className, value, "data-testid": dataTestId, defaultValue, onBlur, onChange, ref, required, ...rest }: NumberFieldProps): import("react/jsx-runtime").JSX.Element;
62
+ ({ label, id, tip, helpText, errorMessage, helpAddon, isInvalid, isWarning, maxLength, className, value, "data-testid": dataTestId, defaultValue, onBlur, onChange, ref, required, ...rest }: NumberFieldProps): import("react/jsx-runtime").JSX.Element;
63
63
  displayName: string;
64
64
  };
65
65
  export {};