@okta/odyssey-react-mui 0.19.0 → 0.20.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 +65 -0
- 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 +159 -99
- package/dist/theme/components.js.map +1 -1
- package/package.json +3 -3
- package/src/MenuButton.tsx +99 -0
- package/src/MenuItem.tsx +50 -0
- package/src/index.ts +10 -2
- package/src/theme/components.tsx +79 -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,23 @@ 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
|
}),
|
|
349
|
+
|
|
350
|
+
endIcon: ({ theme }) => ({
|
|
351
|
+
display: "inline-flex",
|
|
352
|
+
margin: 0,
|
|
353
|
+
marginInlineStart: theme.spacing(2),
|
|
354
|
+
}),
|
|
355
|
+
|
|
342
356
|
startIcon: ({ theme }) => ({
|
|
343
357
|
display: "inline-flex",
|
|
344
358
|
margin: 0,
|
|
345
359
|
marginInlineEnd: theme.spacing(2),
|
|
346
|
-
|
|
347
|
-
"&:only-child": {
|
|
348
|
-
margin: 0,
|
|
349
|
-
},
|
|
350
360
|
}),
|
|
351
361
|
},
|
|
352
362
|
},
|
|
@@ -735,7 +745,7 @@ export const components: ThemeOptions["components"] = {
|
|
|
735
745
|
},
|
|
736
746
|
},
|
|
737
747
|
|
|
738
|
-
"ul, ol": {
|
|
748
|
+
"ul:not([class]), ol:not([class])": {
|
|
739
749
|
maxWidth: theme.mixins.maxWidth,
|
|
740
750
|
marginBlockStart: 0,
|
|
741
751
|
marginBlockEnd: theme.spacing(4),
|
|
@@ -755,7 +765,7 @@ export const components: ThemeOptions["components"] = {
|
|
|
755
765
|
},
|
|
756
766
|
},
|
|
757
767
|
|
|
758
|
-
li: {
|
|
768
|
+
"li:not([class])": {
|
|
759
769
|
marginBlockEnd: theme.spacing(2),
|
|
760
770
|
paddingInlineStart: theme.spacing(1),
|
|
761
771
|
|
|
@@ -1263,6 +1273,7 @@ export const components: ThemeOptions["components"] = {
|
|
|
1263
1273
|
paddingBlock: theme.spacing(2),
|
|
1264
1274
|
paddingInline: theme.spacing(4),
|
|
1265
1275
|
fontSize: theme.typography.caption.fontSize,
|
|
1276
|
+
fontWeight: theme.typography.fontWeightBold,
|
|
1266
1277
|
lineHeight: theme.typography.caption.lineHeight,
|
|
1267
1278
|
color: theme.palette.text.secondary,
|
|
1268
1279
|
textTransform: "uppercase",
|
|
@@ -1271,21 +1282,73 @@ export const components: ThemeOptions["components"] = {
|
|
|
1271
1282
|
},
|
|
1272
1283
|
MuiMenuItem: {
|
|
1273
1284
|
styleOverrides: {
|
|
1274
|
-
root: ({ theme }) => ({
|
|
1275
|
-
justifyContent: "space-between",
|
|
1285
|
+
root: ({ theme, ownerState }) => ({
|
|
1276
1286
|
gap: theme.spacing(2),
|
|
1287
|
+
minHeight: "unset",
|
|
1288
|
+
paddingBlock: theme.spacing(3),
|
|
1277
1289
|
|
|
1278
|
-
"
|
|
1290
|
+
"&:hover": {
|
|
1291
|
+
textDecoration: "none",
|
|
1292
|
+
backgroundColor: theme.palette.grey[100],
|
|
1293
|
+
|
|
1294
|
+
// Reset on touch devices, it doesn't add specificity
|
|
1295
|
+
"@media (hover: none)": {
|
|
1296
|
+
backgroundColor: "transparent",
|
|
1297
|
+
},
|
|
1298
|
+
},
|
|
1299
|
+
|
|
1300
|
+
[`&.${menuItemClasses.root}-destructive`]: {
|
|
1301
|
+
color: theme.palette.error.main,
|
|
1302
|
+
},
|
|
1303
|
+
|
|
1304
|
+
[`&.${menuItemClasses.selected}`]: {
|
|
1279
1305
|
backgroundColor: "transparent",
|
|
1280
1306
|
color: theme.palette.primary.main,
|
|
1281
1307
|
|
|
1282
1308
|
"&:hover": {
|
|
1283
1309
|
backgroundColor: theme.palette.primary.lighter,
|
|
1310
|
+
|
|
1311
|
+
"@media (hover: none)": {
|
|
1312
|
+
backgroundColor: `rgba(${theme.palette.primary.main} / ${theme.palette.action.selectedOpacity})`,
|
|
1313
|
+
},
|
|
1284
1314
|
},
|
|
1285
1315
|
},
|
|
1316
|
+
|
|
1317
|
+
...(!ownerState.disableGutters && {
|
|
1318
|
+
paddingInline: theme.spacing(4),
|
|
1319
|
+
}),
|
|
1320
|
+
|
|
1321
|
+
...(ownerState.divider && {
|
|
1322
|
+
borderBlockEnd: `1px solid ${theme.palette.divider}`,
|
|
1323
|
+
}),
|
|
1324
|
+
|
|
1325
|
+
[`&.${menuItemClasses.disabled}`]: {
|
|
1326
|
+
opacity: 1,
|
|
1327
|
+
color: theme.palette.text.disabled,
|
|
1328
|
+
},
|
|
1329
|
+
|
|
1330
|
+
[`& + .${dividerClasses.root}`]: {
|
|
1331
|
+
marginBlock: theme.spacing(1),
|
|
1332
|
+
},
|
|
1333
|
+
|
|
1334
|
+
[`& .${listItemTextClasses.root}`]: {
|
|
1335
|
+
marginBlock: 0,
|
|
1336
|
+
},
|
|
1337
|
+
|
|
1338
|
+
[`& .${listItemIconClasses.root}`]: {
|
|
1339
|
+
minWidth: "unset",
|
|
1340
|
+
},
|
|
1286
1341
|
}),
|
|
1287
1342
|
},
|
|
1288
1343
|
},
|
|
1344
|
+
MuiListItemIcon: {
|
|
1345
|
+
styleOverrides: {
|
|
1346
|
+
root: {
|
|
1347
|
+
minWidth: "unset",
|
|
1348
|
+
color: "inherit",
|
|
1349
|
+
},
|
|
1350
|
+
},
|
|
1351
|
+
},
|
|
1289
1352
|
MuiNativeSelect: {
|
|
1290
1353
|
defaultProps: {
|
|
1291
1354
|
variant: "standard",
|
|
@@ -1306,6 +1369,9 @@ export const components: ThemeOptions["components"] = {
|
|
|
1306
1369
|
styleOverrides: {
|
|
1307
1370
|
paper: ({ theme }) => ({
|
|
1308
1371
|
marginBlockStart: theme.spacing(1),
|
|
1372
|
+
borderWidth: theme.mixins.borderWidth,
|
|
1373
|
+
borderStyle: theme.mixins.borderStyle,
|
|
1374
|
+
borderColor: theme.palette.grey[200],
|
|
1309
1375
|
}),
|
|
1310
1376
|
},
|
|
1311
1377
|
},
|