better-mui-menu 1.4.1 → 1.5.1

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 CHANGED
@@ -80,14 +80,17 @@ export function FileMenu() {
80
80
  }
81
81
  ```
82
82
 
83
- ## Items shape
84
-
85
- `MenuItem` extends `@mui/material/MenuItemProps` (excluding `children`) so you can still pass `dense`, `disabled`, `aria-selected`, etc.
86
- The `better-mui-menu` adds:
87
-
88
- - `type?: 'item' | 'divider'` render a `Divider` when `'divider'` is supplied.
89
- - `id?: string` optional stable ID for ARIA attributes; one is generated automatically otherwise.
90
- - `label: ReactNode` the label shown in the menu row.
91
- - `startIcon` / `endIcon` pass either a `SvgIconComponent` (for example `Save`) or a JSX element (for example `<Save fontSize='large' sx={{ ml: 0.5 }} />`).
92
- - `items?: MenuItem[]` nested entries that render as submenus.
93
- - `onClick?: MenuItemProps['onClick']` callback function when the menu item is clicked.
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
@@ -155,6 +155,9 @@ var NestedMenuItem = (props) => {
155
155
  if (item.type === "divider") {
156
156
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material3.Divider, {}, `divider-${index}`);
157
157
  }
158
+ if (item.type === "header") {
159
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material3.ListSubheader, { children: item.label }, `header-${index}`);
160
+ }
158
161
  const {
159
162
  type: __,
160
163
  items: entryItems,
@@ -301,6 +304,9 @@ function Menu({ items, elevation = DEFAULT_ELEVATION, ...rest }) {
301
304
  if (item.type === "divider") {
302
305
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material4.Divider, {}, `divider-${index}`);
303
306
  }
307
+ if (item.type === "header") {
308
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material4.ListSubheader, { children: item.label }, `header-${index}`);
309
+ }
304
310
  const {
305
311
  type: _,
306
312
  id,
package/dist/index.d.cts CHANGED
@@ -4,20 +4,25 @@ import React, { ReactNode, ReactElement } from 'react';
4
4
  import { SvgIconComponent } from '@mui/icons-material';
5
5
 
6
6
  type MenuIcon = SvgIconComponent | ReactElement;
7
- type MenuItemBase = {
7
+ type DataAttributes = {
8
+ [K in `data-${string}`]?: string | number | boolean | undefined;
9
+ };
10
+ type MenuDividerItem = {
8
11
  type: 'divider';
9
- } | {
12
+ } & DataAttributes;
13
+ type MenuHeaderItem = {
14
+ type: 'header';
15
+ label: ReactNode;
16
+ } & DataAttributes;
17
+ type MenuActionItem = {
10
18
  type?: 'item';
11
19
  id?: string;
12
20
  label: ReactNode;
13
21
  startIcon?: MenuIcon;
14
22
  endIcon?: MenuIcon;
15
23
  items?: MenuItem[];
16
- };
17
- type DataAttributes = {
18
- [K in `data-${string}`]?: string | number | boolean | undefined;
19
- };
20
- type MenuItem = MenuItemBase & Omit<MenuItemProps, 'children'> & DataAttributes;
24
+ } & Omit<MenuItemProps, 'children' | 'type'> & DataAttributes;
25
+ type MenuItem = MenuDividerItem | MenuHeaderItem | MenuActionItem;
21
26
 
22
27
  type Props = {
23
28
  items: MenuItem[];
package/dist/index.d.ts CHANGED
@@ -4,20 +4,25 @@ import React, { ReactNode, ReactElement } from 'react';
4
4
  import { SvgIconComponent } from '@mui/icons-material';
5
5
 
6
6
  type MenuIcon = SvgIconComponent | ReactElement;
7
- type MenuItemBase = {
7
+ type DataAttributes = {
8
+ [K in `data-${string}`]?: string | number | boolean | undefined;
9
+ };
10
+ type MenuDividerItem = {
8
11
  type: 'divider';
9
- } | {
12
+ } & DataAttributes;
13
+ type MenuHeaderItem = {
14
+ type: 'header';
15
+ label: ReactNode;
16
+ } & DataAttributes;
17
+ type MenuActionItem = {
10
18
  type?: 'item';
11
19
  id?: string;
12
20
  label: ReactNode;
13
21
  startIcon?: MenuIcon;
14
22
  endIcon?: MenuIcon;
15
23
  items?: MenuItem[];
16
- };
17
- type DataAttributes = {
18
- [K in `data-${string}`]?: string | number | boolean | undefined;
19
- };
20
- type MenuItem = MenuItemBase & Omit<MenuItemProps, 'children'> & DataAttributes;
24
+ } & Omit<MenuItemProps, 'children' | 'type'> & DataAttributes;
25
+ type MenuItem = MenuDividerItem | MenuHeaderItem | MenuActionItem;
21
26
 
22
27
  type Props = {
23
28
  items: MenuItem[];
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/Menu/index.tsx
2
- import { Divider as Divider2, Menu as MuiMenu } from "@mui/material";
2
+ import { Divider as Divider2, ListSubheader as ListSubheader2, Menu as MuiMenu } from "@mui/material";
3
3
  import { useId as useId2 } from "react";
4
4
 
5
5
  // src/Menu/NestedMenuItem.tsx
@@ -15,7 +15,7 @@ var ArrowRight_default = createSvgIcon(/* @__PURE__ */ _jsx("path", {
15
15
  }), "ArrowRight");
16
16
 
17
17
  // src/Menu/NestedMenuItem.tsx
18
- import { Divider, Fade as Fade2, MenuItem as MuiMenuItem2, MenuList, Paper, Popper } from "@mui/material";
18
+ import { Divider, Fade as Fade2, ListSubheader, MenuItem as MuiMenuItem2, MenuList, Paper, Popper } from "@mui/material";
19
19
 
20
20
  // src/Menu/MenuEntry.tsx
21
21
  import { forwardRef, isValidElement } from "react";
@@ -129,6 +129,9 @@ var NestedMenuItem = (props) => {
129
129
  if (item.type === "divider") {
130
130
  return /* @__PURE__ */ jsx2(Divider, {}, `divider-${index}`);
131
131
  }
132
+ if (item.type === "header") {
133
+ return /* @__PURE__ */ jsx2(ListSubheader, { children: item.label }, `header-${index}`);
134
+ }
132
135
  const {
133
136
  type: __,
134
137
  items: entryItems,
@@ -275,6 +278,9 @@ function Menu({ items, elevation = DEFAULT_ELEVATION, ...rest }) {
275
278
  if (item.type === "divider") {
276
279
  return /* @__PURE__ */ jsx3(Divider2, {}, `divider-${index}`);
277
280
  }
281
+ if (item.type === "header") {
282
+ return /* @__PURE__ */ jsx3(ListSubheader2, { children: item.label }, `header-${index}`);
283
+ }
278
284
  const {
279
285
  type: _,
280
286
  id,
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "bugs": {
10
10
  "url": "https://github.com/eggei/better-mui-menu/issues"
11
11
  },
12
- "version": "1.4.1",
12
+ "version": "1.5.1",
13
13
  "type": "module",
14
14
  "sideEffects": false,
15
15
  "files": [