@okta/odyssey-react-mui 1.9.21 → 1.9.23

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/Autocomplete.js +3 -1
  3. package/dist/Autocomplete.js.map +1 -1
  4. package/dist/CheckboxGroup.js +2 -0
  5. package/dist/CheckboxGroup.js.map +1 -1
  6. package/dist/ErrorMessageList.js +45 -0
  7. package/dist/ErrorMessageList.js.map +1 -0
  8. package/dist/Field.js +6 -4
  9. package/dist/Field.js.map +1 -1
  10. package/dist/FieldComponentProps.js.map +1 -1
  11. package/dist/FieldError.js +9 -2
  12. package/dist/FieldError.js.map +1 -1
  13. package/dist/NativeSelect.js +2 -0
  14. package/dist/NativeSelect.js.map +1 -1
  15. package/dist/PasswordField.js +2 -0
  16. package/dist/PasswordField.js.map +1 -1
  17. package/dist/RadioGroup.js +2 -0
  18. package/dist/RadioGroup.js.map +1 -1
  19. package/dist/Select.js +2 -0
  20. package/dist/Select.js.map +1 -1
  21. package/dist/TextField.js +2 -0
  22. package/dist/TextField.js.map +1 -1
  23. package/dist/labs/VirtualizedAutocomplete.js +2 -0
  24. package/dist/labs/VirtualizedAutocomplete.js.map +1 -1
  25. package/dist/src/Autocomplete.d.ts +2 -2
  26. package/dist/src/Autocomplete.d.ts.map +1 -1
  27. package/dist/src/CheckboxGroup.d.ts +2 -2
  28. package/dist/src/CheckboxGroup.d.ts.map +1 -1
  29. package/dist/src/ErrorMessageList.d.ts +18 -0
  30. package/dist/src/ErrorMessageList.d.ts.map +1 -0
  31. package/dist/src/Field.d.ts +9 -1
  32. package/dist/src/Field.d.ts.map +1 -1
  33. package/dist/src/FieldComponentProps.d.ts +4 -0
  34. package/dist/src/FieldComponentProps.d.ts.map +1 -1
  35. package/dist/src/FieldError.d.ts +3 -2
  36. package/dist/src/FieldError.d.ts.map +1 -1
  37. package/dist/src/NativeSelect.d.ts +1 -1
  38. package/dist/src/NativeSelect.d.ts.map +1 -1
  39. package/dist/src/PasswordField.d.ts.map +1 -1
  40. package/dist/src/RadioGroup.d.ts +2 -2
  41. package/dist/src/RadioGroup.d.ts.map +1 -1
  42. package/dist/src/Select.d.ts +2 -2
  43. package/dist/src/Select.d.ts.map +1 -1
  44. package/dist/src/TextField.d.ts.map +1 -1
  45. package/dist/src/labs/VirtualizedAutocomplete.d.ts +2 -2
  46. package/dist/src/labs/VirtualizedAutocomplete.d.ts.map +1 -1
  47. package/dist/tsconfig.production.tsbuildinfo +1 -1
  48. package/package.json +3 -3
  49. package/src/Autocomplete.tsx +12 -1
  50. package/src/CheckboxGroup.tsx +7 -1
  51. package/src/ErrorMessageList.tsx +51 -0
  52. package/src/Field.tsx +22 -4
  53. package/src/FieldComponentProps.ts +4 -0
  54. package/src/FieldError.tsx +15 -3
  55. package/src/NativeSelect.tsx +3 -0
  56. package/src/PasswordField.tsx +2 -0
  57. package/src/RadioGroup.tsx +9 -1
  58. package/src/Select.tsx +3 -0
  59. package/src/TextField.tsx +2 -0
  60. package/src/labs/VirtualizedAutocomplete.tsx +3 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okta/odyssey-react-mui",
3
- "version": "1.9.21",
3
+ "version": "1.9.23",
4
4
  "description": "React MUI components for Odyssey, Okta's design system",
5
5
  "author": "Okta, Inc.",
6
6
  "license": "Apache-2.0",
@@ -51,7 +51,7 @@
51
51
  "@mui/system": "^5.14.9",
52
52
  "@mui/utils": "^5.11.2",
53
53
  "@mui/x-date-pickers": "^5.0.15",
54
- "@okta/odyssey-design-tokens": "1.9.21",
54
+ "@okta/odyssey-design-tokens": "1.9.23",
55
55
  "date-fns": "^2.30.0",
56
56
  "i18next": "^23.5.1",
57
57
  "material-react-table": "^2.0.2",
@@ -63,5 +63,5 @@
63
63
  "react": ">=17 <19",
64
64
  "react-dom": ">=17 <19"
65
65
  },
66
- "gitHead": "75ee575800d7d9f4921553d752990feca9622bec"
66
+ "gitHead": "e9db91adb36ede5900bf343338ca6c9e38ca3708"
67
67
  }
@@ -162,6 +162,7 @@ export type AutocompleteProps<
162
162
  } & Pick<
163
163
  FieldComponentProps,
164
164
  | "errorMessage"
165
+ | "errorMessageList"
165
166
  | "hint"
166
167
  | "HintLinkComponent"
167
168
  | "id"
@@ -178,6 +179,7 @@ const Autocomplete = <
178
179
  >({
179
180
  defaultValue,
180
181
  errorMessage,
182
+ errorMessageList,
181
183
  hasMultipleChoices,
182
184
  id: idOverride,
183
185
  inputValue,
@@ -244,6 +246,7 @@ const Autocomplete = <
244
246
  ({ InputLabelProps, InputProps, ...params }) => (
245
247
  <Field
246
248
  errorMessage={errorMessage}
249
+ errorMessageList={errorMessageList}
247
250
  fieldType="single"
248
251
  hasVisibleLabel
249
252
  id={InputLabelProps.htmlFor}
@@ -273,7 +276,15 @@ const Autocomplete = <
273
276
  )}
274
277
  />
275
278
  ),
276
- [errorMessage, hint, HintLinkComponent, isOptional, label, nameOverride]
279
+ [
280
+ errorMessage,
281
+ errorMessageList,
282
+ hint,
283
+ HintLinkComponent,
284
+ isOptional,
285
+ label,
286
+ nameOverride,
287
+ ]
277
288
  );
278
289
  const onChange = useCallback<
279
290
  NonNullable<
@@ -35,13 +35,18 @@ export type CheckboxGroupProps = {
35
35
  label: string;
36
36
  } & Pick<
37
37
  FieldComponentProps,
38
- "errorMessage" | "hint" | "HintLinkComponent" | "isDisabled"
38
+ | "errorMessage"
39
+ | "errorMessageList"
40
+ | "hint"
41
+ | "HintLinkComponent"
42
+ | "isDisabled"
39
43
  > &
40
44
  AllowedProps;
41
45
 
42
46
  const CheckboxGroup = ({
43
47
  children,
44
48
  errorMessage,
49
+ errorMessageList,
45
50
  hint,
46
51
  HintLinkComponent,
47
52
  isDisabled,
@@ -68,6 +73,7 @@ const CheckboxGroup = ({
68
73
  return (
69
74
  <Field
70
75
  errorMessage={errorMessage}
76
+ errorMessageList={errorMessageList}
71
77
  fieldType="group"
72
78
  hasVisibleLabel={true}
73
79
  hint={hint}
@@ -0,0 +1,51 @@
1
+ /*!
2
+ * Copyright (c) 2022-present, Okta, Inc. and/or its affiliates. All rights reserved.
3
+ * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
4
+ *
5
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
6
+ * Unless required by applicable law or agreed to in writing, software
7
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
8
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
+ *
10
+ * See the License for the specific language governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { List as MuiList, ListItem as MuiListItem } from "@mui/material";
14
+ import { useOdysseyDesignTokens } from "./OdysseyDesignTokensContext";
15
+ import { memo, useMemo } from "react";
16
+
17
+ export type ErrorMessageListProps = {
18
+ errorMessages: string[];
19
+ };
20
+
21
+ const listItemStyles = {
22
+ display: "list-item",
23
+ paddingInlineStart: 0,
24
+ };
25
+
26
+ const ErrorMessageList = ({ errorMessages }: ErrorMessageListProps) => {
27
+ const odysseyDesignTokens = useOdysseyDesignTokens();
28
+
29
+ const listStyles = useMemo(
30
+ () => ({
31
+ listStyle: "disc",
32
+ paddingInlineStart: odysseyDesignTokens.Spacing4,
33
+ }),
34
+ [odysseyDesignTokens]
35
+ );
36
+
37
+ return (
38
+ <MuiList disablePadding dense sx={listStyles}>
39
+ {errorMessages.map((errorMessage) => (
40
+ <MuiListItem disablePadding dense sx={listItemStyles}>
41
+ {errorMessage}
42
+ </MuiListItem>
43
+ ))}
44
+ </MuiList>
45
+ );
46
+ };
47
+
48
+ const MemoizedErrorMessageList = memo(ErrorMessageList);
49
+ MemoizedErrorMessageList.displayName = "ErrorMessageList";
50
+
51
+ export { MemoizedErrorMessageList as ErrorMessageList };
package/src/Field.tsx CHANGED
@@ -29,6 +29,14 @@ import { useUniqueId } from "./useUniqueId";
29
29
  export const fieldTypeValues = ["single", "group"] as const;
30
30
 
31
31
  export type FieldProps = {
32
+ /**
33
+ * If `error` is not undefined, the `input` will indicate an error.
34
+ */
35
+ errorMessage?: string;
36
+ /**
37
+ * If `error` is not undefined, the `input` will indicate an error.
38
+ */
39
+ errorMessageList?: string[];
32
40
  /**
33
41
  * The field type determines how ARIA components are setup. It's important to use this to denote if you expect only one component (like a text field) or multiple (like a radio group).
34
42
  */
@@ -73,6 +81,7 @@ export type FieldProps = {
73
81
 
74
82
  const Field = ({
75
83
  errorMessage,
84
+ errorMessageList,
76
85
  fieldType,
77
86
  hasVisibleLabel,
78
87
  hint,
@@ -88,6 +97,7 @@ const Field = ({
88
97
  Pick<
89
98
  FieldComponentProps,
90
99
  | "errorMessage"
100
+ | "errorMessageList"
91
101
  | "hint"
92
102
  | "HintLinkComponent"
93
103
  | "id"
@@ -99,7 +109,8 @@ const Field = ({
99
109
 
100
110
  const id = useUniqueId(idOverride);
101
111
  const hintId = hint ? `${id}-hint` : undefined;
102
- const errorMessageElementId = errorMessage ? `${id}-error` : undefined;
112
+ const errorMessageElementId =
113
+ errorMessage || errorMessageList ? `${id}-error` : undefined;
103
114
  const labelElementId = `${id}-label`;
104
115
 
105
116
  const ariaDescribedBy = useMemo(
@@ -118,7 +129,10 @@ const Field = ({
118
129
  <MuiFormControl
119
130
  component={fieldType === "group" ? "fieldset" : "div"}
120
131
  disabled={isDisabled}
121
- error={Boolean(errorMessage)}
132
+ error={
133
+ Boolean(errorMessage) ||
134
+ (Array.isArray(errorMessageList) && errorMessageList.length > 0)
135
+ }
122
136
  role={isRadioGroup ? "radiogroup" : undefined}
123
137
  fullWidth={isFullWidth}
124
138
  >
@@ -152,8 +166,12 @@ const Field = ({
152
166
  labelElementId,
153
167
  })}
154
168
 
155
- {errorMessage && (
156
- <FieldError id={errorMessageElementId} text={errorMessage} />
169
+ {(errorMessage || errorMessageList) && (
170
+ <FieldError
171
+ id={errorMessageElementId}
172
+ message={errorMessage}
173
+ messageList={errorMessageList}
174
+ />
157
175
  )}
158
176
  </MuiFormControl>
159
177
  );
@@ -19,6 +19,10 @@ export type FieldComponentProps = {
19
19
  * If `error` is not undefined, the `input` will indicate an error.
20
20
  */
21
21
  errorMessage?: string;
22
+ /**
23
+ * If `error` is not undefined, the `input` will indicate multiple errors.
24
+ */
25
+ errorMessageList?: string[];
22
26
  /**
23
27
  * The helper text content.
24
28
  */
@@ -14,16 +14,25 @@ import { memo } from "react";
14
14
 
15
15
  import { FormHelperText } from "@mui/material";
16
16
  import { ScreenReaderText } from "./ScreenReaderText";
17
+ import { ErrorMessageList } from "./ErrorMessageList";
17
18
  import { useTranslation } from "react-i18next";
18
19
 
19
20
  import type { AllowedProps } from "./AllowedProps";
21
+ import { Box } from "./Box";
20
22
 
21
23
  export type FieldErrorProps = {
22
24
  id?: string;
23
- text: string;
25
+ message?: string;
26
+ messageList?: string[];
24
27
  } & AllowedProps;
25
28
 
26
- const FieldError = ({ id, testId, text, translate }: FieldErrorProps) => {
29
+ const FieldError = ({
30
+ id,
31
+ message,
32
+ messageList,
33
+ testId,
34
+ translate,
35
+ }: FieldErrorProps) => {
27
36
  const { t } = useTranslation();
28
37
 
29
38
  return (
@@ -31,7 +40,10 @@ const FieldError = ({ id, testId, text, translate }: FieldErrorProps) => {
31
40
  <ScreenReaderText translate={translate}>{`${t(
32
41
  "fielderror.screenreader.text"
33
42
  )}:`}</ScreenReaderText>
34
- {text}
43
+ <Box>
44
+ {message}
45
+ {messageList && <ErrorMessageList errorMessages={messageList} />}
46
+ </Box>
35
47
  </FormHelperText>
36
48
  );
37
49
  };
@@ -82,6 +82,7 @@ export type NativeSelectProps<
82
82
  } & Pick<
83
83
  FieldComponentProps,
84
84
  | "errorMessage"
85
+ | "errorMessageList"
85
86
  | "hint"
86
87
  | "HintLinkComponent"
87
88
  | "id"
@@ -99,6 +100,7 @@ const NativeSelect: ForwardRefWithType = forwardRef(
99
100
  {
100
101
  defaultValue,
101
102
  errorMessage,
103
+ errorMessageList,
102
104
  hasMultipleChoices: hasMultipleChoicesProp,
103
105
  hint,
104
106
  HintLinkComponent,
@@ -185,6 +187,7 @@ const NativeSelect: ForwardRefWithType = forwardRef(
185
187
  return (
186
188
  <Field
187
189
  errorMessage={errorMessage}
190
+ errorMessageList={errorMessageList}
188
191
  fieldType="single"
189
192
  hasVisibleLabel
190
193
  hint={hint}
@@ -86,6 +86,7 @@ const PasswordField = forwardRef<HTMLInputElement, PasswordFieldProps>(
86
86
  autoCompleteType,
87
87
  defaultValue,
88
88
  errorMessage,
89
+ errorMessageList,
89
90
  hasInitialFocus,
90
91
  hint,
91
92
  id: idOverride,
@@ -220,6 +221,7 @@ const PasswordField = forwardRef<HTMLInputElement, PasswordFieldProps>(
220
221
  return (
221
222
  <Field
222
223
  errorMessage={errorMessage}
224
+ errorMessageList={errorMessageList}
223
225
  fieldType="single"
224
226
  hasVisibleLabel
225
227
  hint={hint}
@@ -45,7 +45,13 @@ export type RadioGroupProps = {
45
45
  value?: RadioProps["value"];
46
46
  } & Pick<
47
47
  FieldComponentProps,
48
- "errorMessage" | "hint" | "HintLinkComponent" | "id" | "isDisabled" | "name"
48
+ | "errorMessage"
49
+ | "errorMessageList"
50
+ | "hint"
51
+ | "HintLinkComponent"
52
+ | "id"
53
+ | "isDisabled"
54
+ | "name"
49
55
  > &
50
56
  AllowedProps;
51
57
 
@@ -53,6 +59,7 @@ const RadioGroup = ({
53
59
  children,
54
60
  defaultValue,
55
61
  errorMessage,
62
+ errorMessageList,
56
63
  hint,
57
64
  HintLinkComponent,
58
65
  id: idOverride,
@@ -101,6 +108,7 @@ const RadioGroup = ({
101
108
  return (
102
109
  <Field
103
110
  errorMessage={errorMessage}
111
+ errorMessageList={errorMessageList}
104
112
  fieldType="group"
105
113
  hasVisibleLabel={false}
106
114
  hint={hint}
package/src/Select.tsx CHANGED
@@ -98,6 +98,7 @@ export type SelectProps<
98
98
  } & Pick<
99
99
  FieldComponentProps,
100
100
  | "errorMessage"
101
+ | "errorMessageList"
101
102
  | "hint"
102
103
  | "HintLinkComponent"
103
104
  | "id"
@@ -130,6 +131,7 @@ const Select = <
130
131
  >({
131
132
  defaultValue,
132
133
  errorMessage,
134
+ errorMessageList,
133
135
  hasMultipleChoices: hasMultipleChoicesProp,
134
136
  hint,
135
137
  HintLinkComponent,
@@ -318,6 +320,7 @@ const Select = <
318
320
  return (
319
321
  <Field
320
322
  errorMessage={errorMessage}
323
+ errorMessageList={errorMessageList}
321
324
  fieldType="single"
322
325
  hasVisibleLabel
323
326
  hint={hint}
package/src/TextField.tsx CHANGED
@@ -107,6 +107,7 @@ const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
107
107
  hasInitialFocus,
108
108
  endAdornment,
109
109
  errorMessage,
110
+ errorMessageList,
110
111
  hint,
111
112
  HintLinkComponent,
112
113
  id: idOverride,
@@ -231,6 +232,7 @@ const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
231
232
  return (
232
233
  <Field
233
234
  errorMessage={errorMessage}
235
+ errorMessageList={errorMessageList}
234
236
  fieldType="single"
235
237
  hasVisibleLabel
236
238
  hint={hint}
@@ -168,7 +168,7 @@ export type AutocompleteProps<
168
168
  getIsOptionEqualToValue?: (option: OptionType, value: OptionType) => boolean;
169
169
  } & Pick<
170
170
  FieldComponentProps,
171
- "errorMessage" | "hint" | "id" | "isOptional" | "name"
171
+ "errorMessage" | "errorMessageList" | "hint" | "id" | "isOptional" | "name"
172
172
  > &
173
173
  AllowedProps;
174
174
 
@@ -179,6 +179,7 @@ const VirtualizedAutocomplete = <
179
179
  >({
180
180
  defaultValue,
181
181
  errorMessage,
182
+ errorMessageList,
182
183
  hasMultipleChoices,
183
184
  id: idOverride,
184
185
  inputValue,
@@ -243,6 +244,7 @@ const VirtualizedAutocomplete = <
243
244
  ({ InputLabelProps, InputProps, ...params }) => (
244
245
  <Field
245
246
  errorMessage={errorMessage}
247
+ errorMessageList={errorMessageList}
246
248
  fieldType="single"
247
249
  hasVisibleLabel
248
250
  id={InputLabelProps.htmlFor}