better-mui-menu 1.5.0 → 1.5.2
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/README.md +14 -11
- package/dist/index.cjs +55 -26
- package/dist/index.js +55 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -80,14 +80,17 @@ export function FileMenu() {
|
|
|
80
80
|
}
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
##
|
|
84
|
-
|
|
85
|
-
`MenuItem` extends `@mui/material/MenuItemProps` (excluding `children`) so you can still pass `
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
83
|
+
## MenuItem Reference
|
|
84
|
+
|
|
85
|
+
`MenuItem` extends `@mui/material/MenuItemProps` (excluding `children`) so you can still pass `disabled`, `sx`, `aria-*`, `data-*`, etc.
|
|
86
|
+
|
|
87
|
+
| Field | Applies to | Type / values | Required | Default | Notes |
|
|
88
|
+
| --- | --- | --- | --- | --- | --- |
|
|
89
|
+
| `type` | all entries | `'item' \| 'divider' \| 'header'` | no | `'item'` | Use `'divider'` for separators, `'header'` for section labels. |
|
|
90
|
+
| `id` | `'item'` | string | no | auto-generated | Used for stable ARIA/menu item IDs. |
|
|
91
|
+
| `label` | `'item'`, `'header'` | text or JSX | yes (`'item'`, `'header'`) | none | Not used for `'divider'`. |
|
|
92
|
+
| `startIcon` | `'item'` | MUI Icon or JSX | no | none | Example: `Save` or `<Save fontSize='small' />`. |
|
|
93
|
+
| `endIcon` | `'item'` | MUI Icon or JSX | no | none | For submenu triggers, a right-arrow icon is shown when omitted. |
|
|
94
|
+
| `items` | `'item'` | `MenuItem[]` | no | none | If present and non-empty, renders a nested submenu. |
|
|
95
|
+
| `onClick` | `'item'` | function | no | none | Runs on leaf item click; menu stack closes afterward. |
|
|
96
|
+
| `...MenuItemProps` | `'item'` | MUI `MenuItem` props (except `children`, `type`) | no | MUI defaults | Example: `disabled`, `dense`, `selected`, `data-*`. |
|
package/dist/index.cjs
CHANGED
|
@@ -42,6 +42,8 @@ var ArrowRight_default = (0, import_utils.createSvgIcon)(/* @__PURE__ */ (0, imp
|
|
|
42
42
|
|
|
43
43
|
// src/Menu/NestedMenuItem.tsx
|
|
44
44
|
var import_material3 = require("@mui/material");
|
|
45
|
+
var import_Menu = require("@mui/material/Menu");
|
|
46
|
+
var import_styles = require("@mui/material/styles");
|
|
45
47
|
|
|
46
48
|
// src/Menu/MenuEntry.tsx
|
|
47
49
|
var import_react = require("react");
|
|
@@ -83,6 +85,16 @@ var MenuEntry = (0, import_react.forwardRef)(function MenuEntry2({ label, startI
|
|
|
83
85
|
// src/Menu/NestedMenuItem.tsx
|
|
84
86
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
85
87
|
var isNodeInstance = (target) => target instanceof Node;
|
|
88
|
+
var SubMenuPaper = (0, import_styles.styled)(import_material3.Paper, {
|
|
89
|
+
name: "MuiMenu",
|
|
90
|
+
slot: "Paper",
|
|
91
|
+
overridesResolver: (_, styles) => styles.paper
|
|
92
|
+
})({});
|
|
93
|
+
var SubMenuList = (0, import_styles.styled)(import_material3.MenuList, {
|
|
94
|
+
name: "MuiMenu",
|
|
95
|
+
slot: "List",
|
|
96
|
+
overridesResolver: (_, styles) => styles.list
|
|
97
|
+
})({});
|
|
86
98
|
var NestedMenuItem = (props) => {
|
|
87
99
|
const {
|
|
88
100
|
id: providedId,
|
|
@@ -206,6 +218,10 @@ var NestedMenuItem = (props) => {
|
|
|
206
218
|
});
|
|
207
219
|
};
|
|
208
220
|
const renderedSubMenuItems = items && items.length > 0 ? renderItemsFromData() : renderChildren;
|
|
221
|
+
const subMenuPaperProps = menuProps?.slotProps?.paper || {};
|
|
222
|
+
const { className: subMenuPaperClassName, ...subMenuPaperRestProps } = subMenuPaperProps;
|
|
223
|
+
const subMenuListProps = menuProps?.slotProps?.list || {};
|
|
224
|
+
const { className: subMenuListClassName, ...subMenuListRestProps } = subMenuListProps;
|
|
209
225
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
210
226
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
211
227
|
MenuEntry,
|
|
@@ -223,9 +239,12 @@ var NestedMenuItem = (props) => {
|
|
|
223
239
|
if (e.key === "ArrowLeft") {
|
|
224
240
|
handleClose();
|
|
225
241
|
}
|
|
226
|
-
if (e.key === "ArrowRight" || e.key === "Enter"
|
|
242
|
+
if (e.key === "ArrowRight" || e.key === "Enter") {
|
|
227
243
|
handleOpen(e);
|
|
228
244
|
}
|
|
245
|
+
if ((e.key === "ArrowUp" || e.key === "ArrowDown") && open && document.activeElement === menuItemRef.current) {
|
|
246
|
+
handleClose();
|
|
247
|
+
}
|
|
229
248
|
},
|
|
230
249
|
"aria-haspopup": "menu",
|
|
231
250
|
"aria-controls": subMenuId,
|
|
@@ -262,34 +281,44 @@ var NestedMenuItem = (props) => {
|
|
|
262
281
|
if (isNodeInstance(e.relatedTarget) && menuItemRef.current?.contains(e.relatedTarget)) return;
|
|
263
282
|
scheduleClose();
|
|
264
283
|
},
|
|
265
|
-
children: ({ TransitionProps }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material3.Fade, { ...TransitionProps, timeout: transitionConfig.timeout, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
266
|
-
|
|
284
|
+
children: ({ TransitionProps }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material3.Fade, { ...TransitionProps, timeout: transitionConfig.timeout, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
285
|
+
SubMenuPaper,
|
|
267
286
|
{
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
...
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
287
|
+
elevation: menuProps.elevation,
|
|
288
|
+
className: [import_Menu.menuClasses.paper, subMenuPaperClassName].filter(Boolean).join(" "),
|
|
289
|
+
sx: { overflow: "auto" },
|
|
290
|
+
...subMenuPaperRestProps,
|
|
291
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
292
|
+
SubMenuList,
|
|
293
|
+
{
|
|
294
|
+
id: subMenuId,
|
|
295
|
+
"aria-labelledby": menuItemId,
|
|
296
|
+
role: "menu",
|
|
297
|
+
className: [import_Menu.menuClasses.list, subMenuListClassName].filter(Boolean).join(" "),
|
|
298
|
+
...subMenuListRestProps,
|
|
299
|
+
autoFocusItem: true,
|
|
300
|
+
onKeyDown: (e) => {
|
|
301
|
+
if (e.key === "ArrowLeft") {
|
|
302
|
+
const { nativeEvent } = e;
|
|
303
|
+
if (nativeEvent.__nestedMenuArrowLeftHandled) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (!subMenuRef.current?.contains(e.target)) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
nativeEvent.__nestedMenuArrowLeftHandled = true;
|
|
310
|
+
e.preventDefault();
|
|
311
|
+
e.stopPropagation();
|
|
312
|
+
nativeEvent.stopImmediatePropagation();
|
|
313
|
+
handleClose();
|
|
314
|
+
menuItemRef.current?.focus();
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
children: renderedSubMenuItems
|
|
288
318
|
}
|
|
289
|
-
|
|
290
|
-
children: renderedSubMenuItems
|
|
319
|
+
)
|
|
291
320
|
}
|
|
292
|
-
) })
|
|
321
|
+
) })
|
|
293
322
|
}
|
|
294
323
|
)
|
|
295
324
|
] });
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,8 @@ var ArrowRight_default = createSvgIcon(/* @__PURE__ */ _jsx("path", {
|
|
|
16
16
|
|
|
17
17
|
// src/Menu/NestedMenuItem.tsx
|
|
18
18
|
import { Divider, Fade as Fade2, ListSubheader, MenuItem as MuiMenuItem2, MenuList, Paper, Popper } from "@mui/material";
|
|
19
|
+
import { menuClasses } from "@mui/material/Menu";
|
|
20
|
+
import { styled as styled2 } from "@mui/material/styles";
|
|
19
21
|
|
|
20
22
|
// src/Menu/MenuEntry.tsx
|
|
21
23
|
import { forwardRef, isValidElement } from "react";
|
|
@@ -57,6 +59,16 @@ var MenuEntry = forwardRef(function MenuEntry2({ label, startIcon, endIcon, onCl
|
|
|
57
59
|
// src/Menu/NestedMenuItem.tsx
|
|
58
60
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
59
61
|
var isNodeInstance = (target) => target instanceof Node;
|
|
62
|
+
var SubMenuPaper = styled2(Paper, {
|
|
63
|
+
name: "MuiMenu",
|
|
64
|
+
slot: "Paper",
|
|
65
|
+
overridesResolver: (_, styles) => styles.paper
|
|
66
|
+
})({});
|
|
67
|
+
var SubMenuList = styled2(MenuList, {
|
|
68
|
+
name: "MuiMenu",
|
|
69
|
+
slot: "List",
|
|
70
|
+
overridesResolver: (_, styles) => styles.list
|
|
71
|
+
})({});
|
|
60
72
|
var NestedMenuItem = (props) => {
|
|
61
73
|
const {
|
|
62
74
|
id: providedId,
|
|
@@ -180,6 +192,10 @@ var NestedMenuItem = (props) => {
|
|
|
180
192
|
});
|
|
181
193
|
};
|
|
182
194
|
const renderedSubMenuItems = items && items.length > 0 ? renderItemsFromData() : renderChildren;
|
|
195
|
+
const subMenuPaperProps = menuProps?.slotProps?.paper || {};
|
|
196
|
+
const { className: subMenuPaperClassName, ...subMenuPaperRestProps } = subMenuPaperProps;
|
|
197
|
+
const subMenuListProps = menuProps?.slotProps?.list || {};
|
|
198
|
+
const { className: subMenuListClassName, ...subMenuListRestProps } = subMenuListProps;
|
|
183
199
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
184
200
|
/* @__PURE__ */ jsx2(
|
|
185
201
|
MenuEntry,
|
|
@@ -197,9 +213,12 @@ var NestedMenuItem = (props) => {
|
|
|
197
213
|
if (e.key === "ArrowLeft") {
|
|
198
214
|
handleClose();
|
|
199
215
|
}
|
|
200
|
-
if (e.key === "ArrowRight" || e.key === "Enter"
|
|
216
|
+
if (e.key === "ArrowRight" || e.key === "Enter") {
|
|
201
217
|
handleOpen(e);
|
|
202
218
|
}
|
|
219
|
+
if ((e.key === "ArrowUp" || e.key === "ArrowDown") && open && document.activeElement === menuItemRef.current) {
|
|
220
|
+
handleClose();
|
|
221
|
+
}
|
|
203
222
|
},
|
|
204
223
|
"aria-haspopup": "menu",
|
|
205
224
|
"aria-controls": subMenuId,
|
|
@@ -236,34 +255,44 @@ var NestedMenuItem = (props) => {
|
|
|
236
255
|
if (isNodeInstance(e.relatedTarget) && menuItemRef.current?.contains(e.relatedTarget)) return;
|
|
237
256
|
scheduleClose();
|
|
238
257
|
},
|
|
239
|
-
children: ({ TransitionProps }) => /* @__PURE__ */ jsx2(Fade2, { ...TransitionProps, timeout: transitionConfig.timeout, children: /* @__PURE__ */ jsx2(
|
|
240
|
-
|
|
258
|
+
children: ({ TransitionProps }) => /* @__PURE__ */ jsx2(Fade2, { ...TransitionProps, timeout: transitionConfig.timeout, children: /* @__PURE__ */ jsx2(
|
|
259
|
+
SubMenuPaper,
|
|
241
260
|
{
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
...
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
261
|
+
elevation: menuProps.elevation,
|
|
262
|
+
className: [menuClasses.paper, subMenuPaperClassName].filter(Boolean).join(" "),
|
|
263
|
+
sx: { overflow: "auto" },
|
|
264
|
+
...subMenuPaperRestProps,
|
|
265
|
+
children: /* @__PURE__ */ jsx2(
|
|
266
|
+
SubMenuList,
|
|
267
|
+
{
|
|
268
|
+
id: subMenuId,
|
|
269
|
+
"aria-labelledby": menuItemId,
|
|
270
|
+
role: "menu",
|
|
271
|
+
className: [menuClasses.list, subMenuListClassName].filter(Boolean).join(" "),
|
|
272
|
+
...subMenuListRestProps,
|
|
273
|
+
autoFocusItem: true,
|
|
274
|
+
onKeyDown: (e) => {
|
|
275
|
+
if (e.key === "ArrowLeft") {
|
|
276
|
+
const { nativeEvent } = e;
|
|
277
|
+
if (nativeEvent.__nestedMenuArrowLeftHandled) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (!subMenuRef.current?.contains(e.target)) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
nativeEvent.__nestedMenuArrowLeftHandled = true;
|
|
284
|
+
e.preventDefault();
|
|
285
|
+
e.stopPropagation();
|
|
286
|
+
nativeEvent.stopImmediatePropagation();
|
|
287
|
+
handleClose();
|
|
288
|
+
menuItemRef.current?.focus();
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
children: renderedSubMenuItems
|
|
262
292
|
}
|
|
263
|
-
|
|
264
|
-
children: renderedSubMenuItems
|
|
293
|
+
)
|
|
265
294
|
}
|
|
266
|
-
) })
|
|
295
|
+
) })
|
|
267
296
|
}
|
|
268
297
|
)
|
|
269
298
|
] });
|