@okta/odyssey-react-mui 1.0.2 → 1.2.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/CHANGELOG.md +54 -0
- package/README.md +1 -1
- package/dist/Autocomplete.js +20 -3
- package/dist/Autocomplete.js.map +1 -1
- package/dist/Banner.js +3 -1
- package/dist/Banner.js.map +1 -1
- package/dist/Box.js +8 -4
- package/dist/Box.js.map +1 -1
- package/dist/Button.js +3 -1
- package/dist/Button.js.map +1 -1
- package/dist/Callout.js +2 -0
- package/dist/Callout.js.map +1 -1
- package/dist/Checkbox.js +6 -2
- package/dist/Checkbox.js.map +1 -1
- package/dist/CheckboxGroup.js +5 -7
- package/dist/CheckboxGroup.js.map +1 -1
- package/dist/CircularProgress.js +2 -0
- package/dist/CircularProgress.js.map +1 -1
- package/dist/Dialog.js +2 -0
- package/dist/Dialog.js.map +1 -1
- package/dist/Field.js.map +1 -1
- package/dist/FieldError.js +2 -0
- package/dist/FieldError.js.map +1 -1
- package/dist/FieldHint.js +2 -0
- package/dist/FieldHint.js.map +1 -1
- package/dist/FieldLabel.js +3 -1
- package/dist/FieldLabel.js.map +1 -1
- package/dist/Fieldset.js +3 -1
- package/dist/Fieldset.js.map +1 -1
- package/dist/Form.js +5 -3
- package/dist/Form.js.map +1 -1
- package/dist/Link.js +3 -1
- package/dist/Link.js.map +1 -1
- package/dist/MenuButton.js +8 -2
- package/dist/MenuButton.js.map +1 -1
- package/dist/MenuItem.js +6 -2
- package/dist/MenuItem.js.map +1 -1
- package/dist/NativeSelect.js +3 -1
- package/dist/NativeSelect.js.map +1 -1
- package/dist/OdysseyCacheProvider.js +4 -1
- package/dist/OdysseyCacheProvider.js.map +1 -1
- package/dist/OdysseyProvider.js +12 -5
- package/dist/OdysseyProvider.js.map +1 -1
- package/dist/OdysseyThemeProvider.js +8 -7
- package/dist/OdysseyThemeProvider.js.map +1 -1
- package/dist/OdysseyTranslationProvider.js +1 -1
- package/dist/OdysseyTranslationProvider.js.map +1 -1
- package/dist/OdysseyTranslationProvider.types.js +1 -1
- package/dist/OdysseyTranslationProvider.types.js.map +1 -1
- package/dist/PasswordField.js +18 -9
- package/dist/PasswordField.js.map +1 -1
- package/dist/Radio.js +2 -0
- package/dist/Radio.js.map +1 -1
- package/dist/RadioGroup.js +5 -2
- package/dist/RadioGroup.js.map +1 -1
- package/dist/SearchField.js +11 -10
- package/dist/SearchField.js.map +1 -1
- package/dist/Select.js +39 -35
- package/dist/Select.js.map +1 -1
- package/dist/SeleniumProps.js +2 -0
- package/dist/SeleniumProps.js.map +1 -0
- package/dist/Status.js +4 -2
- package/dist/Status.js.map +1 -1
- package/dist/Tabs.js +11 -4
- package/dist/Tabs.js.map +1 -1
- package/dist/Tag.js +4 -2
- package/dist/Tag.js.map +1 -1
- package/dist/TagList.js +3 -1
- package/dist/TagList.js.map +1 -1
- package/dist/TextField.js +6 -2
- package/dist/TextField.js.map +1 -1
- package/dist/Toast.js +2 -0
- package/dist/Toast.js.map +1 -1
- package/dist/Tooltip.js +2 -0
- package/dist/Tooltip.js.map +1 -1
- package/dist/Typography.js +71 -59
- package/dist/Typography.js.map +1 -1
- package/dist/createShadowDom.js +26 -0
- package/dist/createShadowDom.js.map +1 -0
- package/dist/{OdysseyI18n.js → i18n.js} +5 -2
- package/dist/i18n.js.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/labs/DatePicker.js +4 -2
- package/dist/labs/DatePicker.js.map +1 -1
- package/dist/labs/PaginatedTable.js +6 -4
- package/dist/labs/PaginatedTable.js.map +1 -1
- package/dist/labs/StaticTable.js +9 -4
- package/dist/labs/StaticTable.js.map +1 -1
- package/dist/labs/datePickerTheme.js +4 -2
- package/dist/labs/datePickerTheme.js.map +1 -1
- package/dist/properties/ts/odyssey-react-mui.js +2 -0
- package/dist/properties/ts/odyssey-react-mui.js.map +1 -1
- package/dist/src/Autocomplete.d.ts +29 -4
- package/dist/src/Autocomplete.d.ts.map +1 -1
- package/dist/src/Banner.d.ts +3 -2
- package/dist/src/Banner.d.ts.map +1 -1
- package/dist/src/Box.d.ts +9 -2
- package/dist/src/Box.d.ts.map +1 -1
- package/dist/src/Button.d.ts +3 -2
- package/dist/src/Button.d.ts.map +1 -1
- package/dist/src/Callout.d.ts +3 -2
- package/dist/src/Callout.d.ts.map +1 -1
- package/dist/src/Checkbox.d.ts +8 -3
- package/dist/src/Checkbox.d.ts.map +1 -1
- package/dist/src/CheckboxGroup.d.ts +3 -6
- package/dist/src/CheckboxGroup.d.ts.map +1 -1
- package/dist/src/CircularProgress.d.ts +3 -2
- package/dist/src/CircularProgress.d.ts.map +1 -1
- package/dist/src/Dialog.d.ts +3 -2
- package/dist/src/Dialog.d.ts.map +1 -1
- package/dist/src/Field.d.ts +2 -1
- package/dist/src/Field.d.ts.map +1 -1
- package/dist/src/FieldError.d.ts +3 -2
- package/dist/src/FieldError.d.ts.map +1 -1
- package/dist/src/FieldHint.d.ts +3 -2
- package/dist/src/FieldHint.d.ts.map +1 -1
- package/dist/src/FieldLabel.d.ts +3 -2
- package/dist/src/FieldLabel.d.ts.map +1 -1
- package/dist/src/Fieldset.d.ts +3 -2
- package/dist/src/Fieldset.d.ts.map +1 -1
- package/dist/src/Form.d.ts +3 -2
- package/dist/src/Form.d.ts.map +1 -1
- package/dist/src/Link.d.ts +3 -2
- package/dist/src/Link.d.ts.map +1 -1
- package/dist/src/MenuButton.d.ts +12 -3
- package/dist/src/MenuButton.d.ts.map +1 -1
- package/dist/src/MenuItem.d.ts +5 -4
- package/dist/src/MenuItem.d.ts.map +1 -1
- package/dist/src/NativeSelect.d.ts +56 -2
- package/dist/src/NativeSelect.d.ts.map +1 -1
- package/dist/src/OdysseyCacheProvider.d.ts +6 -1
- package/dist/src/OdysseyCacheProvider.d.ts.map +1 -1
- package/dist/src/OdysseyProvider.d.ts +1 -1
- package/dist/src/OdysseyProvider.d.ts.map +1 -1
- package/dist/src/OdysseyThemeProvider.d.ts +2 -1
- package/dist/src/OdysseyThemeProvider.d.ts.map +1 -1
- package/dist/src/OdysseyTranslationProvider.d.ts +1 -1
- package/dist/src/OdysseyTranslationProvider.d.ts.map +1 -1
- package/dist/src/OdysseyTranslationProvider.types.d.ts +1 -1
- package/dist/src/OdysseyTranslationProvider.types.d.ts.map +1 -1
- package/dist/src/PasswordField.d.ts +78 -2
- package/dist/src/PasswordField.d.ts.map +1 -1
- package/dist/src/Radio.d.ts +3 -2
- package/dist/src/Radio.d.ts.map +1 -1
- package/dist/src/RadioGroup.d.ts +8 -3
- package/dist/src/RadioGroup.d.ts.map +1 -1
- package/dist/src/SearchField.d.ts +58 -2
- package/dist/src/SearchField.d.ts.map +1 -1
- package/dist/src/Select.d.ts +7 -2
- package/dist/src/Select.d.ts.map +1 -1
- package/dist/src/SeleniumProps.d.ts +20 -0
- package/dist/src/SeleniumProps.d.ts.map +1 -0
- package/dist/src/Status.d.ts +3 -2
- package/dist/src/Status.d.ts.map +1 -1
- package/dist/src/Tabs.d.ts +9 -3
- package/dist/src/Tabs.d.ts.map +1 -1
- package/dist/src/Tag.d.ts +3 -2
- package/dist/src/Tag.d.ts.map +1 -1
- package/dist/src/TagList.d.ts +3 -2
- package/dist/src/TagList.d.ts.map +1 -1
- package/dist/src/TextField.d.ts +86 -2
- package/dist/src/TextField.d.ts.map +1 -1
- package/dist/src/Toast.d.ts +3 -2
- package/dist/src/Toast.d.ts.map +1 -1
- package/dist/src/Tooltip.d.ts +3 -2
- package/dist/src/Tooltip.d.ts.map +1 -1
- package/dist/src/Typography.d.ts +14 -49
- package/dist/src/Typography.d.ts.map +1 -1
- package/dist/src/createShadowDom.d.ts +16 -0
- package/dist/src/createShadowDom.d.ts.map +1 -0
- package/dist/src/{OdysseyI18n.d.ts → i18n.d.ts} +20 -2
- package/dist/src/i18n.d.ts.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/labs/DatePicker.d.ts +5 -1
- package/dist/src/labs/DatePicker.d.ts.map +1 -1
- package/dist/src/labs/PaginatedTable.d.ts.map +1 -1
- package/dist/src/labs/StaticTable.d.ts.map +1 -1
- package/dist/src/properties/ts/odyssey-react-mui.d.ts +2 -0
- package/dist/src/properties/ts/odyssey-react-mui.d.ts.map +1 -1
- package/dist/src/theme/components.d.ts +4 -1
- package/dist/src/theme/components.d.ts.map +1 -1
- package/dist/src/theme/createOdysseyMuiTheme.d.ts +23 -0
- package/dist/src/theme/createOdysseyMuiTheme.d.ts.map +1 -0
- package/dist/src/theme/mixins.d.ts +3 -1
- package/dist/src/theme/mixins.d.ts.map +1 -1
- package/dist/src/theme/palette.d.ts +3 -1
- package/dist/src/theme/palette.d.ts.map +1 -1
- package/dist/src/theme/shape.d.ts +3 -1
- package/dist/src/theme/shape.d.ts.map +1 -1
- package/dist/src/theme/spacing.d.ts +3 -1
- package/dist/src/theme/spacing.d.ts.map +1 -1
- package/dist/src/theme/theme.d.ts +1 -8
- package/dist/src/theme/theme.d.ts.map +1 -1
- package/dist/src/theme/typography.d.ts +3 -1
- package/dist/src/theme/typography.d.ts.map +1 -1
- package/dist/theme/components.js +118 -73
- package/dist/theme/components.js.map +1 -1
- package/dist/theme/createOdysseyMuiTheme.js +51 -0
- package/dist/theme/createOdysseyMuiTheme.js.map +1 -0
- package/dist/theme/mixins.js +4 -1
- package/dist/theme/mixins.js.map +1 -1
- package/dist/theme/palette.js +4 -1
- package/dist/theme/palette.js.map +1 -1
- package/dist/theme/shape.js +4 -1
- package/dist/theme/shape.js.map +1 -1
- package/dist/theme/spacing.js +4 -1
- package/dist/theme/spacing.js.map +1 -1
- package/dist/theme/theme.js +1 -20
- package/dist/theme/theme.js.map +1 -1
- package/dist/theme/typography.js +4 -1
- package/dist/theme/typography.js.map +1 -1
- package/dist/tsconfig.production.tsbuildinfo +1 -1
- package/package.json +7 -6
- package/src/Autocomplete.tsx +56 -4
- package/src/Banner.tsx +11 -2
- package/src/Box.tsx +11 -5
- package/src/Button.tsx +6 -1
- package/src/Callout.tsx +5 -3
- package/src/Checkbox.tsx +14 -4
- package/src/CheckboxGroup.tsx +6 -10
- package/src/CircularProgress.tsx +5 -1
- package/src/Dialog.tsx +5 -2
- package/src/Field.tsx +2 -0
- package/src/FieldError.tsx +5 -3
- package/src/FieldHint.tsx +9 -3
- package/src/FieldLabel.tsx +5 -3
- package/src/Fieldset.tsx +4 -1
- package/src/Form.tsx +7 -4
- package/src/Link.tsx +18 -3
- package/src/MenuButton.tsx +33 -4
- package/src/MenuItem.tsx +11 -6
- package/src/NativeSelect.tsx +7 -2
- package/src/OdysseyCacheProvider.tsx +9 -1
- package/src/OdysseyProvider.tsx +18 -8
- package/src/OdysseyThemeProvider.tsx +12 -8
- package/src/OdysseyTranslationProvider.test.tsx +2 -2
- package/src/OdysseyTranslationProvider.tsx +1 -1
- package/src/OdysseyTranslationProvider.types.ts +1 -0
- package/src/PasswordField.tsx +37 -13
- package/src/Radio.tsx +5 -1
- package/src/RadioGroup.tsx +12 -4
- package/src/SearchField.tsx +23 -15
- package/src/Select.tsx +154 -149
- package/src/SeleniumProps.ts +20 -0
- package/src/Status.tsx +15 -3
- package/src/Tabs.tsx +18 -4
- package/src/Tag.tsx +12 -3
- package/src/TagList.tsx +4 -2
- package/src/TextField.tsx +14 -2
- package/src/Toast.tsx +4 -1
- package/src/Tooltip.tsx +4 -1
- package/src/Typography.tsx +76 -54
- package/src/createShadowDom.ts +46 -0
- package/src/{OdysseyI18n.ts → i18n.ts} +4 -2
- package/src/index.ts +1 -0
- package/src/labs/DatePicker.tsx +15 -7
- package/src/labs/PaginatedTable.tsx +12 -3
- package/src/labs/README.md +2 -2
- package/src/labs/StaticTable.tsx +13 -3
- package/src/labs/datePickerTheme.tsx +2 -2
- package/src/properties/odyssey-react-mui.properties +2 -0
- package/src/properties/ts/odyssey-react-mui.ts +1 -1
- package/src/theme/components.tsx +69 -18
- package/src/theme/createOdysseyMuiTheme.ts +47 -0
- package/src/theme/mixins.ts +5 -1
- package/src/theme/palette.ts +5 -3
- package/src/theme/shape.ts +5 -1
- package/src/theme/spacing.ts +5 -3
- package/src/theme/theme.ts +1 -26
- package/src/theme/typography.ts +5 -3
- package/dist/OdysseyI18n.js.map +0 -1
- package/dist/src/OdysseyI18n.d.ts.map +0 -1
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
|
-
|
|
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 = ({
|
|
53
|
-
|
|
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}
|
package/src/MenuButton.tsx
CHANGED
|
@@ -10,13 +10,20 @@
|
|
|
10
10
|
* See the License for the specific language governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
Button,
|
|
15
|
+
buttonSizeValues,
|
|
16
|
+
buttonVariantValues,
|
|
17
|
+
MenuItem,
|
|
18
|
+
useUniqueId,
|
|
19
|
+
} from "./";
|
|
14
20
|
import { Divider, ListSubheader, Menu } from "@mui/material";
|
|
15
|
-
import { ChevronDownIcon } from "./icons.generated";
|
|
21
|
+
import { ChevronDownIcon, MoreIcon } from "./icons.generated";
|
|
16
22
|
import { memo, type ReactElement, useCallback, useMemo, useState } from "react";
|
|
17
23
|
|
|
18
24
|
import { MenuContext, MenuContextType } from "./MenuContext";
|
|
19
25
|
import { NullElement } from "./NullElement";
|
|
26
|
+
import type { SeleniumProps } from "./SeleniumProps";
|
|
20
27
|
|
|
21
28
|
export type MenuButtonProps = {
|
|
22
29
|
/**
|
|
@@ -55,6 +62,14 @@ export type MenuButtonProps = {
|
|
|
55
62
|
* The id of the Button
|
|
56
63
|
*/
|
|
57
64
|
id?: string;
|
|
65
|
+
/**
|
|
66
|
+
* If the MenuButton is an overflow menu or standard menu.
|
|
67
|
+
*/
|
|
68
|
+
isOverflow?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* The size of the button
|
|
71
|
+
*/
|
|
72
|
+
size?: (typeof buttonSizeValues)[number];
|
|
58
73
|
/**
|
|
59
74
|
* The tooltip text for the Button if it's icon-only
|
|
60
75
|
*/
|
|
@@ -75,7 +90,8 @@ export type MenuButtonProps = {
|
|
|
75
90
|
ariaLabelledBy: string;
|
|
76
91
|
buttonLabel?: undefined | "";
|
|
77
92
|
}
|
|
78
|
-
)
|
|
93
|
+
) &
|
|
94
|
+
SeleniumProps;
|
|
79
95
|
|
|
80
96
|
const MenuButton = ({
|
|
81
97
|
ariaLabel,
|
|
@@ -84,8 +100,11 @@ const MenuButton = ({
|
|
|
84
100
|
buttonLabel = "",
|
|
85
101
|
buttonVariant = "secondary",
|
|
86
102
|
children,
|
|
87
|
-
endIcon
|
|
103
|
+
endIcon: endIconProp,
|
|
88
104
|
id: idOverride,
|
|
105
|
+
isOverflow,
|
|
106
|
+
size,
|
|
107
|
+
testId,
|
|
89
108
|
tooltipText,
|
|
90
109
|
}: MenuButtonProps) => {
|
|
91
110
|
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
|
@@ -115,6 +134,14 @@ const MenuButton = ({
|
|
|
115
134
|
[closeMenu, openMenu]
|
|
116
135
|
);
|
|
117
136
|
|
|
137
|
+
const endIcon = endIconProp ? (
|
|
138
|
+
endIconProp
|
|
139
|
+
) : isOverflow ? (
|
|
140
|
+
<MoreIcon />
|
|
141
|
+
) : (
|
|
142
|
+
<ChevronDownIcon />
|
|
143
|
+
);
|
|
144
|
+
|
|
118
145
|
return (
|
|
119
146
|
<div>
|
|
120
147
|
<Button
|
|
@@ -124,10 +151,12 @@ const MenuButton = ({
|
|
|
124
151
|
ariaDescribedBy={ariaDescribedBy}
|
|
125
152
|
ariaLabel={ariaLabel}
|
|
126
153
|
ariaLabelledBy={ariaLabelledBy}
|
|
154
|
+
data-se={testId}
|
|
127
155
|
endIcon={endIcon}
|
|
128
156
|
id={`${uniqueId}-button`}
|
|
129
157
|
label={buttonLabel}
|
|
130
158
|
onClick={openMenu}
|
|
159
|
+
size={size}
|
|
131
160
|
tooltipText={tooltipText}
|
|
132
161
|
variant={buttonVariant}
|
|
133
162
|
/>
|
package/src/MenuItem.tsx
CHANGED
|
@@ -18,6 +18,7 @@ import { menuItemClasses } from "@mui/material/MenuItem";
|
|
|
18
18
|
import { memo, useCallback, useContext, type ReactNode } from "react";
|
|
19
19
|
|
|
20
20
|
import { MenuContext } from "./MenuContext";
|
|
21
|
+
import type { SeleniumProps } from "./SeleniumProps";
|
|
21
22
|
|
|
22
23
|
export type MenuItemProps = {
|
|
23
24
|
/**
|
|
@@ -33,9 +34,9 @@ export type MenuItemProps = {
|
|
|
33
34
|
*/
|
|
34
35
|
isSelected?: boolean;
|
|
35
36
|
/**
|
|
36
|
-
* If `true`, the menu item will be visually marked as
|
|
37
|
+
* If `true`, the menu item will be visually marked as disabled.
|
|
37
38
|
*/
|
|
38
|
-
|
|
39
|
+
isDisabled?: boolean;
|
|
39
40
|
/**
|
|
40
41
|
* Callback fired when the menu item is clicked.
|
|
41
42
|
*/
|
|
@@ -50,13 +51,15 @@ export type MenuItemProps = {
|
|
|
50
51
|
* - "destructive": A variant indicating a destructive action.
|
|
51
52
|
*/
|
|
52
53
|
variant?: "default" | "destructive";
|
|
53
|
-
};
|
|
54
|
+
} & SeleniumProps;
|
|
54
55
|
|
|
55
56
|
const MenuItem = ({
|
|
56
57
|
children,
|
|
57
58
|
hasInitialFocus,
|
|
58
59
|
isSelected,
|
|
60
|
+
isDisabled,
|
|
59
61
|
onClick: onClickProp,
|
|
62
|
+
testId,
|
|
60
63
|
value,
|
|
61
64
|
variant = "default",
|
|
62
65
|
}: MenuItemProps) => {
|
|
@@ -74,14 +77,16 @@ const MenuItem = ({
|
|
|
74
77
|
<MuiMenuItem
|
|
75
78
|
/* eslint-disable-next-line jsx-a11y/no-autofocus */
|
|
76
79
|
autoFocus={hasInitialFocus}
|
|
77
|
-
selected={isSelected}
|
|
78
|
-
value={value}
|
|
79
|
-
onClick={onClick}
|
|
80
80
|
className={
|
|
81
81
|
variant === "destructive"
|
|
82
82
|
? `${menuItemClasses.root}-destructive`
|
|
83
83
|
: undefined
|
|
84
84
|
}
|
|
85
|
+
data-se={testId}
|
|
86
|
+
disabled={isDisabled}
|
|
87
|
+
onClick={onClick}
|
|
88
|
+
selected={isSelected}
|
|
89
|
+
value={value}
|
|
85
90
|
>
|
|
86
91
|
{children}
|
|
87
92
|
</MuiMenuItem>
|
package/src/NativeSelect.tsx
CHANGED
|
@@ -15,6 +15,8 @@ import { Select as MuiSelect } from "@mui/material";
|
|
|
15
15
|
import { SelectProps as MuiSelectProps } from "@mui/material";
|
|
16
16
|
import { Field } from "./Field";
|
|
17
17
|
|
|
18
|
+
import type { SeleniumProps } from "./SeleniumProps";
|
|
19
|
+
|
|
18
20
|
export type NativeSelectOption = {
|
|
19
21
|
text: string;
|
|
20
22
|
value?: string;
|
|
@@ -74,7 +76,7 @@ export type NativeSelectProps = {
|
|
|
74
76
|
* The value or values selected in the NativeSelect
|
|
75
77
|
*/
|
|
76
78
|
value?: string | string[];
|
|
77
|
-
};
|
|
79
|
+
} & SeleniumProps;
|
|
78
80
|
|
|
79
81
|
const NativeSelect = forwardRef<HTMLSelectElement, NativeSelectProps>(
|
|
80
82
|
(
|
|
@@ -90,6 +92,7 @@ const NativeSelect = forwardRef<HTMLSelectElement, NativeSelectProps>(
|
|
|
90
92
|
onBlur,
|
|
91
93
|
onChange,
|
|
92
94
|
onFocus,
|
|
95
|
+
testId,
|
|
93
96
|
value,
|
|
94
97
|
children,
|
|
95
98
|
},
|
|
@@ -98,6 +101,7 @@ const NativeSelect = forwardRef<HTMLSelectElement, NativeSelectProps>(
|
|
|
98
101
|
const renderFieldComponent = useCallback(
|
|
99
102
|
() => (
|
|
100
103
|
<MuiSelect
|
|
104
|
+
data-se={testId}
|
|
101
105
|
defaultValue={defaultValue}
|
|
102
106
|
id={idOverride}
|
|
103
107
|
name={idOverride}
|
|
@@ -112,6 +116,7 @@ const NativeSelect = forwardRef<HTMLSelectElement, NativeSelectProps>(
|
|
|
112
116
|
/>
|
|
113
117
|
),
|
|
114
118
|
[
|
|
119
|
+
children,
|
|
115
120
|
defaultValue,
|
|
116
121
|
idOverride,
|
|
117
122
|
isMultiSelect,
|
|
@@ -119,7 +124,7 @@ const NativeSelect = forwardRef<HTMLSelectElement, NativeSelectProps>(
|
|
|
119
124
|
onChange,
|
|
120
125
|
onFocus,
|
|
121
126
|
ref,
|
|
122
|
-
|
|
127
|
+
testId,
|
|
123
128
|
value,
|
|
124
129
|
]
|
|
125
130
|
);
|
|
@@ -24,12 +24,18 @@ import { useUniqueAlphabeticalId } from "./useUniqueAlphabeticalId";
|
|
|
24
24
|
|
|
25
25
|
export type OdysseyCacheProviderProps = {
|
|
26
26
|
children: ReactNode;
|
|
27
|
+
/**
|
|
28
|
+
* Emotion renders into this HTML element.
|
|
29
|
+
* When enabling this prop, Emotion renders at the top of this component rather than the bottom like it does in the HTML `<head>`.
|
|
30
|
+
*/
|
|
31
|
+
emotionRootElement?: HTMLStyleElement;
|
|
27
32
|
nonce?: string;
|
|
28
33
|
stylisPlugins?: StylisPlugin[];
|
|
29
34
|
};
|
|
30
35
|
|
|
31
36
|
const OdysseyCacheProvider = ({
|
|
32
37
|
children,
|
|
38
|
+
emotionRootElement,
|
|
33
39
|
nonce,
|
|
34
40
|
stylisPlugins,
|
|
35
41
|
}: OdysseyCacheProviderProps) => {
|
|
@@ -38,11 +44,13 @@ const OdysseyCacheProvider = ({
|
|
|
38
44
|
const emotionCache = useMemo(
|
|
39
45
|
() =>
|
|
40
46
|
createCache({
|
|
47
|
+
container: emotionRootElement,
|
|
41
48
|
key: uniqueAlphabeticalId,
|
|
42
49
|
nonce: nonce || window.cspNonce,
|
|
50
|
+
prepend: Boolean(emotionRootElement),
|
|
43
51
|
stylisPlugins,
|
|
44
52
|
}),
|
|
45
|
-
[nonce, stylisPlugins, uniqueAlphabeticalId]
|
|
53
|
+
[emotionRootElement, nonce, stylisPlugins, uniqueAlphabeticalId]
|
|
46
54
|
);
|
|
47
55
|
|
|
48
56
|
return <CacheProvider value={emotionCache}>{children}</CacheProvider>;
|
package/src/OdysseyProvider.tsx
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { memo, ReactNode } from "react";
|
|
14
|
+
import { ScopedCssBaseline } from "@mui/material";
|
|
14
15
|
|
|
15
16
|
import {
|
|
16
17
|
OdysseyCacheProvider,
|
|
@@ -34,23 +35,32 @@ export type OdysseyProviderProps = OdysseyCacheProviderProps &
|
|
|
34
35
|
const OdysseyProvider = ({
|
|
35
36
|
children,
|
|
36
37
|
designTokensOverride,
|
|
38
|
+
emotionRootElement,
|
|
39
|
+
shadowRootElement,
|
|
37
40
|
languageCode,
|
|
38
41
|
nonce,
|
|
39
42
|
stylisPlugins,
|
|
40
43
|
themeOverride,
|
|
41
44
|
translationOverrides,
|
|
42
45
|
}: OdysseyProviderProps) => (
|
|
43
|
-
<OdysseyCacheProvider
|
|
46
|
+
<OdysseyCacheProvider
|
|
47
|
+
emotionRootElement={emotionRootElement}
|
|
48
|
+
nonce={nonce}
|
|
49
|
+
stylisPlugins={stylisPlugins}
|
|
50
|
+
>
|
|
44
51
|
<OdysseyThemeProvider
|
|
45
|
-
themeOverride={themeOverride}
|
|
46
52
|
designTokensOverride={designTokensOverride}
|
|
53
|
+
shadowRootElement={shadowRootElement}
|
|
54
|
+
themeOverride={themeOverride}
|
|
47
55
|
>
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
<ScopedCssBaseline>
|
|
57
|
+
<OdysseyTranslationProvider
|
|
58
|
+
languageCode={languageCode}
|
|
59
|
+
translationOverrides={translationOverrides}
|
|
60
|
+
>
|
|
61
|
+
{children}
|
|
62
|
+
</OdysseyTranslationProvider>
|
|
63
|
+
</ScopedCssBaseline>
|
|
54
64
|
</OdysseyThemeProvider>
|
|
55
65
|
</OdysseyCacheProvider>
|
|
56
66
|
);
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from "@mui/material/styles";
|
|
17
17
|
import { memo, ReactNode, useMemo } from "react";
|
|
18
18
|
|
|
19
|
-
import {
|
|
19
|
+
import { ThemeOptions } from "@mui/material";
|
|
20
20
|
import { deepmerge } from "@mui/utils";
|
|
21
21
|
import { createOdysseyMuiTheme, DesignTokensOverride } from "./theme";
|
|
22
22
|
import * as Tokens from "@okta/odyssey-design-tokens";
|
|
@@ -25,12 +25,14 @@ import { OdysseyDesignTokensContext } from "./OdysseyDesignTokensContext";
|
|
|
25
25
|
export type OdysseyThemeProviderProps = {
|
|
26
26
|
children: ReactNode;
|
|
27
27
|
designTokensOverride?: DesignTokensOverride;
|
|
28
|
+
shadowRootElement?: HTMLDivElement;
|
|
28
29
|
themeOverride?: ThemeOptions;
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
const OdysseyThemeProvider = ({
|
|
32
33
|
children,
|
|
33
34
|
designTokensOverride,
|
|
35
|
+
shadowRootElement,
|
|
34
36
|
themeOverride,
|
|
35
37
|
}: OdysseyThemeProviderProps) => {
|
|
36
38
|
const odysseyTokens = useMemo(
|
|
@@ -38,8 +40,12 @@ const OdysseyThemeProvider = ({
|
|
|
38
40
|
[designTokensOverride]
|
|
39
41
|
);
|
|
40
42
|
const odysseyTheme = useMemo(
|
|
41
|
-
() =>
|
|
42
|
-
|
|
43
|
+
() =>
|
|
44
|
+
createOdysseyMuiTheme({
|
|
45
|
+
odysseyTokens,
|
|
46
|
+
shadowRootElement,
|
|
47
|
+
}),
|
|
48
|
+
[odysseyTokens, shadowRootElement]
|
|
43
49
|
);
|
|
44
50
|
|
|
45
51
|
const customOdysseyTheme = useMemo(
|
|
@@ -49,11 +55,9 @@ const OdysseyThemeProvider = ({
|
|
|
49
55
|
|
|
50
56
|
return (
|
|
51
57
|
<MuiThemeProvider theme={customOdysseyTheme ?? odysseyTheme}>
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
</OdysseyDesignTokensContext.Provider>
|
|
56
|
-
</ScopedCssBaseline>
|
|
58
|
+
<OdysseyDesignTokensContext.Provider value={odysseyTokens}>
|
|
59
|
+
{children}
|
|
60
|
+
</OdysseyDesignTokensContext.Provider>
|
|
57
61
|
</MuiThemeProvider>
|
|
58
62
|
);
|
|
59
63
|
};
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
|
|
13
13
|
import { render, screen } from "@testing-library/react";
|
|
14
14
|
import { OdysseyTranslationProvider } from "./OdysseyTranslationProvider";
|
|
15
|
-
import
|
|
15
|
+
import { odysseyTranslate } from "./i18n";
|
|
16
16
|
import { TextField } from "./TextField";
|
|
17
17
|
|
|
18
18
|
describe("OdysseyTranslationProvider", () => {
|
|
19
19
|
it("defaults to 'en' translation bundle", () => {
|
|
20
20
|
render(
|
|
21
21
|
<OdysseyTranslationProvider>
|
|
22
|
-
<span>{
|
|
22
|
+
<span>{odysseyTranslate("fieldlabel.optional.text")}</span>
|
|
23
23
|
</OdysseyTranslationProvider>
|
|
24
24
|
);
|
|
25
25
|
|
|
@@ -14,7 +14,7 @@ import { ReactNode, useEffect } from "react";
|
|
|
14
14
|
|
|
15
15
|
import { SupportedLanguages } from "./OdysseyTranslationProvider.types";
|
|
16
16
|
|
|
17
|
-
import i18n,
|
|
17
|
+
import { i18n, defaultNS, resources } from "./i18n";
|
|
18
18
|
import { I18nextProvider } from "react-i18next";
|
|
19
19
|
|
|
20
20
|
export type TranslationOverrides = {
|
package/src/PasswordField.tsx
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* See the License for the specific language governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { InputAdornment, InputBase } from "@mui/material";
|
|
13
|
+
import { InputAdornment, InputBase, IconButton } from "@mui/material";
|
|
14
14
|
import {
|
|
15
15
|
ChangeEventHandler,
|
|
16
16
|
FocusEventHandler,
|
|
@@ -21,8 +21,9 @@ import {
|
|
|
21
21
|
} from "react";
|
|
22
22
|
|
|
23
23
|
import { ShowIcon, HideIcon } from "./icons.generated";
|
|
24
|
-
import { Button } from "./Button";
|
|
25
24
|
import { Field } from "./Field";
|
|
25
|
+
import type { SeleniumProps } from "./SeleniumProps";
|
|
26
|
+
import { useTranslation } from "react-i18next";
|
|
26
27
|
|
|
27
28
|
export type PasswordFieldProps = {
|
|
28
29
|
/**
|
|
@@ -39,6 +40,10 @@ export type PasswordFieldProps = {
|
|
|
39
40
|
* If `true`, the component will receive focus automatically.
|
|
40
41
|
*/
|
|
41
42
|
hasInitialFocus?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* If `true`, the show/hide icon is not shown to the user
|
|
45
|
+
*/
|
|
46
|
+
hasShowPassword?: boolean;
|
|
42
47
|
/**
|
|
43
48
|
* The helper text content.
|
|
44
49
|
*/
|
|
@@ -63,6 +68,10 @@ export type PasswordFieldProps = {
|
|
|
63
68
|
* The label for the `input` element.
|
|
64
69
|
*/
|
|
65
70
|
label: string;
|
|
71
|
+
/**
|
|
72
|
+
* The name of the `input` element. Defaults to the `id` if not set.
|
|
73
|
+
*/
|
|
74
|
+
name?: string;
|
|
66
75
|
/**
|
|
67
76
|
* Callback fired when the `input` element loses focus.
|
|
68
77
|
*/
|
|
@@ -83,7 +92,7 @@ export type PasswordFieldProps = {
|
|
|
83
92
|
* The value of the `input` element, required for a controlled component.
|
|
84
93
|
*/
|
|
85
94
|
value?: string;
|
|
86
|
-
};
|
|
95
|
+
} & SeleniumProps;
|
|
87
96
|
|
|
88
97
|
const PasswordField = forwardRef<HTMLInputElement, PasswordFieldProps>(
|
|
89
98
|
(
|
|
@@ -95,16 +104,20 @@ const PasswordField = forwardRef<HTMLInputElement, PasswordFieldProps>(
|
|
|
95
104
|
id: idOverride,
|
|
96
105
|
isDisabled = false,
|
|
97
106
|
isOptional = false,
|
|
107
|
+
hasShowPassword = true,
|
|
98
108
|
isReadOnly,
|
|
99
109
|
label,
|
|
110
|
+
name: nameOverride,
|
|
100
111
|
onChange,
|
|
101
112
|
onFocus,
|
|
102
113
|
onBlur,
|
|
103
114
|
placeholder,
|
|
115
|
+
testId,
|
|
104
116
|
value,
|
|
105
117
|
},
|
|
106
118
|
ref
|
|
107
119
|
) => {
|
|
120
|
+
const { t } = useTranslation();
|
|
108
121
|
const [inputType, setInputType] = useState("password");
|
|
109
122
|
|
|
110
123
|
const togglePasswordVisibility = useCallback(() => {
|
|
@@ -120,19 +133,26 @@ const PasswordField = forwardRef<HTMLInputElement, PasswordFieldProps>(
|
|
|
120
133
|
autoComplete={autoCompleteType}
|
|
121
134
|
/* eslint-disable-next-line jsx-a11y/no-autofocus */
|
|
122
135
|
autoFocus={hasInitialFocus}
|
|
136
|
+
data-se={testId}
|
|
123
137
|
endAdornment={
|
|
124
|
-
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
138
|
+
hasShowPassword && (
|
|
139
|
+
<InputAdornment position="end">
|
|
140
|
+
<IconButton
|
|
141
|
+
aria-label={
|
|
142
|
+
inputType === "password"
|
|
143
|
+
? t("passwordfield.icon.label.show")
|
|
144
|
+
: t("passwordfield.icon.label.hide")
|
|
145
|
+
}
|
|
146
|
+
onClick={togglePasswordVisibility}
|
|
147
|
+
>
|
|
148
|
+
{inputType === "password" ? <ShowIcon /> : <HideIcon />}
|
|
149
|
+
</IconButton>
|
|
150
|
+
</InputAdornment>
|
|
151
|
+
)
|
|
133
152
|
}
|
|
134
153
|
id={id}
|
|
135
|
-
|
|
154
|
+
inputProps={{ role: "textbox" }}
|
|
155
|
+
name={nameOverride ?? id}
|
|
136
156
|
onChange={onChange}
|
|
137
157
|
onFocus={onFocus}
|
|
138
158
|
onBlur={onBlur}
|
|
@@ -147,15 +167,19 @@ const PasswordField = forwardRef<HTMLInputElement, PasswordFieldProps>(
|
|
|
147
167
|
[
|
|
148
168
|
autoCompleteType,
|
|
149
169
|
hasInitialFocus,
|
|
170
|
+
t,
|
|
150
171
|
togglePasswordVisibility,
|
|
151
172
|
inputType,
|
|
173
|
+
nameOverride,
|
|
152
174
|
onChange,
|
|
153
175
|
onFocus,
|
|
154
176
|
onBlur,
|
|
155
177
|
placeholder,
|
|
156
178
|
isOptional,
|
|
157
179
|
isReadOnly,
|
|
180
|
+
hasShowPassword,
|
|
158
181
|
ref,
|
|
182
|
+
testId,
|
|
159
183
|
value,
|
|
160
184
|
]
|
|
161
185
|
);
|
package/src/Radio.tsx
CHANGED
|
@@ -15,6 +15,8 @@ import { memo } from "react";
|
|
|
15
15
|
|
|
16
16
|
import { FormControlLabel } from "@mui/material";
|
|
17
17
|
|
|
18
|
+
import type { SeleniumProps } from "./SeleniumProps";
|
|
19
|
+
|
|
18
20
|
export type RadioProps = {
|
|
19
21
|
/**
|
|
20
22
|
* If `true`, the Radio is selected
|
|
@@ -40,7 +42,7 @@ export type RadioProps = {
|
|
|
40
42
|
* The value attribute of the Radio
|
|
41
43
|
*/
|
|
42
44
|
value: string;
|
|
43
|
-
};
|
|
45
|
+
} & SeleniumProps;
|
|
44
46
|
|
|
45
47
|
const Radio = ({
|
|
46
48
|
isChecked,
|
|
@@ -48,12 +50,14 @@ const Radio = ({
|
|
|
48
50
|
isInvalid,
|
|
49
51
|
label,
|
|
50
52
|
name,
|
|
53
|
+
testId,
|
|
51
54
|
value,
|
|
52
55
|
}: RadioProps) => (
|
|
53
56
|
<FormControlLabel
|
|
54
57
|
checked={isChecked}
|
|
55
58
|
className={isInvalid ? "Mui-error" : ""}
|
|
56
59
|
control={<MuiRadio />}
|
|
60
|
+
data-se={testId}
|
|
57
61
|
disabled={isDisabled}
|
|
58
62
|
label={label}
|
|
59
63
|
name={name}
|
package/src/RadioGroup.tsx
CHANGED
|
@@ -15,6 +15,7 @@ import { ChangeEventHandler, memo, ReactElement, useCallback } from "react";
|
|
|
15
15
|
|
|
16
16
|
import { Radio, RadioProps } from "./Radio";
|
|
17
17
|
import { Field } from "./Field";
|
|
18
|
+
import type { SeleniumProps } from "./SeleniumProps";
|
|
18
19
|
|
|
19
20
|
export type RadioGroupProps = {
|
|
20
21
|
/**
|
|
@@ -34,7 +35,7 @@ export type RadioGroupProps = {
|
|
|
34
35
|
*/
|
|
35
36
|
hint?: string;
|
|
36
37
|
/**
|
|
37
|
-
* The id of the `input` element.
|
|
38
|
+
* The id of the `input` element.
|
|
38
39
|
*/
|
|
39
40
|
id?: string;
|
|
40
41
|
/**
|
|
@@ -45,6 +46,10 @@ export type RadioGroupProps = {
|
|
|
45
46
|
* The text label for the RadioGroup
|
|
46
47
|
*/
|
|
47
48
|
label: string;
|
|
49
|
+
/**
|
|
50
|
+
* The name of the `input` element. Defaults to the `id` if not set.
|
|
51
|
+
*/
|
|
52
|
+
name?: string;
|
|
48
53
|
/**
|
|
49
54
|
* Listen for changes in the browser that change `value`
|
|
50
55
|
*/
|
|
@@ -53,7 +58,7 @@ export type RadioGroupProps = {
|
|
|
53
58
|
* The `value` on the selected Radio
|
|
54
59
|
*/
|
|
55
60
|
value?: RadioProps["value"];
|
|
56
|
-
};
|
|
61
|
+
} & SeleniumProps;
|
|
57
62
|
|
|
58
63
|
const RadioGroup = ({
|
|
59
64
|
children,
|
|
@@ -63,23 +68,26 @@ const RadioGroup = ({
|
|
|
63
68
|
id: idOverride,
|
|
64
69
|
isDisabled,
|
|
65
70
|
label,
|
|
71
|
+
name: nameOverride,
|
|
66
72
|
onChange,
|
|
73
|
+
testId,
|
|
67
74
|
value,
|
|
68
75
|
}: RadioGroupProps) => {
|
|
69
76
|
const renderFieldComponent = useCallback(
|
|
70
77
|
({ ariaDescribedBy, id }) => (
|
|
71
78
|
<MuiRadioGroup
|
|
72
79
|
aria-describedby={ariaDescribedBy}
|
|
80
|
+
data-se={testId}
|
|
73
81
|
defaultValue={defaultValue}
|
|
74
82
|
id={id}
|
|
75
|
-
name={id}
|
|
83
|
+
name={nameOverride ?? id}
|
|
76
84
|
onChange={onChange}
|
|
77
85
|
value={value}
|
|
78
86
|
>
|
|
79
87
|
{children}
|
|
80
88
|
</MuiRadioGroup>
|
|
81
89
|
),
|
|
82
|
-
[children, defaultValue, onChange, value]
|
|
90
|
+
[children, defaultValue, nameOverride, onChange, testId, value]
|
|
83
91
|
);
|
|
84
92
|
|
|
85
93
|
return (
|