Skip to content

Commit 71904a1

Browse files
authored
Issue fix for the menu has no menu items #1223 (#1279)
* fix issue #1223 * fix empty menu items without useState
1 parent 77c3141 commit 71904a1

File tree

3 files changed

+25
-18
lines changed

3 files changed

+25
-18
lines changed

docs/documentation/components/menu.mdx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ function MenuOptionsGroupExample() {
181181
{ label: 'Descending', value: 'desc' },
182182
]}
183183
selected={selectedOrder}
184-
onChange={(selected) => setSelectedOrder(selected)}
184+
onChange={selected => setSelectedOrder(selected)}
185185
/>
186186
<Menu.Divider />
187187
<Menu.OptionsGroup
@@ -194,7 +194,7 @@ function MenuOptionsGroupExample() {
194194
{ label: 'Type', value: 'type' },
195195
]}
196196
selected={selectedField}
197-
onChange={(selected) => setSelectedField(selected)}
197+
onChange={selected => setSelectedField(selected)}
198198
/>
199199
</Menu>
200200
)
@@ -237,3 +237,9 @@ The focus styles are currently not working in the docs, sorry for the inconvenie
237237
<Button>Custom Menu Items</Button>
238238
</Popover>
239239
```
240+
241+
## Menu without items
242+
243+
```jsx
244+
<Menu></Menu>
245+
```

src/menu/src/Menu.js

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,17 @@ import MenuOptionsGroup from './MenuOptionsGroup'
99

1010
const Menu = memo(function Menu(props) {
1111
const menuRef = useRef(null)
12+
1213
const firstItem = useRef()
1314
const lastItem = useRef()
1415

1516
const menuItems = useRef()
1617

1718
useEffect(() => {
1819
const currentMenuRef = menuRef.current
19-
20-
menuItems.current = currentMenuRef
21-
? [
22-
...currentMenuRef.querySelectorAll(
23-
'[role="menuitemradio"]:not([disabled]), [role="menuitem"]:not([disabled])'
24-
)
25-
]
26-
: []
27-
28-
if (menuItems.current.length === 0) {
29-
throw new Error('The menu has no menu items')
30-
}
20+
menuItems.current = [
21+
...currentMenuRef.querySelectorAll('[role="menuitemradio"]:not([disabled]), [role="menuitem"]:not([disabled])')
22+
]
3123

3224
firstItem.current = menuItems.current[0]
3325
lastItem.current = menuItems.current[menuItems.current.length - 1]
@@ -68,9 +60,7 @@ const Menu = memo(function Menu(props) {
6860
const { target } = e
6961
const menuItem = menuItems.current && menuItems.current.find(item => item === target)
7062

71-
if (!menuItem) {
72-
return
73-
}
63+
if (!menuItem) return
7464

7565
if (e.key === 'ArrowDown') {
7666
e.preventDefault()
@@ -101,9 +91,17 @@ const Menu = memo(function Menu(props) {
10191
}, [menuRef])
10292

10393
const { children } = props
94+
95+
const renderEmptyChildren = () => {
96+
return (
97+
<MenuGroup>
98+
<MenuItem disabled>No items...</MenuItem>
99+
</MenuGroup>
100+
)
101+
}
104102
return (
105103
<Pane is="nav" ref={menuRef} role="menu" outline="none">
106-
{children}
104+
{children || renderEmptyChildren()}
107105
</Pane>
108106
)
109107
})

src/menu/stories/index.stories.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ storiesOf('menu', module)
195195
>
196196
<Button>Hover menus</Button>
197197
</Popover>
198+
<Popover position={Position.BOTTOM_LEFT} content={<Menu></Menu>}>
199+
<Button marginTop={16}>Without Menu Items</Button>
200+
</Popover>
198201

199202
<UnorderedList marginTop={24}>
200203
<ListItem>Arrow down on a button will bring focus inside the popover.</ListItem>

0 commit comments

Comments
 (0)