@sats-group/ui-lib 75.8.0 → 75.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sats-group/ui-lib",
3
- "version": "75.8.0",
3
+ "version": "75.10.0",
4
4
  "description": "SATS web user interface library",
5
5
  "engines": {
6
6
  "node": "^18 || ^20",
@@ -163,12 +163,19 @@
163
163
  }
164
164
 
165
165
  &__help {
166
+ display: flex;
167
+ align-items: center;
168
+ gap: spacing.$xs;
166
169
  margin-top: spacing.$xxs;
167
170
  color: light.$on-background-primary-disabled;
168
171
  }
169
172
 
170
173
  &__error {
174
+ display: flex;
175
+ align-items: center;
176
+ gap: spacing.$xs;
171
177
  margin-top: spacing.$xxs;
178
+ color: light.$on-surface-error;
172
179
  }
173
180
 
174
181
  &__asterisk {
@@ -5,6 +5,9 @@ import Text from '../text';
5
5
  import useInputValidation from '../use-input-validation';
6
6
 
7
7
  import { themes, variants, TextInput as Props } from './text-input.types';
8
+ import { useEffect } from 'react';
9
+ import SvgError from '@sats-group/icons/16/error';
10
+ import SvgInfo from '@sats-group/icons/16/info';
8
11
 
9
12
  const RefTextInput = React.forwardRef<HTMLInputElement, Props>(
10
13
  (
@@ -29,8 +32,16 @@ const RefTextInput = React.forwardRef<HTMLInputElement, Props>(
29
32
  },
30
33
  ref,
31
34
  ) => {
32
- const [validationOnChange, onInvalid, error] =
33
- useInputValidation(customErrorMessages);
35
+ const [isError, setIsError] = React.useState(hasError);
36
+ const [validationOnChange, onInvalid, error] = useInputValidation(
37
+ customErrorMessages,
38
+ customErrorMessages ? customErrorMessages.defaultError : undefined,
39
+ isError,
40
+ );
41
+
42
+ useEffect(() => {
43
+ setIsError(hasError);
44
+ }, [hasError]);
34
45
 
35
46
  return (
36
47
  <label
@@ -38,7 +49,7 @@ const RefTextInput = React.forwardRef<HTMLInputElement, Props>(
38
49
  'text-input--theme-dark': theme === themes.dark,
39
50
  'text-input--theme-light': theme === themes.light,
40
51
  'text-input--disabled': disabled,
41
- 'text-input--error': error || hasError,
52
+ 'text-input--error': error || isError,
42
53
  'text-input--moving-label': icon ? false : hasMovingLabel,
43
54
  'text-input--icon': icon,
44
55
  'text-input--variant-small': variant === variants.small,
@@ -57,6 +68,7 @@ const RefTextInput = React.forwardRef<HTMLInputElement, Props>(
57
68
  onChange={e => {
58
69
  onChange(e);
59
70
  validationOnChange(e);
71
+ setIsError(false); // NOTE: We want to reset error state on change to not confuse users.
60
72
  }}
61
73
  // NOTE: Using " " as placeholder for moving label theme to enable using `:placeholder-shown` to determine when to move the label
62
74
  placeholder={
@@ -87,12 +99,14 @@ const RefTextInput = React.forwardRef<HTMLInputElement, Props>(
87
99
 
88
100
  {helpText ? (
89
101
  <div className="text-input__help">
102
+ <SvgInfo />
90
103
  <Text size={Text.sizes.interface}>{helpText}</Text>
91
104
  </div>
92
105
  ) : null}
93
106
  {/* NOTE: This is aria-hidden because reporting of validation errors is handled by the browser */}
94
107
  {error ? (
95
108
  <div aria-hidden="true" className="text-input__error">
109
+ <SvgError />
96
110
  <Text size={Text.sizes.interface}>{error}</Text>
97
111
  </div>
98
112
  ) : null}
@@ -1,4 +1,4 @@
1
- import { useRef, useState } from 'react';
1
+ import { useRef, useState, useEffect } from 'react';
2
2
 
3
3
  import { Messages } from './use-input-validation.types';
4
4
 
@@ -18,14 +18,28 @@ const getCustomMessage = (validity: ValidityState, messages: Messages) => {
18
18
  if (validity.tooShort) return messages.tooShort;
19
19
  if (validity.typeMismatch) return messages.typeMismatch;
20
20
  if (validity.valueMissing) return messages.valueMissing;
21
+ return undefined;
21
22
  };
22
23
 
23
- export default (customMessages: Messages = {}) => {
24
+ export default (
25
+ customMessages: Messages = {},
26
+ defaultError?: string,
27
+ isError?: boolean,
28
+ ) => {
24
29
  const [error, setError] = useState<string | undefined>();
25
30
  const validationEnabled = useRef(false);
26
31
 
32
+ useEffect(() => {
33
+ if (isError && defaultError) {
34
+ setError(defaultError);
35
+ } else {
36
+ setError(undefined);
37
+ }
38
+ }, [isError, defaultError]);
39
+
27
40
  const onInvalid = (e: React.FormEvent<SupportedElement>) => {
28
41
  validationEnabled.current = true;
42
+
29
43
  const message = getCustomMessage(
30
44
  (e.target as HTMLInputElement).validity,
31
45
  customMessages,
@@ -34,7 +48,6 @@ export default (customMessages: Messages = {}) => {
34
48
  };
35
49
 
36
50
  const onChange = (e: React.ChangeEvent<SupportedElement>) => {
37
- if (!validationEnabled.current) return;
38
51
  const message = getCustomMessage(e.target.validity, customMessages);
39
52
  setError(message || e.target?.validationMessage || undefined);
40
53
  };
@@ -1,6 +1,7 @@
1
1
  export type Messages = {
2
2
  badInput?: string;
3
3
  customError?: string;
4
+ defaultError?: string;
4
5
  patternMismatch?: string;
5
6
  rangeOverflow?: string;
6
7
  rangeUnderflow?: string;