@okta/odyssey-react-mui 1.0.2 → 1.1.1

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 (204) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +1 -1
  3. package/dist/Autocomplete.js +9 -3
  4. package/dist/Autocomplete.js.map +1 -1
  5. package/dist/Banner.js +3 -1
  6. package/dist/Banner.js.map +1 -1
  7. package/dist/Box.js +8 -4
  8. package/dist/Box.js.map +1 -1
  9. package/dist/Button.js +3 -1
  10. package/dist/Button.js.map +1 -1
  11. package/dist/Callout.js +2 -0
  12. package/dist/Callout.js.map +1 -1
  13. package/dist/Checkbox.js +6 -2
  14. package/dist/Checkbox.js.map +1 -1
  15. package/dist/CheckboxGroup.js +5 -7
  16. package/dist/CheckboxGroup.js.map +1 -1
  17. package/dist/CircularProgress.js +2 -0
  18. package/dist/CircularProgress.js.map +1 -1
  19. package/dist/Dialog.js +2 -0
  20. package/dist/Dialog.js.map +1 -1
  21. package/dist/Field.js.map +1 -1
  22. package/dist/FieldError.js +2 -0
  23. package/dist/FieldError.js.map +1 -1
  24. package/dist/FieldHint.js +2 -0
  25. package/dist/FieldHint.js.map +1 -1
  26. package/dist/FieldLabel.js +3 -1
  27. package/dist/FieldLabel.js.map +1 -1
  28. package/dist/Fieldset.js +3 -1
  29. package/dist/Fieldset.js.map +1 -1
  30. package/dist/Form.js +5 -3
  31. package/dist/Form.js.map +1 -1
  32. package/dist/Link.js +3 -1
  33. package/dist/Link.js.map +1 -1
  34. package/dist/MenuButton.js +8 -2
  35. package/dist/MenuButton.js.map +1 -1
  36. package/dist/MenuItem.js +6 -2
  37. package/dist/MenuItem.js.map +1 -1
  38. package/dist/NativeSelect.js +3 -1
  39. package/dist/NativeSelect.js.map +1 -1
  40. package/dist/OdysseyI18n.js +2 -0
  41. package/dist/OdysseyI18n.js.map +1 -1
  42. package/dist/OdysseyProvider.js +7 -4
  43. package/dist/OdysseyProvider.js.map +1 -1
  44. package/dist/OdysseyThemeProvider.js +3 -6
  45. package/dist/OdysseyThemeProvider.js.map +1 -1
  46. package/dist/OdysseyTranslationProvider.types.js +1 -1
  47. package/dist/OdysseyTranslationProvider.types.js.map +1 -1
  48. package/dist/PasswordField.js +9 -8
  49. package/dist/PasswordField.js.map +1 -1
  50. package/dist/Radio.js +2 -0
  51. package/dist/Radio.js.map +1 -1
  52. package/dist/RadioGroup.js +5 -2
  53. package/dist/RadioGroup.js.map +1 -1
  54. package/dist/SearchField.js +11 -10
  55. package/dist/SearchField.js.map +1 -1
  56. package/dist/Select.js +8 -5
  57. package/dist/Select.js.map +1 -1
  58. package/dist/SeleniumProps.js +2 -0
  59. package/dist/SeleniumProps.js.map +1 -0
  60. package/dist/Status.js +4 -2
  61. package/dist/Status.js.map +1 -1
  62. package/dist/Tabs.js +11 -4
  63. package/dist/Tabs.js.map +1 -1
  64. package/dist/Tag.js +4 -2
  65. package/dist/Tag.js.map +1 -1
  66. package/dist/TagList.js +3 -1
  67. package/dist/TagList.js.map +1 -1
  68. package/dist/TextField.js +6 -2
  69. package/dist/TextField.js.map +1 -1
  70. package/dist/Toast.js +2 -0
  71. package/dist/Toast.js.map +1 -1
  72. package/dist/Tooltip.js +2 -0
  73. package/dist/Tooltip.js.map +1 -1
  74. package/dist/Typography.js +71 -37
  75. package/dist/Typography.js.map +1 -1
  76. package/dist/labs/DatePicker.js +4 -2
  77. package/dist/labs/DatePicker.js.map +1 -1
  78. package/dist/labs/PaginatedTable.js +6 -4
  79. package/dist/labs/PaginatedTable.js.map +1 -1
  80. package/dist/labs/StaticTable.js +9 -4
  81. package/dist/labs/StaticTable.js.map +1 -1
  82. package/dist/src/Autocomplete.d.ts +7 -2
  83. package/dist/src/Autocomplete.d.ts.map +1 -1
  84. package/dist/src/Banner.d.ts +3 -2
  85. package/dist/src/Banner.d.ts.map +1 -1
  86. package/dist/src/Box.d.ts +9 -2
  87. package/dist/src/Box.d.ts.map +1 -1
  88. package/dist/src/Button.d.ts +3 -2
  89. package/dist/src/Button.d.ts.map +1 -1
  90. package/dist/src/Callout.d.ts +3 -2
  91. package/dist/src/Callout.d.ts.map +1 -1
  92. package/dist/src/Checkbox.d.ts +8 -3
  93. package/dist/src/Checkbox.d.ts.map +1 -1
  94. package/dist/src/CheckboxGroup.d.ts +3 -6
  95. package/dist/src/CheckboxGroup.d.ts.map +1 -1
  96. package/dist/src/CircularProgress.d.ts +3 -2
  97. package/dist/src/CircularProgress.d.ts.map +1 -1
  98. package/dist/src/Dialog.d.ts +3 -2
  99. package/dist/src/Dialog.d.ts.map +1 -1
  100. package/dist/src/Field.d.ts +2 -1
  101. package/dist/src/Field.d.ts.map +1 -1
  102. package/dist/src/FieldError.d.ts +3 -2
  103. package/dist/src/FieldError.d.ts.map +1 -1
  104. package/dist/src/FieldHint.d.ts +3 -2
  105. package/dist/src/FieldHint.d.ts.map +1 -1
  106. package/dist/src/FieldLabel.d.ts +3 -2
  107. package/dist/src/FieldLabel.d.ts.map +1 -1
  108. package/dist/src/Fieldset.d.ts +3 -2
  109. package/dist/src/Fieldset.d.ts.map +1 -1
  110. package/dist/src/Form.d.ts +3 -2
  111. package/dist/src/Form.d.ts.map +1 -1
  112. package/dist/src/Link.d.ts +3 -2
  113. package/dist/src/Link.d.ts.map +1 -1
  114. package/dist/src/MenuButton.d.ts +12 -3
  115. package/dist/src/MenuButton.d.ts.map +1 -1
  116. package/dist/src/MenuItem.d.ts +5 -4
  117. package/dist/src/MenuItem.d.ts.map +1 -1
  118. package/dist/src/NativeSelect.d.ts +56 -2
  119. package/dist/src/NativeSelect.d.ts.map +1 -1
  120. package/dist/src/OdysseyI18n.d.ts +15 -0
  121. package/dist/src/OdysseyI18n.d.ts.map +1 -1
  122. package/dist/src/OdysseyProvider.d.ts.map +1 -1
  123. package/dist/src/OdysseyThemeProvider.d.ts.map +1 -1
  124. package/dist/src/OdysseyTranslationProvider.types.d.ts +1 -1
  125. package/dist/src/OdysseyTranslationProvider.types.d.ts.map +1 -1
  126. package/dist/src/PasswordField.d.ts +70 -2
  127. package/dist/src/PasswordField.d.ts.map +1 -1
  128. package/dist/src/Radio.d.ts +3 -2
  129. package/dist/src/Radio.d.ts.map +1 -1
  130. package/dist/src/RadioGroup.d.ts +8 -3
  131. package/dist/src/RadioGroup.d.ts.map +1 -1
  132. package/dist/src/SearchField.d.ts +58 -2
  133. package/dist/src/SearchField.d.ts.map +1 -1
  134. package/dist/src/Select.d.ts +60 -2
  135. package/dist/src/Select.d.ts.map +1 -1
  136. package/dist/src/SeleniumProps.d.ts +20 -0
  137. package/dist/src/SeleniumProps.d.ts.map +1 -0
  138. package/dist/src/Status.d.ts +3 -2
  139. package/dist/src/Status.d.ts.map +1 -1
  140. package/dist/src/Tabs.d.ts +9 -3
  141. package/dist/src/Tabs.d.ts.map +1 -1
  142. package/dist/src/Tag.d.ts +3 -2
  143. package/dist/src/Tag.d.ts.map +1 -1
  144. package/dist/src/TagList.d.ts +3 -2
  145. package/dist/src/TagList.d.ts.map +1 -1
  146. package/dist/src/TextField.d.ts +86 -2
  147. package/dist/src/TextField.d.ts.map +1 -1
  148. package/dist/src/Toast.d.ts +3 -2
  149. package/dist/src/Toast.d.ts.map +1 -1
  150. package/dist/src/Tooltip.d.ts +3 -2
  151. package/dist/src/Tooltip.d.ts.map +1 -1
  152. package/dist/src/Typography.d.ts +14 -45
  153. package/dist/src/Typography.d.ts.map +1 -1
  154. package/dist/src/labs/DatePicker.d.ts +5 -1
  155. package/dist/src/labs/DatePicker.d.ts.map +1 -1
  156. package/dist/src/labs/PaginatedTable.d.ts.map +1 -1
  157. package/dist/src/labs/StaticTable.d.ts.map +1 -1
  158. package/dist/src/theme/components.d.ts.map +1 -1
  159. package/dist/theme/components.js +38 -10
  160. package/dist/theme/components.js.map +1 -1
  161. package/dist/tsconfig.production.tsbuildinfo +1 -1
  162. package/package.json +6 -5
  163. package/src/Autocomplete.tsx +13 -2
  164. package/src/Banner.tsx +11 -2
  165. package/src/Box.tsx +11 -5
  166. package/src/Button.tsx +6 -1
  167. package/src/Callout.tsx +5 -3
  168. package/src/Checkbox.tsx +14 -4
  169. package/src/CheckboxGroup.tsx +6 -10
  170. package/src/CircularProgress.tsx +5 -1
  171. package/src/Dialog.tsx +5 -2
  172. package/src/Field.tsx +2 -0
  173. package/src/FieldError.tsx +5 -3
  174. package/src/FieldHint.tsx +9 -3
  175. package/src/FieldLabel.tsx +5 -3
  176. package/src/Fieldset.tsx +4 -1
  177. package/src/Form.tsx +7 -4
  178. package/src/Link.tsx +18 -3
  179. package/src/MenuButton.tsx +33 -4
  180. package/src/MenuItem.tsx +11 -6
  181. package/src/NativeSelect.tsx +7 -2
  182. package/src/OdysseyI18n.ts +2 -0
  183. package/src/OdysseyProvider.tsx +9 -6
  184. package/src/OdysseyThemeProvider.tsx +4 -6
  185. package/src/OdysseyTranslationProvider.types.ts +1 -0
  186. package/src/PasswordField.tsx +18 -10
  187. package/src/Radio.tsx +5 -1
  188. package/src/RadioGroup.tsx +12 -4
  189. package/src/SearchField.tsx +23 -15
  190. package/src/Select.tsx +16 -6
  191. package/src/SeleniumProps.ts +20 -0
  192. package/src/Status.tsx +15 -3
  193. package/src/Tabs.tsx +18 -4
  194. package/src/Tag.tsx +12 -3
  195. package/src/TagList.tsx +4 -2
  196. package/src/TextField.tsx +14 -2
  197. package/src/Toast.tsx +4 -1
  198. package/src/Tooltip.tsx +4 -1
  199. package/src/Typography.tsx +76 -28
  200. package/src/labs/DatePicker.tsx +15 -7
  201. package/src/labs/PaginatedTable.tsx +12 -3
  202. package/src/labs/README.md +2 -2
  203. package/src/labs/StaticTable.tsx +13 -3
  204. package/src/theme/components.tsx +43 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okta/odyssey-react-mui",
3
- "version": "1.0.2",
3
+ "version": "1.1.1",
4
4
  "description": "React MUI components for Odyssey, Okta's design system",
5
5
  "author": "Okta, Inc.",
6
6
  "license": "Apache-2.0",
@@ -43,12 +43,15 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@emotion/cache": "^11.10.5",
46
+ "@emotion/react": "^11.11.1",
47
+ "@emotion/styled": "^11.11.0",
46
48
  "@mui/icons-material": "^5.11.0",
47
49
  "@mui/lab": "^5.0.0-alpha.117",
48
50
  "@mui/material": "^5.12.3",
51
+ "@mui/system": "^5.14.9",
49
52
  "@mui/utils": "^5.11.2",
50
53
  "@mui/x-date-pickers": "^5.0.15",
51
- "@okta/odyssey-design-tokens": "1.0.2",
54
+ "@okta/odyssey-design-tokens": "1.1.1",
52
55
  "date-fns": "^2.30.0",
53
56
  "i18next": "^22.4.15",
54
57
  "material-react-table": "^1.14.0",
@@ -57,10 +60,8 @@
57
60
  "word-wrap": "~1.2.5"
58
61
  },
59
62
  "peerDependencies": {
60
- "@emotion/react": "^11",
61
- "@emotion/styled": "^11",
62
63
  "react": ">=17 <19",
63
64
  "react-dom": ">=17 <19"
64
65
  },
65
- "gitHead": "06d0b602d3bf239b43a739dd3a63ec2fb7f0ba01"
66
+ "gitHead": "3cf42aaed1fa433ee7a0e4b10112f98544f28f56"
66
67
  }
@@ -18,6 +18,7 @@ import {
18
18
  import { memo, useCallback } from "react";
19
19
 
20
20
  import { Field } from "./Field";
21
+ import type { SeleniumProps } from "./SeleniumProps";
21
22
 
22
23
  export type AutocompleteProps<
23
24
  OptionType,
@@ -64,6 +65,10 @@ export type AutocompleteProps<
64
65
  undefined,
65
66
  IsCustomValueAllowed
66
67
  >["loading"];
68
+ /**
69
+ * If `true`, the `input` element is not required.
70
+ */
71
+ isOptional?: boolean;
67
72
  /**
68
73
  * Makes the Autocomplete input read-only
69
74
  */
@@ -113,7 +118,7 @@ export type AutocompleteProps<
113
118
  undefined,
114
119
  IsCustomValueAllowed
115
120
  >["value"];
116
- };
121
+ } & SeleniumProps;
117
122
 
118
123
  const Autocomplete = <
119
124
  OptionType,
@@ -124,6 +129,7 @@ const Autocomplete = <
124
129
  isCustomValueAllowed,
125
130
  isDisabled,
126
131
  isLoading,
132
+ isOptional = false,
127
133
  isReadOnly,
128
134
  hint,
129
135
  label,
@@ -131,6 +137,7 @@ const Autocomplete = <
131
137
  onInputChange,
132
138
  options,
133
139
  value,
140
+ testId,
134
141
  }: AutocompleteProps<OptionType, HasMultipleChoices, IsCustomValueAllowed>) => {
135
142
  const renderInput = useCallback(
136
143
  ({ InputLabelProps, InputProps, ...params }) => (
@@ -140,23 +147,27 @@ const Autocomplete = <
140
147
  id={InputLabelProps.htmlFor}
141
148
  hint={hint}
142
149
  label={label}
150
+ isOptional={isOptional}
143
151
  renderFieldComponent={({ ariaDescribedBy, id }) => (
144
152
  <InputBase
145
153
  {...params}
146
154
  {...InputProps}
147
155
  aria-describedby={ariaDescribedBy}
148
156
  id={id}
157
+ required={!isOptional}
149
158
  />
150
159
  )}
151
160
  />
152
161
  ),
153
- [hint, label]
162
+ [hint, isOptional, label]
154
163
  );
155
164
 
156
165
  return (
157
166
  <MuiAutocomplete
158
167
  // AutoComplete is wrapped in a div within MUI which does not get the disabled attr. So this aria-disabled gets set in the div
159
168
  aria-disabled={isDisabled}
169
+ data-se={testId}
170
+ disableCloseOnSelect={hasMultipleChoices}
160
171
  disabled={isDisabled}
161
172
  freeSolo={isCustomValueAllowed}
162
173
  loading={isLoading}
package/src/Banner.tsx CHANGED
@@ -16,6 +16,8 @@ import { ScreenReaderText } from "./ScreenReaderText";
16
16
  import { memo } from "react";
17
17
  import { useTranslation } from "react-i18next";
18
18
 
19
+ import type { SeleniumProps } from "./SeleniumProps";
20
+
19
21
  export const bannerRoleValues = ["status", "alert"] as const;
20
22
  export const bannerSeverityValues: AlertColor[] = [
21
23
  "success",
@@ -54,7 +56,7 @@ export type BannerProps = {
54
56
  * The text content of the alert
55
57
  */
56
58
  text: string;
57
- };
59
+ } & SeleniumProps;
58
60
 
59
61
  const Banner = ({
60
62
  linkUrl,
@@ -63,11 +65,18 @@ const Banner = ({
63
65
  role,
64
66
  severity,
65
67
  text,
68
+ testId,
66
69
  }: BannerProps) => {
67
70
  const { t } = useTranslation();
68
71
 
69
72
  return (
70
- <Alert onClose={onClose} role={role} severity={severity} variant="banner">
73
+ <Alert
74
+ data-se={testId}
75
+ onClose={onClose}
76
+ role={role}
77
+ severity={severity}
78
+ variant="banner"
79
+ >
71
80
  <ScreenReaderText>{t(`severity.${severity}`)}:</ScreenReaderText>
72
81
  <AlertTitle>{text}</AlertTitle>
73
82
  {linkUrl && (
package/src/Box.tsx CHANGED
@@ -11,25 +11,31 @@
11
11
  */
12
12
 
13
13
  import { Box as MuiBox, BoxProps as MuiBoxProps } from "@mui/material";
14
- import { ReactNode, forwardRef } from "react";
14
+ import { ReactNode, forwardRef, memo } from "react";
15
+
16
+ import type { SeleniumProps } from "./SeleniumProps";
15
17
 
16
18
  export type BoxProps = {
17
19
  children?: ReactNode;
18
20
  component?: MuiBoxProps["component"];
19
21
  id?: MuiBoxProps["id"];
20
22
  sx?: MuiBoxProps["sx"];
21
- };
23
+ } & SeleniumProps;
22
24
 
23
- export const Box = forwardRef<HTMLElement, BoxProps>(
24
- ({ children, component, id, sx }, ref) => (
25
+ const Box = forwardRef<HTMLElement, BoxProps>(
26
+ ({ children, component, id, sx, testId }, ref) => (
25
27
  <MuiBox
26
28
  ref={ref}
27
29
  children={children}
28
30
  component={component}
31
+ data-se={testId}
29
32
  id={id}
30
33
  sx={sx}
31
34
  />
32
35
  )
33
36
  );
34
37
 
35
- Box.displayName = "Box";
38
+ const MemoizedBox = memo(Box);
39
+ MemoizedBox.displayName = "Box";
40
+
41
+ export { MemoizedBox as Box };
package/src/Button.tsx CHANGED
@@ -16,6 +16,7 @@ import { memo, ReactElement, useCallback } from "react";
16
16
 
17
17
  import { MuiPropsContext, useMuiProps } from "./MuiPropsContext";
18
18
  import { Tooltip } from "./Tooltip";
19
+ import type { SeleniumProps } from "./SeleniumProps";
19
20
 
20
21
  export const buttonSizeValues = ["small", "medium", "large"] as const;
21
22
  export const buttonTypeValues = ["button", "submit", "reset"] as const;
@@ -100,7 +101,8 @@ export type ButtonProps = {
100
101
  label?: "" | undefined;
101
102
  startIcon?: ReactElement;
102
103
  }
103
- );
104
+ ) &
105
+ SeleniumProps;
104
106
 
105
107
  const Button = ({
106
108
  ariaDescribedBy,
@@ -114,6 +116,7 @@ const Button = ({
114
116
  onClick,
115
117
  size = "medium",
116
118
  startIcon,
119
+ testId,
117
120
  tooltipText,
118
121
  type = "button",
119
122
  variant,
@@ -127,6 +130,7 @@ const Button = ({
127
130
  aria-label={ariaLabel}
128
131
  aria-labelledby={ariaLabelledBy}
129
132
  aria-describedby={ariaDescribedBy}
133
+ data-se={testId}
130
134
  disabled={isDisabled}
131
135
  endIcon={endIcon}
132
136
  fullWidth={isFullWidth}
@@ -152,6 +156,7 @@ const Button = ({
152
156
  onClick,
153
157
  size,
154
158
  startIcon,
159
+ testId,
155
160
  type,
156
161
  variant,
157
162
  ]
package/src/Callout.tsx CHANGED
@@ -15,6 +15,8 @@ import { Alert, AlertTitle, Box } from "@mui/material";
15
15
  import { ScreenReaderText } from "./ScreenReaderText";
16
16
  import { useTranslation } from "react-i18next";
17
17
 
18
+ import type { SeleniumProps } from "./SeleniumProps";
19
+
18
20
  export const calloutRoleValues = ["status", "alert"] as const;
19
21
  export const calloutSeverityValues = [
20
22
  "success",
@@ -42,13 +44,13 @@ export type CalloutProps = {
42
44
  * The title of the Callout
43
45
  */
44
46
  title?: string;
45
- };
47
+ } & SeleniumProps;
46
48
 
47
- const Callout = ({ children, role, severity, title }: CalloutProps) => {
49
+ const Callout = ({ children, role, severity, testId, title }: CalloutProps) => {
48
50
  const { t } = useTranslation();
49
51
 
50
52
  return (
51
- <Alert role={role} severity={severity} variant="callout">
53
+ <Alert data-se={testId} role={role} severity={severity} variant="callout">
52
54
  <ScreenReaderText>{t(`severity.${severity}`)}: </ScreenReaderText>
53
55
  {title && <AlertTitle>{title}</AlertTitle>}
54
56
  <Box component="div">{children}</Box>
package/src/Checkbox.tsx CHANGED
@@ -19,6 +19,8 @@ import { Typography } from "./Typography";
19
19
  import { memo, useCallback, useMemo, useState } from "react";
20
20
  import { useTranslation } from "react-i18next";
21
21
 
22
+ import type { SeleniumProps } from "./SeleniumProps";
23
+
22
24
  export const checkboxValidityValues = ["valid", "invalid", "inherit"] as const;
23
25
 
24
26
  export type CheckboxProps = {
@@ -30,6 +32,10 @@ export type CheckboxProps = {
30
32
  * The ID of the element that labels the Checkbox
31
33
  */
32
34
  ariaLabelledBy?: string;
35
+ /**
36
+ * The id of the `input` element.
37
+ */
38
+ id?: string;
33
39
  /**
34
40
  * Determines whether the Checkbox is checked
35
41
  */
@@ -51,7 +57,7 @@ export type CheckboxProps = {
51
57
  */
52
58
  label?: string;
53
59
  /**
54
- * The name attribute of the Checkbox
60
+ * The name of the `input` element. Defaults to the `id` if not set.
55
61
  */
56
62
  name?: string;
57
63
  /**
@@ -66,18 +72,20 @@ export type CheckboxProps = {
66
72
  * The value attribute of the Checkbox
67
73
  */
68
74
  value?: string;
69
- };
75
+ } & SeleniumProps;
70
76
 
71
77
  const Checkbox = ({
72
78
  ariaLabel,
73
79
  ariaLabelledBy,
80
+ id: idOverride,
74
81
  isDefaultChecked = false,
75
82
  isDisabled,
76
83
  isIndeterminate,
77
84
  isRequired,
78
85
  label: labelProp,
79
- name,
86
+ name: nameOverride,
80
87
  onChange: onChangeProp,
88
+ testId,
81
89
  validity = "inherit",
82
90
  value,
83
91
  }: CheckboxProps) => {
@@ -122,9 +130,11 @@ const Checkbox = ({
122
130
  control={
123
131
  <MuiCheckbox indeterminate={isIndeterminate} required={isRequired} />
124
132
  }
133
+ data-se={testId}
125
134
  disabled={isDisabled}
135
+ id={idOverride}
126
136
  label={label}
127
- name={name}
137
+ name={nameOverride ?? idOverride}
128
138
  onChange={onChange}
129
139
  value={value}
130
140
  required={isRequired}
@@ -15,6 +15,7 @@ import { memo, ReactElement, useCallback } from "react";
15
15
 
16
16
  import { Checkbox } from "./Checkbox";
17
17
  import { Field } from "./Field";
18
+ import type { SeleniumProps } from "./SeleniumProps";
18
19
 
19
20
  export type CheckboxGroupProps = {
20
21
  /**
@@ -31,10 +32,6 @@ export type CheckboxGroupProps = {
31
32
  * The hint text for the CheckboxGroup
32
33
  */
33
34
  hint?: string;
34
- /**
35
- * The id of the `input` element. This will also be the input's `name` field.
36
- */
37
- id?: string;
38
35
  /**
39
36
  * If `true`, the CheckboxGroup is disabled
40
37
  */
@@ -47,24 +44,24 @@ export type CheckboxGroupProps = {
47
44
  * The label text for the CheckboxGroup
48
45
  */
49
46
  label: string;
50
- };
47
+ } & SeleniumProps;
51
48
 
52
49
  const CheckboxGroup = ({
53
50
  children,
54
51
  errorMessage,
55
52
  hint,
56
- id: idOverride,
57
53
  isDisabled,
58
54
  isRequired = false,
59
55
  label,
56
+ testId,
60
57
  }: CheckboxGroupProps) => {
61
58
  const renderFieldComponent = useCallback(
62
- ({ ariaDescribedBy, id }) => (
63
- <MuiFormGroup aria-describedby={ariaDescribedBy} id={id}>
59
+ ({ ariaDescribedBy }) => (
60
+ <MuiFormGroup aria-describedby={ariaDescribedBy} data-se={testId}>
64
61
  {children}
65
62
  </MuiFormGroup>
66
63
  ),
67
- [children]
64
+ [children, testId]
68
65
  );
69
66
 
70
67
  return (
@@ -73,7 +70,6 @@ const CheckboxGroup = ({
73
70
  fieldType="group"
74
71
  hasVisibleLabel={true}
75
72
  hint={hint}
76
- id={idOverride}
77
73
  isDisabled={isDisabled}
78
74
  isOptional={!isRequired}
79
75
  label={label}
@@ -12,6 +12,8 @@
12
12
 
13
13
  import { CircularProgress as MuiCircularProgress } from "@mui/material";
14
14
 
15
+ import type { SeleniumProps } from "./SeleniumProps";
16
+
15
17
  export type CircularProgressProps = {
16
18
  /**
17
19
  * The ARIA label for the progress spinner
@@ -22,13 +24,15 @@ export type CircularProgressProps = {
22
24
  * If undefined, the spinner will spin perpetually.
23
25
  */
24
26
  value?: number;
25
- };
27
+ } & SeleniumProps;
26
28
 
27
29
  export const CircularProgress = ({
28
30
  ariaLabel,
31
+ testId,
29
32
  value,
30
33
  }: CircularProgressProps) => (
31
34
  <MuiCircularProgress
35
+ data-se={testId}
32
36
  value={value}
33
37
  variant={value ? "determinate" : "indeterminate"}
34
38
  aria-label={ariaLabel}
package/src/Dialog.tsx CHANGED
@@ -28,6 +28,8 @@ import {
28
28
  ReactElement,
29
29
  } from "react";
30
30
 
31
+ import type { SeleniumProps } from "./SeleniumProps";
32
+
31
33
  export type DialogProps = {
32
34
  /**
33
35
  * An optional Button object to be situated in the Dialog footer. Should almost always be of variant `primary`.
@@ -58,7 +60,7 @@ export type DialogProps = {
58
60
  */
59
61
  title: string;
60
62
  ariaLabel: string;
61
- };
63
+ } & SeleniumProps;
62
64
 
63
65
  const Dialog = ({
64
66
  callToActionFirstComponent,
@@ -67,6 +69,7 @@ const Dialog = ({
67
69
  children,
68
70
  isOpen,
69
71
  onClose,
72
+ testId,
70
73
  title,
71
74
  ariaLabel,
72
75
  }: DialogProps) => {
@@ -103,7 +106,7 @@ const Dialog = ({
103
106
  );
104
107
 
105
108
  return (
106
- <MuiDialog open={isOpen} onClose={onClose}>
109
+ <MuiDialog data-se={testId} open={isOpen} onClose={onClose}>
107
110
  <DialogTitle>
108
111
  {title}
109
112
  <Button
package/src/Field.tsx CHANGED
@@ -76,9 +76,11 @@ export type FieldProps = {
76
76
  */
77
77
  renderFieldComponent: ({
78
78
  ariaDescribedBy,
79
+ dataSe,
79
80
  id,
80
81
  }: {
81
82
  ariaDescribedBy?: string;
83
+ dataSe?: string;
82
84
  id: string;
83
85
  }) => ReactElement;
84
86
  };
@@ -16,16 +16,18 @@ import { FormHelperText } from "@mui/material";
16
16
  import { ScreenReaderText } from "./ScreenReaderText";
17
17
  import { useTranslation } from "react-i18next";
18
18
 
19
+ import type { SeleniumProps } from "./SeleniumProps";
20
+
19
21
  export type FieldErrorProps = {
20
22
  id?: string;
21
23
  text: string;
22
- };
24
+ } & SeleniumProps;
23
25
 
24
- const FieldError = ({ id, text }: FieldErrorProps) => {
26
+ const FieldError = ({ id, testId, text }: FieldErrorProps) => {
25
27
  const { t } = useTranslation();
26
28
 
27
29
  return (
28
- <FormHelperText error id={id}>
30
+ <FormHelperText data-se={testId} error id={id}>
29
31
  <ScreenReaderText>{`${t(
30
32
  "fielderror.screenreader.text"
31
33
  )}:`}</ScreenReaderText>
package/src/FieldHint.tsx CHANGED
@@ -14,13 +14,19 @@ import { memo } from "react";
14
14
 
15
15
  import { FormHelperText } from "@mui/material";
16
16
 
17
+ import type { SeleniumProps } from "./SeleniumProps";
18
+
17
19
  export type FieldHintProps = {
18
20
  id?: string;
19
21
  text: string;
20
- };
22
+ } & SeleniumProps;
21
23
 
22
- const FieldHint = ({ id, text }: FieldHintProps) => {
23
- return <FormHelperText id={id}>{text}</FormHelperText>;
24
+ const FieldHint = ({ id, testId, text }: FieldHintProps) => {
25
+ return (
26
+ <FormHelperText data-se={testId} id={id}>
27
+ {text}
28
+ </FormHelperText>
29
+ );
24
30
  };
25
31
 
26
32
  const MemoizedFieldHint = memo(FieldHint);
@@ -16,6 +16,7 @@ import { memo, useMemo } from "react";
16
16
  import { useTranslation } from "react-i18next";
17
17
  import { ScreenReaderText } from "./ScreenReaderText";
18
18
  import { Subordinate } from "./Typography";
19
+ import type { SeleniumProps } from "./SeleniumProps";
19
20
 
20
21
  export type FieldLabelProps = {
21
22
  hasVisibleLabel: boolean;
@@ -23,27 +24,28 @@ export type FieldLabelProps = {
23
24
  inputId: string;
24
25
  isOptional: boolean;
25
26
  text: string;
26
- };
27
+ } & SeleniumProps;
27
28
 
28
29
  const FieldLabel = ({
29
30
  hasVisibleLabel,
30
31
  id,
31
32
  inputId,
32
33
  isOptional,
34
+ testId,
33
35
  text,
34
36
  }: FieldLabelProps) => {
35
37
  const { t } = useTranslation();
36
38
 
37
39
  const inputLabel = useMemo(
38
40
  () => (
39
- <MuiInputLabel htmlFor={inputId} id={id}>
41
+ <MuiInputLabel data-se={testId} htmlFor={inputId} id={id}>
40
42
  <span>{text}</span>
41
43
  {isOptional && (
42
44
  <Subordinate>{t("fieldlabel.optional.text")}</Subordinate>
43
45
  )}
44
46
  </MuiInputLabel>
45
47
  ),
46
- [id, inputId, isOptional, text, t]
48
+ [id, inputId, isOptional, testId, text, t]
47
49
  );
48
50
 
49
51
  return hasVisibleLabel ? (
package/src/Fieldset.tsx CHANGED
@@ -18,6 +18,7 @@ import { FieldsetContext } from "./FieldsetContext";
18
18
  import { Legend, Support } from "./Typography";
19
19
  import { useOdysseyDesignTokens } from "./OdysseyDesignTokensContext";
20
20
  import { useUniqueId } from "./useUniqueId";
21
+ import type { SeleniumProps } from "./SeleniumProps";
21
22
 
22
23
  export type FieldsetProps = {
23
24
  /**
@@ -48,7 +49,7 @@ export type FieldsetProps = {
48
49
  * The name associated with the group.
49
50
  */
50
51
  name?: string;
51
- };
52
+ } & SeleniumProps;
52
53
 
53
54
  const Fieldset = ({
54
55
  alert,
@@ -58,6 +59,7 @@ const Fieldset = ({
58
59
  isDisabled = false,
59
60
  legend,
60
61
  name,
62
+ testId,
61
63
  }: FieldsetProps) => {
62
64
  const odysseyDesignTokens = useOdysseyDesignTokens();
63
65
  const id = useUniqueId(idOverride);
@@ -72,6 +74,7 @@ const Fieldset = ({
72
74
  return (
73
75
  <Box
74
76
  component="fieldset"
77
+ data-se={testId}
75
78
  disabled={isDisabled}
76
79
  name={name}
77
80
  id={id}
package/src/Form.tsx CHANGED
@@ -17,6 +17,7 @@ import { Button } from "./Button";
17
17
  import { Callout } from "./Callout";
18
18
  import { Heading4, Support } from "./Typography";
19
19
  import { useUniqueId } from "./useUniqueId";
20
+ import type { SeleniumProps } from "./SeleniumProps";
20
21
 
21
22
  export const formEncodingTypeValues = [
22
23
  "application/x-www-form-urlencoded",
@@ -84,7 +85,7 @@ export type FormProps = {
84
85
  * The title of the Form
85
86
  */
86
87
  title?: string;
87
- };
88
+ } & SeleniumProps;
88
89
 
89
90
  const Form = ({
90
91
  alert,
@@ -98,20 +99,22 @@ const Form = ({
98
99
  name,
99
100
  noValidate = false,
100
101
  target,
102
+ testId,
101
103
  title,
102
104
  }: FormProps) => {
103
105
  const id = useUniqueId(idOverride);
104
106
 
105
107
  return (
106
108
  <Box
107
- component="form"
108
109
  autoComplete={autoCompleteType}
109
- name={name}
110
+ component="form"
111
+ data-se={testId}
110
112
  encType={encodingType}
113
+ id={id}
111
114
  method={method}
115
+ name={name}
112
116
  noValidate={noValidate}
113
117
  target={target}
114
- id={id}
115
118
  sx={{
116
119
  maxWidth: (theme) => theme.mixins.maxWidth,
117
120
  margin: (theme) => theme.spacing(0),
package/src/Link.tsx CHANGED
@@ -12,6 +12,7 @@
12
12
 
13
13
  import { memo, ReactElement } from "react";
14
14
  import { ExternalLinkIcon } from "./icons.generated";
15
+ import type { SeleniumProps } from "./SeleniumProps";
15
16
 
16
17
  import { Link as MuiLink } from "@mui/material";
17
18
 
@@ -47,10 +48,24 @@ export type LinkProps = {
47
48
  * The visual presentation of the Link (default or monochrome)
48
49
  */
49
50
  variant?: (typeof linkVariantValues)[number];
50
- };
51
+ } & SeleniumProps;
51
52
 
52
- const Link = ({ children, href, icon, target, rel, variant }: LinkProps) => (
53
- <MuiLink href={href} rel={rel} target={target} variant={variant}>
53
+ const Link = ({
54
+ children,
55
+ href,
56
+ icon,
57
+ rel,
58
+ target,
59
+ testId,
60
+ variant,
61
+ }: LinkProps) => (
62
+ <MuiLink
63
+ data-se={testId}
64
+ href={href}
65
+ rel={rel}
66
+ target={target}
67
+ variant={variant}
68
+ >
54
69
  {icon && <span className="Link-icon">{icon}</span>}
55
70
 
56
71
  {children}