@okta/odyssey-react-mui 0.19.0 → 0.21.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 +110 -4
- package/dist/MenuButton.d.ts +34 -0
- package/dist/MenuButton.d.ts.map +1 -0
- package/dist/MenuButton.js +62 -0
- package/dist/MenuButton.js.map +1 -0
- package/dist/MenuItem.d.ts +22 -0
- package/dist/MenuItem.d.ts.map +1 -0
- package/dist/MenuItem.js +31 -0
- package/dist/MenuItem.js.map +1 -0
- package/dist/PasswordInput.d.ts +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/theme/components.d.ts +1 -1
- package/dist/theme/components.d.ts.map +1 -1
- package/dist/theme/components.js +167 -99
- package/dist/theme/components.js.map +1 -1
- package/package.json +5 -4
- package/src/MenuButton.tsx +99 -0
- package/src/MenuItem.tsx +50 -0
- package/src/index.ts +10 -2
- package/src/theme/components.tsx +87 -13
|
@@ -0,0 +1,99 @@
|
|
|
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 {
|
|
14
|
+
Button,
|
|
15
|
+
ButtonProps,
|
|
16
|
+
ChevronDownIcon,
|
|
17
|
+
Divider,
|
|
18
|
+
ListSubheader,
|
|
19
|
+
Menu,
|
|
20
|
+
MenuItem,
|
|
21
|
+
useUniqueId,
|
|
22
|
+
} from "./";
|
|
23
|
+
import { memo, MouseEvent, ReactElement, useMemo, useState } from "react";
|
|
24
|
+
|
|
25
|
+
export interface MenuButtonProps {
|
|
26
|
+
/**
|
|
27
|
+
* The <MenuItem> components within the Menu.
|
|
28
|
+
*/
|
|
29
|
+
children: Array<
|
|
30
|
+
ReactElement<typeof MenuItem | typeof Divider | typeof ListSubheader>
|
|
31
|
+
>;
|
|
32
|
+
/**
|
|
33
|
+
* The end Icon on the trigggering Button
|
|
34
|
+
*/
|
|
35
|
+
buttonEndIcon?: ReactElement;
|
|
36
|
+
/**
|
|
37
|
+
* The label on the triggering Button
|
|
38
|
+
*/
|
|
39
|
+
buttonLabel?: string;
|
|
40
|
+
/**
|
|
41
|
+
* The variant of the triggering Button
|
|
42
|
+
*/
|
|
43
|
+
buttonVariant?: ButtonProps["variant"];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const MenuButton = ({
|
|
47
|
+
buttonLabel = "",
|
|
48
|
+
children,
|
|
49
|
+
buttonEndIcon = <ChevronDownIcon />,
|
|
50
|
+
buttonVariant = "secondary",
|
|
51
|
+
}: MenuButtonProps) => {
|
|
52
|
+
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
|
53
|
+
|
|
54
|
+
const open = Boolean(anchorEl);
|
|
55
|
+
|
|
56
|
+
const handleClick = (event: MouseEvent<HTMLButtonElement>) => {
|
|
57
|
+
setAnchorEl(event.currentTarget);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleClose = () => {
|
|
61
|
+
setAnchorEl(null);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const uniqueId = useUniqueId();
|
|
65
|
+
|
|
66
|
+
const menuListProps = useMemo(
|
|
67
|
+
() => ({ "aria-labelledby": `${uniqueId}-button` }),
|
|
68
|
+
[uniqueId]
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<div>
|
|
73
|
+
<Button
|
|
74
|
+
endIcon={buttonEndIcon}
|
|
75
|
+
id={`${uniqueId}-button`}
|
|
76
|
+
aria-controls={open ? `${uniqueId}-menu` : undefined}
|
|
77
|
+
aria-haspopup="true"
|
|
78
|
+
aria-expanded={open ? "true" : undefined}
|
|
79
|
+
onClick={handleClick}
|
|
80
|
+
variant={buttonVariant}
|
|
81
|
+
>
|
|
82
|
+
{buttonLabel}
|
|
83
|
+
</Button>
|
|
84
|
+
<Menu
|
|
85
|
+
id={`${uniqueId}-menu`}
|
|
86
|
+
anchorEl={anchorEl}
|
|
87
|
+
open={open}
|
|
88
|
+
onClose={handleClose}
|
|
89
|
+
MenuListProps={menuListProps}
|
|
90
|
+
>
|
|
91
|
+
{children}
|
|
92
|
+
</Menu>
|
|
93
|
+
</div>
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const MemoizedMenuButton = memo(MenuButton);
|
|
98
|
+
|
|
99
|
+
export { MemoizedMenuButton as MenuButton };
|
package/src/MenuItem.tsx
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
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, forwardRef } from "react";
|
|
14
|
+
import { MenuItem as MuiMenuItem } from "@mui/material";
|
|
15
|
+
import { menuItemClasses } from "@mui/material/MenuItem";
|
|
16
|
+
import type { MenuItemProps as MuiMenuItemProps } from "@mui/material";
|
|
17
|
+
|
|
18
|
+
export interface MenuItemProps
|
|
19
|
+
extends Omit<
|
|
20
|
+
MuiMenuItemProps,
|
|
21
|
+
| "component"
|
|
22
|
+
| "dense"
|
|
23
|
+
| "disableGutters"
|
|
24
|
+
| "divider"
|
|
25
|
+
| "focusVisibleClassName"
|
|
26
|
+
> {
|
|
27
|
+
/**
|
|
28
|
+
* Toggles whether or not the MenuItem represents a destructive action.
|
|
29
|
+
*/
|
|
30
|
+
isDestructive?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const MenuItem = forwardRef<HTMLLIElement, MenuItemProps>(
|
|
34
|
+
({ isDestructive, ...props }, ref) => (
|
|
35
|
+
<MuiMenuItem
|
|
36
|
+
{...props}
|
|
37
|
+
ref={ref}
|
|
38
|
+
className={
|
|
39
|
+
isDestructive ? `${menuItemClasses.root}-destructive` : undefined
|
|
40
|
+
}
|
|
41
|
+
>
|
|
42
|
+
{props.children}
|
|
43
|
+
</MuiMenuItem>
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const MemoizedMenuItem = memo(MenuItem);
|
|
48
|
+
MemoizedMenuItem.displayName = "MenuItem";
|
|
49
|
+
|
|
50
|
+
export { MemoizedMenuItem as MenuItem };
|
package/src/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ export {
|
|
|
24
24
|
DialogContent,
|
|
25
25
|
DialogContentText,
|
|
26
26
|
DialogTitle,
|
|
27
|
+
Divider,
|
|
27
28
|
FormControl,
|
|
28
29
|
FormControlLabel,
|
|
29
30
|
FormGroup,
|
|
@@ -38,7 +39,9 @@ export {
|
|
|
38
39
|
ListItemIcon,
|
|
39
40
|
ListItemText,
|
|
40
41
|
ListSubheader,
|
|
41
|
-
|
|
42
|
+
Menu,
|
|
43
|
+
MenuList,
|
|
44
|
+
Paper,
|
|
42
45
|
ScopedCssBaseline,
|
|
43
46
|
Select,
|
|
44
47
|
Snackbar,
|
|
@@ -72,6 +75,7 @@ export type {
|
|
|
72
75
|
DialogContentProps,
|
|
73
76
|
DialogContentTextProps,
|
|
74
77
|
DialogTitleProps,
|
|
78
|
+
DividerProps,
|
|
75
79
|
FormControlLabelProps,
|
|
76
80
|
FormControlProps,
|
|
77
81
|
FormGroupProps,
|
|
@@ -86,7 +90,9 @@ export type {
|
|
|
86
90
|
ListItemIconProps,
|
|
87
91
|
ListItemTextProps,
|
|
88
92
|
ListSubheaderProps,
|
|
89
|
-
|
|
93
|
+
MenuProps,
|
|
94
|
+
MenuListProps,
|
|
95
|
+
PaperProps,
|
|
90
96
|
ScopedCssBaselineProps,
|
|
91
97
|
SelectChangeEvent,
|
|
92
98
|
SelectProps,
|
|
@@ -121,6 +127,8 @@ export * from "./Icon";
|
|
|
121
127
|
export * from "./iconDictionary";
|
|
122
128
|
export * from "./Infobox";
|
|
123
129
|
export * from "./Link";
|
|
130
|
+
export * from "./MenuButton";
|
|
131
|
+
export * from "./MenuItem";
|
|
124
132
|
export * from "./OdysseyCacheProvider";
|
|
125
133
|
export * from "./OdysseyThemeProvider";
|
|
126
134
|
export * from "./PasswordInput";
|
package/src/theme/components.tsx
CHANGED
|
@@ -10,13 +10,18 @@
|
|
|
10
10
|
* See the License for the specific language governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import
|
|
13
|
+
import { ThemeOptions } from "@mui/material";
|
|
14
14
|
import type {} from "@mui/lab/themeAugmentation";
|
|
15
15
|
//import radioClasses from "@mui/material";
|
|
16
|
+
import { buttonClasses } from "@mui/material/Button";
|
|
16
17
|
import { chipClasses } from "@mui/material/Chip";
|
|
17
18
|
import { dialogActionsClasses } from "@mui/material/DialogActions";
|
|
19
|
+
import { dividerClasses } from "@mui/material/Divider";
|
|
18
20
|
import { inputAdornmentClasses } from "@mui/material/InputAdornment";
|
|
19
21
|
import { inputBaseClasses } from "@mui/material/InputBase";
|
|
22
|
+
import { listItemIconClasses } from "@mui/material/ListItemIcon";
|
|
23
|
+
import { listItemTextClasses } from "@mui/material/ListItemText";
|
|
24
|
+
import { menuItemClasses } from "@mui/material/MenuItem";
|
|
20
25
|
import { svgIconClasses } from "@mui/material/SvgIcon";
|
|
21
26
|
import { tableBodyClasses } from "@mui/material/TableBody";
|
|
22
27
|
import { tableCellClasses } from "@mui/material/TableCell";
|
|
@@ -292,7 +297,7 @@ export const components: ThemeOptions["components"] = {
|
|
|
292
297
|
style: {
|
|
293
298
|
minWidth: "auto",
|
|
294
299
|
|
|
295
|
-
|
|
300
|
+
[`.${buttonClasses.endIcon}, .${buttonClasses.startIcon}`]: {
|
|
296
301
|
margin: "0",
|
|
297
302
|
},
|
|
298
303
|
},
|
|
@@ -335,18 +340,31 @@ export const components: ThemeOptions["components"] = {
|
|
|
335
340
|
pointerEvents: "inherit", // in order to have cursor: not-allowed, must change pointer-events from "none"
|
|
336
341
|
},
|
|
337
342
|
|
|
338
|
-
|
|
339
|
-
|
|
343
|
+
[`.${buttonClasses.startIcon}, .${buttonClasses.endIcon}`]: {
|
|
344
|
+
"& > *:nth-of-type(1)": {
|
|
345
|
+
fontSize: `${theme.typography.ui.lineHeight}em`,
|
|
346
|
+
},
|
|
340
347
|
},
|
|
341
348
|
}),
|
|
342
|
-
|
|
349
|
+
|
|
350
|
+
endIcon: ({ theme, ownerState }) => ({
|
|
351
|
+
display: "inline-flex",
|
|
352
|
+
margin: 0,
|
|
353
|
+
marginInlineStart: theme.spacing(2),
|
|
354
|
+
|
|
355
|
+
...(ownerState.children === undefined && {
|
|
356
|
+
marginInlineStart: 0,
|
|
357
|
+
}),
|
|
358
|
+
}),
|
|
359
|
+
|
|
360
|
+
startIcon: ({ theme, ownerState }) => ({
|
|
343
361
|
display: "inline-flex",
|
|
344
362
|
margin: 0,
|
|
345
363
|
marginInlineEnd: theme.spacing(2),
|
|
346
364
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
},
|
|
365
|
+
...(ownerState.children === undefined && {
|
|
366
|
+
marginInlineEnd: 0,
|
|
367
|
+
}),
|
|
350
368
|
}),
|
|
351
369
|
},
|
|
352
370
|
},
|
|
@@ -735,7 +753,7 @@ export const components: ThemeOptions["components"] = {
|
|
|
735
753
|
},
|
|
736
754
|
},
|
|
737
755
|
|
|
738
|
-
"ul, ol": {
|
|
756
|
+
"ul:not([class]), ol:not([class])": {
|
|
739
757
|
maxWidth: theme.mixins.maxWidth,
|
|
740
758
|
marginBlockStart: 0,
|
|
741
759
|
marginBlockEnd: theme.spacing(4),
|
|
@@ -755,7 +773,7 @@ export const components: ThemeOptions["components"] = {
|
|
|
755
773
|
},
|
|
756
774
|
},
|
|
757
775
|
|
|
758
|
-
li: {
|
|
776
|
+
"li:not([class])": {
|
|
759
777
|
marginBlockEnd: theme.spacing(2),
|
|
760
778
|
paddingInlineStart: theme.spacing(1),
|
|
761
779
|
|
|
@@ -1263,6 +1281,7 @@ export const components: ThemeOptions["components"] = {
|
|
|
1263
1281
|
paddingBlock: theme.spacing(2),
|
|
1264
1282
|
paddingInline: theme.spacing(4),
|
|
1265
1283
|
fontSize: theme.typography.caption.fontSize,
|
|
1284
|
+
fontWeight: theme.typography.fontWeightBold,
|
|
1266
1285
|
lineHeight: theme.typography.caption.lineHeight,
|
|
1267
1286
|
color: theme.palette.text.secondary,
|
|
1268
1287
|
textTransform: "uppercase",
|
|
@@ -1271,21 +1290,73 @@ export const components: ThemeOptions["components"] = {
|
|
|
1271
1290
|
},
|
|
1272
1291
|
MuiMenuItem: {
|
|
1273
1292
|
styleOverrides: {
|
|
1274
|
-
root: ({ theme }) => ({
|
|
1275
|
-
justifyContent: "space-between",
|
|
1293
|
+
root: ({ theme, ownerState }) => ({
|
|
1276
1294
|
gap: theme.spacing(2),
|
|
1295
|
+
minHeight: "unset",
|
|
1296
|
+
paddingBlock: theme.spacing(3),
|
|
1277
1297
|
|
|
1278
|
-
"
|
|
1298
|
+
"&:hover": {
|
|
1299
|
+
textDecoration: "none",
|
|
1300
|
+
backgroundColor: theme.palette.grey[100],
|
|
1301
|
+
|
|
1302
|
+
// Reset on touch devices, it doesn't add specificity
|
|
1303
|
+
"@media (hover: none)": {
|
|
1304
|
+
backgroundColor: "transparent",
|
|
1305
|
+
},
|
|
1306
|
+
},
|
|
1307
|
+
|
|
1308
|
+
[`&.${menuItemClasses.root}-destructive`]: {
|
|
1309
|
+
color: theme.palette.error.main,
|
|
1310
|
+
},
|
|
1311
|
+
|
|
1312
|
+
[`&.${menuItemClasses.selected}`]: {
|
|
1279
1313
|
backgroundColor: "transparent",
|
|
1280
1314
|
color: theme.palette.primary.main,
|
|
1281
1315
|
|
|
1282
1316
|
"&:hover": {
|
|
1283
1317
|
backgroundColor: theme.palette.primary.lighter,
|
|
1318
|
+
|
|
1319
|
+
"@media (hover: none)": {
|
|
1320
|
+
backgroundColor: `rgba(${theme.palette.primary.main} / ${theme.palette.action.selectedOpacity})`,
|
|
1321
|
+
},
|
|
1284
1322
|
},
|
|
1285
1323
|
},
|
|
1324
|
+
|
|
1325
|
+
...(!ownerState.disableGutters && {
|
|
1326
|
+
paddingInline: theme.spacing(4),
|
|
1327
|
+
}),
|
|
1328
|
+
|
|
1329
|
+
...(ownerState.divider && {
|
|
1330
|
+
borderBlockEnd: `1px solid ${theme.palette.divider}`,
|
|
1331
|
+
}),
|
|
1332
|
+
|
|
1333
|
+
[`&.${menuItemClasses.disabled}`]: {
|
|
1334
|
+
opacity: 1,
|
|
1335
|
+
color: theme.palette.text.disabled,
|
|
1336
|
+
},
|
|
1337
|
+
|
|
1338
|
+
[`& + .${dividerClasses.root}`]: {
|
|
1339
|
+
marginBlock: theme.spacing(1),
|
|
1340
|
+
},
|
|
1341
|
+
|
|
1342
|
+
[`& .${listItemTextClasses.root}`]: {
|
|
1343
|
+
marginBlock: 0,
|
|
1344
|
+
},
|
|
1345
|
+
|
|
1346
|
+
[`& .${listItemIconClasses.root}`]: {
|
|
1347
|
+
minWidth: "unset",
|
|
1348
|
+
},
|
|
1286
1349
|
}),
|
|
1287
1350
|
},
|
|
1288
1351
|
},
|
|
1352
|
+
MuiListItemIcon: {
|
|
1353
|
+
styleOverrides: {
|
|
1354
|
+
root: {
|
|
1355
|
+
minWidth: "unset",
|
|
1356
|
+
color: "inherit",
|
|
1357
|
+
},
|
|
1358
|
+
},
|
|
1359
|
+
},
|
|
1289
1360
|
MuiNativeSelect: {
|
|
1290
1361
|
defaultProps: {
|
|
1291
1362
|
variant: "standard",
|
|
@@ -1306,6 +1377,9 @@ export const components: ThemeOptions["components"] = {
|
|
|
1306
1377
|
styleOverrides: {
|
|
1307
1378
|
paper: ({ theme }) => ({
|
|
1308
1379
|
marginBlockStart: theme.spacing(1),
|
|
1380
|
+
borderWidth: theme.mixins.borderWidth,
|
|
1381
|
+
borderStyle: theme.mixins.borderStyle,
|
|
1382
|
+
borderColor: theme.palette.grey[200],
|
|
1309
1383
|
}),
|
|
1310
1384
|
},
|
|
1311
1385
|
},
|