@okta/odyssey-react-mui 1.9.4 → 1.9.6

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 (68) 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/Field.js +2 -0
  7. package/dist/Field.js.map +1 -1
  8. package/dist/FieldComponentProps.js.map +1 -1
  9. package/dist/FieldHint.js +9 -2
  10. package/dist/FieldHint.js.map +1 -1
  11. package/dist/HintLink.js +23 -0
  12. package/dist/HintLink.js.map +1 -0
  13. package/dist/NativeSelect.js +2 -0
  14. package/dist/NativeSelect.js.map +1 -1
  15. package/dist/OdysseyTranslationProvider.js +6 -1
  16. package/dist/OdysseyTranslationProvider.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/index.js +1 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/labs/DataTable.js +1 -1
  26. package/dist/labs/DataTable.js.map +1 -1
  27. package/dist/src/Autocomplete.d.ts +2 -2
  28. package/dist/src/Autocomplete.d.ts.map +1 -1
  29. package/dist/src/CheckboxGroup.d.ts +2 -2
  30. package/dist/src/CheckboxGroup.d.ts.map +1 -1
  31. package/dist/src/Field.d.ts +2 -25
  32. package/dist/src/Field.d.ts.map +1 -1
  33. package/dist/src/FieldComponentProps.d.ts +6 -0
  34. package/dist/src/FieldComponentProps.d.ts.map +1 -1
  35. package/dist/src/FieldHint.d.ts +3 -1
  36. package/dist/src/FieldHint.d.ts.map +1 -1
  37. package/dist/src/HintLink.d.ts +16 -0
  38. package/dist/src/HintLink.d.ts.map +1 -0
  39. package/dist/src/NativeSelect.d.ts +1 -1
  40. package/dist/src/NativeSelect.d.ts.map +1 -1
  41. package/dist/src/OdysseyTranslationProvider.d.ts.map +1 -1
  42. package/dist/src/RadioGroup.d.ts +2 -2
  43. package/dist/src/RadioGroup.d.ts.map +1 -1
  44. package/dist/src/Select.d.ts +2 -2
  45. package/dist/src/Select.d.ts.map +1 -1
  46. package/dist/src/TextField.d.ts.map +1 -1
  47. package/dist/src/index.d.ts +1 -0
  48. package/dist/src/index.d.ts.map +1 -1
  49. package/dist/src/labs/DataTable.d.ts.map +1 -1
  50. package/dist/src/theme/components.d.ts.map +1 -1
  51. package/dist/theme/components.js +35 -2
  52. package/dist/theme/components.js.map +1 -1
  53. package/dist/tsconfig.production.tsbuildinfo +1 -1
  54. package/package.json +3 -3
  55. package/src/Autocomplete.tsx +10 -2
  56. package/src/CheckboxGroup.tsx +6 -1
  57. package/src/Field.tsx +17 -26
  58. package/src/FieldComponentProps.ts +8 -0
  59. package/src/FieldHint.tsx +8 -1
  60. package/src/HintLink.tsx +28 -0
  61. package/src/NativeSelect.tsx +9 -1
  62. package/src/OdysseyTranslationProvider.tsx +17 -1
  63. package/src/RadioGroup.tsx +3 -1
  64. package/src/Select.tsx +4 -1
  65. package/src/TextField.tsx +2 -0
  66. package/src/index.ts +1 -0
  67. package/src/labs/DataTable.tsx +8 -1
  68. package/src/theme/components.tsx +35 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okta/odyssey-react-mui",
3
- "version": "1.9.4",
3
+ "version": "1.9.6",
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.4",
54
+ "@okta/odyssey-design-tokens": "1.9.6",
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": "c2cfdc3048a0c8a71d2728f9b1a81162db405a32"
66
+ "gitHead": "6dec6e9312bbcda85401a6f29304a22cfd1bdc88"
67
67
  }
@@ -161,7 +161,13 @@ export type AutocompleteProps<
161
161
  getIsOptionEqualToValue?: (option: OptionType, value: OptionType) => boolean;
162
162
  } & Pick<
163
163
  FieldComponentProps,
164
- "errorMessage" | "hint" | "id" | "isOptional" | "name" | "isFullWidth"
164
+ | "errorMessage"
165
+ | "hint"
166
+ | "HintLinkComponent"
167
+ | "id"
168
+ | "isFullWidth"
169
+ | "isOptional"
170
+ | "name"
165
171
  > &
166
172
  SeleniumProps;
167
173
 
@@ -182,6 +188,7 @@ const Autocomplete = <
182
188
  isOptional = false,
183
189
  isReadOnly,
184
190
  hint,
191
+ HintLinkComponent,
185
192
  label,
186
193
  name: nameOverride,
187
194
  onBlur,
@@ -240,6 +247,7 @@ const Autocomplete = <
240
247
  hasVisibleLabel
241
248
  id={InputLabelProps.htmlFor}
242
249
  hint={hint}
250
+ HintLinkComponent={HintLinkComponent}
243
251
  label={label}
244
252
  isOptional={isOptional}
245
253
  renderFieldComponent={({
@@ -264,7 +272,7 @@ const Autocomplete = <
264
272
  )}
265
273
  />
266
274
  ),
267
- [errorMessage, hint, isOptional, label, nameOverride]
275
+ [errorMessage, hint, HintLinkComponent, isOptional, label, nameOverride]
268
276
  );
269
277
  const onChange = useCallback<
270
278
  NonNullable<
@@ -33,13 +33,17 @@ export type CheckboxGroupProps = {
33
33
  * The label text for the CheckboxGroup
34
34
  */
35
35
  label: string;
36
- } & Pick<FieldComponentProps, "errorMessage" | "hint" | "isDisabled"> &
36
+ } & Pick<
37
+ FieldComponentProps,
38
+ "errorMessage" | "hint" | "HintLinkComponent" | "isDisabled"
39
+ > &
37
40
  SeleniumProps;
38
41
 
39
42
  const CheckboxGroup = ({
40
43
  children,
41
44
  errorMessage,
42
45
  hint,
46
+ HintLinkComponent,
43
47
  isDisabled,
44
48
  isRequired = false,
45
49
  label,
@@ -65,6 +69,7 @@ const CheckboxGroup = ({
65
69
  fieldType="group"
66
70
  hasVisibleLabel={true}
67
71
  hint={hint}
72
+ HintLinkComponent={HintLinkComponent}
68
73
  isDisabled={isDisabled}
69
74
  isOptional={!isRequired}
70
75
  label={label}
package/src/Field.tsx CHANGED
@@ -16,6 +16,8 @@ import {
16
16
  FormControl as MuiFormControl,
17
17
  FormLabel as MuiFormLabel,
18
18
  } from "@mui/material";
19
+
20
+ import { FieldComponentProps } from "./FieldComponentProps";
19
21
  import { FieldError } from "./FieldError";
20
22
  import { FieldHint } from "./FieldHint";
21
23
  import { FieldLabel } from "./FieldLabel";
@@ -27,10 +29,6 @@ import { useUniqueId } from "./useUniqueId";
27
29
  export const fieldTypeValues = ["single", "group"] as const;
28
30
 
29
31
  export type FieldProps = {
30
- /**
31
- * If `error` is not undefined, the `input` will indicate an error.
32
- */
33
- errorMessage?: string;
34
32
  /**
35
33
  * 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).
36
34
  */
@@ -39,14 +37,6 @@ export type FieldProps = {
39
37
  * If `true`, the Field label will be shown
40
38
  */
41
39
  hasVisibleLabel: boolean;
42
- /**
43
- * The helper text content.
44
- */
45
- hint?: string;
46
- /**
47
- * The id of the `input` element.
48
- */
49
- id?: string;
50
40
  /**
51
41
  * Important for narrowing down the `fieldset` role to "radiogroup".
52
42
  */
@@ -55,18 +45,6 @@ export type FieldProps = {
55
45
  * Important for determining if children inherit error state
56
46
  */
57
47
  isCheckboxGroup?: boolean;
58
- /**
59
- * If `true`, the component is disabled.
60
- */
61
- isDisabled?: boolean;
62
- /**
63
- * If `true`, the component can stretch to fill the width of the container.
64
- */
65
- isFullWidth?: boolean;
66
- /**
67
- * If `true`, the `input` element is not required.
68
- */
69
- isOptional?: boolean;
70
48
  /**
71
49
  * The label for the `input` element.
72
50
  */
@@ -98,6 +76,7 @@ const Field = ({
98
76
  fieldType,
99
77
  hasVisibleLabel,
100
78
  hint,
79
+ HintLinkComponent,
101
80
  id: idOverride,
102
81
  isDisabled: isDisabledProp = false,
103
82
  isFullWidth = false,
@@ -105,7 +84,17 @@ const Field = ({
105
84
  isOptional = false,
106
85
  label,
107
86
  renderFieldComponent,
108
- }: FieldProps) => {
87
+ }: FieldProps &
88
+ Pick<
89
+ FieldComponentProps,
90
+ | "errorMessage"
91
+ | "hint"
92
+ | "HintLinkComponent"
93
+ | "id"
94
+ | "isDisabled"
95
+ | "isFullWidth"
96
+ | "isOptional"
97
+ >) => {
109
98
  const { t } = useTranslation();
110
99
 
111
100
  const id = useUniqueId(idOverride);
@@ -152,7 +141,9 @@ const Field = ({
152
141
  />
153
142
  )}
154
143
 
155
- {hint && <FieldHint id={hintId} text={hint} />}
144
+ {hint && (
145
+ <FieldHint id={hintId} LinkComponent={HintLinkComponent} text={hint} />
146
+ )}
156
147
 
157
148
  {renderFieldComponent({
158
149
  ariaDescribedBy,
@@ -10,6 +10,10 @@
10
10
  * See the License for the specific language governing permissions and limitations under the License.
11
11
  */
12
12
 
13
+ import { ReactElement } from "react";
14
+
15
+ import { HintLink } from "./HintLink";
16
+
13
17
  export type FieldComponentProps = {
14
18
  /**
15
19
  * If `error` is not undefined, the `input` will indicate an error.
@@ -19,6 +23,10 @@ export type FieldComponentProps = {
19
23
  * The helper text content.
20
24
  */
21
25
  hint?: string;
26
+ /**
27
+ * A `Link` component to provide greater context that is rendered at the end of the `hint` text
28
+ */
29
+ HintLinkComponent?: ReactElement<typeof HintLink>;
22
30
  /**
23
31
  * The id of the `input` element.
24
32
  */
package/src/FieldHint.tsx CHANGED
@@ -14,17 +14,24 @@ import { memo } from "react";
14
14
 
15
15
  import { FormHelperText } from "@mui/material";
16
16
 
17
+ import { FieldComponentProps } from "./FieldComponentProps";
17
18
  import type { SeleniumProps } from "./SeleniumProps";
18
19
 
19
20
  export type FieldHintProps = {
21
+ LinkComponent?: FieldComponentProps["HintLinkComponent"];
20
22
  id?: string;
21
23
  text: string;
22
24
  } & SeleniumProps;
23
25
 
24
- const FieldHint = ({ id, testId, text }: FieldHintProps) => {
26
+ const FieldHint = ({ id, LinkComponent, testId, text }: FieldHintProps) => {
25
27
  return (
26
28
  <FormHelperText data-se={testId} id={id}>
27
29
  {text}
30
+ {LinkComponent && (
31
+ <>
32
+ <span>&nbsp;{LinkComponent}</span>
33
+ </>
34
+ )}
28
35
  </FormHelperText>
29
36
  );
30
37
  };
@@ -0,0 +1,28 @@
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 { memo } from "react";
14
+
15
+ import { Link, LinkProps } from "./Link";
16
+
17
+ const HintLink = (
18
+ props: Pick<
19
+ LinkProps,
20
+ "children" | "href" | "onClick" | "rel" | "target" | "testId"
21
+ >
22
+ ) => <Link {...props} variant="default" />;
23
+
24
+ const MemoizedHintLink = memo(HintLink);
25
+
26
+ MemoizedHintLink.displayName = "HintLink";
27
+
28
+ export { MemoizedHintLink as HintLink };
@@ -81,7 +81,13 @@ export type NativeSelectProps<
81
81
  value?: Value;
82
82
  } & Pick<
83
83
  FieldComponentProps,
84
- "errorMessage" | "hint" | "id" | "isDisabled" | "isOptional" | "isFullWidth"
84
+ | "errorMessage"
85
+ | "hint"
86
+ | "HintLinkComponent"
87
+ | "id"
88
+ | "isDisabled"
89
+ | "isFullWidth"
90
+ | "isOptional"
85
91
  > &
86
92
  SeleniumProps;
87
93
 
@@ -95,6 +101,7 @@ const NativeSelect: ForwardRefWithType = forwardRef(
95
101
  errorMessage,
96
102
  hasMultipleChoices: hasMultipleChoicesProp,
97
103
  hint,
104
+ HintLinkComponent,
98
105
  id: idOverride,
99
106
  isDisabled = false,
100
107
  isFullWidth = false,
@@ -178,6 +185,7 @@ const NativeSelect: ForwardRefWithType = forwardRef(
178
185
  fieldType="single"
179
186
  hasVisibleLabel
180
187
  hint={hint}
188
+ HintLinkComponent={HintLinkComponent}
181
189
  id={idOverride}
182
190
  isDisabled={isDisabled}
183
191
  isFullWidth={isFullWidth}
@@ -44,14 +44,30 @@ export type OdysseyTranslationProviderProps<
44
44
  translationOverrides?: TranslationOverrides<SupportedLanguages>;
45
45
  };
46
46
 
47
+ const formatLanguageCodeToHyphenated = <SupportedLanguages extends string>(
48
+ languageCode: OdysseyTranslationProviderProps<SupportedLanguages>["languageCode"]
49
+ ) => languageCode?.replaceAll("_", "-");
50
+
47
51
  export const OdysseyTranslationProvider = <SupportedLanguages extends string>({
48
52
  children,
49
53
  languageCode,
50
54
  translationOverrides,
51
55
  }: OdysseyTranslationProviderProps<SupportedLanguages>) => {
52
56
  useEffect(() => {
57
+ const normalizedLanguageCode =
58
+ formatLanguageCodeToHyphenated<SupportedLanguages>(languageCode);
59
+
60
+ const changeHtmlElementLanguageAttribute = () => {
61
+ window.document.documentElement.setAttribute(
62
+ "lang",
63
+ normalizedLanguageCode || "en"
64
+ );
65
+ };
53
66
  // Defaults to the browser's language if available otherwise `en` will be used
54
- i18n.changeLanguage(languageCode || window.navigator.language);
67
+ i18n.changeLanguage(
68
+ normalizedLanguageCode || window.navigator.language,
69
+ changeHtmlElementLanguageAttribute
70
+ );
55
71
  }, [languageCode]);
56
72
 
57
73
  useEffect(() => {
@@ -45,7 +45,7 @@ export type RadioGroupProps = {
45
45
  value?: RadioProps["value"];
46
46
  } & Pick<
47
47
  FieldComponentProps,
48
- "errorMessage" | "hint" | "id" | "isDisabled" | "name"
48
+ "errorMessage" | "hint" | "HintLinkComponent" | "id" | "isDisabled" | "name"
49
49
  > &
50
50
  SeleniumProps;
51
51
 
@@ -54,6 +54,7 @@ const RadioGroup = ({
54
54
  defaultValue,
55
55
  errorMessage,
56
56
  hint,
57
+ HintLinkComponent,
57
58
  id: idOverride,
58
59
  isDisabled,
59
60
  label,
@@ -101,6 +102,7 @@ const RadioGroup = ({
101
102
  fieldType="group"
102
103
  hasVisibleLabel={false}
103
104
  hint={hint}
105
+ HintLinkComponent={HintLinkComponent}
104
106
  id={idOverride}
105
107
  isDisabled={isDisabled}
106
108
  label={label}
package/src/Select.tsx CHANGED
@@ -86,11 +86,12 @@ export type SelectProps<
86
86
  FieldComponentProps,
87
87
  | "errorMessage"
88
88
  | "hint"
89
+ | "HintLinkComponent"
89
90
  | "id"
90
91
  | "isDisabled"
92
+ | "isFullWidth"
91
93
  | "isOptional"
92
94
  | "name"
93
- | "isFullWidth"
94
95
  > &
95
96
  SeleniumProps;
96
97
 
@@ -118,6 +119,7 @@ const Select = <
118
119
  errorMessage,
119
120
  hasMultipleChoices: hasMultipleChoicesProp,
120
121
  hint,
122
+ HintLinkComponent,
121
123
  id: idOverride,
122
124
  isDisabled = false,
123
125
  isFullWidth = false,
@@ -287,6 +289,7 @@ const Select = <
287
289
  fieldType="single"
288
290
  hasVisibleLabel
289
291
  hint={hint}
292
+ HintLinkComponent={HintLinkComponent}
290
293
  id={idOverride}
291
294
  isDisabled={isDisabled}
292
295
  isFullWidth={isFullWidth}
package/src/TextField.tsx CHANGED
@@ -102,6 +102,7 @@ const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
102
102
  endAdornment,
103
103
  errorMessage,
104
104
  hint,
105
+ HintLinkComponent,
105
106
  id: idOverride,
106
107
  isDisabled = false,
107
108
  isFullWidth = false,
@@ -204,6 +205,7 @@ const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
204
205
  fieldType="single"
205
206
  hasVisibleLabel
206
207
  hint={hint}
208
+ HintLinkComponent={HintLinkComponent}
207
209
  id={idOverride}
208
210
  isDisabled={isDisabled}
209
211
  isFullWidth={isFullWidth}
package/src/index.ts CHANGED
@@ -71,6 +71,7 @@ export * from "./Dialog";
71
71
  export * from "./Fieldset";
72
72
  export * from "./FieldComponentProps";
73
73
  export * from "./Form";
74
+ export * from "./HintLink";
74
75
  export * from "./Link";
75
76
  export * from "./MenuButton";
76
77
  export * from "./MenuItem";
@@ -628,7 +628,14 @@ const DataTable = ({
628
628
  )}
629
629
  </>
630
630
  ),
631
- [density, columnVisibility, columns, hasChangeableDensity]
631
+ [
632
+ columnVisibility,
633
+ columns,
634
+ density,
635
+ hasChangeableDensity,
636
+ handleColumnVisibility,
637
+ hasColumnVisibility,
638
+ ]
632
639
  );
633
640
 
634
641
  return (
@@ -972,6 +972,32 @@ export const components = ({
972
972
  html {
973
973
  font-size: calc((${themeParam.typography.fontSize} / 16) * 100%);
974
974
  }
975
+
976
+ :not(code) &, :not(pre) & {
977
+ :lang(el) {
978
+ font-family: 'Noto Sans', sans-serif;
979
+ }
980
+
981
+ :lang(ja) {
982
+ font-family: 'Noto Sans JP', sans-serif;
983
+ }
984
+
985
+ :lang(ko) {
986
+ font-family: 'Noto Sans KR', sans-serif;
987
+ }
988
+
989
+ :lang(th) {
990
+ font-family: 'Noto Sans Thai', sans-serif;
991
+ }
992
+
993
+ :lang(zh-CN) {
994
+ font-family: 'Noto Sans SC', sans-serif;
995
+ }
996
+
997
+ :lang(zh-TW) {
998
+ font-family: 'Noto Sans TC', sans-serif;
999
+ }
1000
+ }
975
1001
  `,
976
1002
  },
977
1003
  MuiScopedCssBaseline: {
@@ -1478,6 +1504,9 @@ export const components = ({
1478
1504
  },
1479
1505
  styleOverrides: {
1480
1506
  root: {
1507
+ display: "flex",
1508
+ justifyContent: "flex-start",
1509
+ alignItems: "center",
1481
1510
  fontSize: odysseyTokens.TypographySizeSubordinate,
1482
1511
  lineHeight: odysseyTokens.TypographyLineHeightBody,
1483
1512
  marginBlockStart: odysseyTokens.Spacing2,
@@ -1490,6 +1519,10 @@ export const components = ({
1490
1519
  marginBlockEnd: 0,
1491
1520
  },
1492
1521
  textAlign: "start",
1522
+
1523
+ ".field-hint-link-component": {
1524
+ marginInlineStart: odysseyTokens.Spacing1,
1525
+ },
1493
1526
  },
1494
1527
  },
1495
1528
  },
@@ -2115,6 +2148,8 @@ export const components = ({
2115
2148
 
2116
2149
  ...(ownerState.disabled && {
2117
2150
  color: odysseyTokens.TypographyColorDisabled,
2151
+ // !important used to override more specific .Mui-Disabled class selector
2152
+ opacity: "1 !important",
2118
2153
  }),
2119
2154
 
2120
2155
  ...(ownerState.wrapped && {