Skip to content

Commit a9c5c35

Browse files
authored
Bugfix/iterate over selectable elements (#294)
2 parents 79157d6 + 3f0c6d2 commit a9c5c35

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

src/AbstractMenu.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export default class AbstractMenu extends Component {
9494
return;
9595
}
9696

97-
if ([MenuItem, this.getSubMenuType()].indexOf(child.type) < 0) {
97+
if ([MenuItem, this.getSubMenuType()].indexOf(child.type) < 0 && child.props.children instanceof Object) {
9898
// Maybe the MenuItem or SubMenu is capsuled in a wrapper div or something else
9999
React.Children.forEach(child.props.children, childCollector);
100100
} else if (!child.props.divider) {

tests/ContextMenu.test.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,56 @@ describe('ContextMenu tests', () => {
210210
// The selected item should be preserved and not reset.
211211
expect(screen.getByText('Item 2')).toHaveClass('react-contextmenu-item--selected');
212212
});
213+
214+
test('should select proper menu item, even though it is wrapped with html element', async () => {
215+
const data = { position: { x: 50, y: 50 }, id: 'CORRECT_ID' };
216+
render(
217+
<ContextMenu id={data.id} onHide={jest.fn()}>
218+
<div><MenuItem onClick={jest.fn()}>Item 1</MenuItem></div>
219+
<span><MenuItem onClick={jest.fn()}>Item 2</MenuItem></span>
220+
</ContextMenu>
221+
);
222+
const user = userEvent.setup();
223+
224+
await showMenu(data);
225+
// Check that it's visible and there is no selected item at first.
226+
expect(visibleContextMenuElement()).toBeInTheDocument();
227+
expect(selectedItemElement()).not.toBeInTheDocument();
228+
229+
// Select the first item with down arrow.
230+
await user.keyboard('{ArrowDown}');
231+
expect(screen.getByText('Item 1')).toHaveClass('react-contextmenu-item--selected');
232+
233+
// Select the second item with down arrow.
234+
await user.keyboard('{ArrowDown}');
235+
// Index 1 with MenuItem type should be selected.
236+
expect(screen.getByText('Item 2')).toHaveClass('react-contextmenu-item--selected');
237+
238+
// Select the next item. But since this was the last item, it should loop
239+
// back to the first again.
240+
await user.keyboard('{ArrowDown}');
241+
// Index 0 with MenuItem type should be selected.
242+
expect(screen.getByText('Item 1')).toHaveClass('react-contextmenu-item--selected');
243+
});
244+
245+
test('should allow keyboard actions when menu contains a non menu item element', async () => {
246+
const data = { position: { x: 50, y: 50 }, id: 'CORRECT_ID' };
247+
render(
248+
<ContextMenu id={data.id} onHide={jest.fn()}>
249+
<MenuItem onClick={jest.fn()}>Item 1</MenuItem>
250+
<MenuItem onClick={jest.fn()}>Item 2</MenuItem>
251+
<div>custom-content</div>
252+
</ContextMenu>
253+
);
254+
const user = userEvent.setup();
255+
256+
await showMenu(data);
257+
// Check that it's visible and there is no selected item at first.
258+
expect(visibleContextMenuElement()).toBeInTheDocument();
259+
expect(selectedItemElement()).not.toBeInTheDocument();
260+
261+
// Select the first item with down arrow and don't throw any errors
262+
await user.keyboard('{ArrowDown}');
263+
expect(screen.getByText('Item 1')).toHaveClass('react-contextmenu-item--selected');
264+
});
213265
});

0 commit comments

Comments
 (0)