Skip to content

Commit 6f21f95

Browse files
authored
Merge pull request #50 from sparksuite/enter-close-menu
Ensure enter key closes the menu
2 parents cca088f + de75478 commit 6f21f95

File tree

4 files changed

+34
-11
lines changed

4 files changed

+34
-11
lines changed

demo/src/app.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ const App: React.FC = () => {
4848
<li>The up / down arrow keys allow for navigation through the menu items</li>
4949
<li>Pressing tab will close the menu and move the focus to the next focusable element</li>
5050
<li>Pressing escape will close the menu and return the focus to the button</li>
51-
<li>Pressing enter will trigger that item (whether itʼs a link or has a click handler attached)</li>
51+
<li>
52+
Pressing enter will activate that item and close the menu (whether itʼs a link or has a click handler
53+
attached)
54+
</li>
5255
</ul>
5356
</li>
5457
</ul>

src/use-dropdown-menu.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,12 @@ export default function useDropdownMenu(itemCount: number) {
112112
} else if (key === 'Tab') {
113113
setIsOpen(false);
114114
return;
115-
} else if (key === 'Enter' && !e.currentTarget.href) {
116-
e.currentTarget.click();
115+
} else if (key === 'Enter') {
116+
if (!e.currentTarget.href) {
117+
e.currentTarget.click();
118+
}
119+
120+
setIsOpen(false);
117121
return;
118122
}
119123

test/puppeteer/demo.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,21 @@ it('leaves the menu open if you click inside of it', async () => {
8383

8484
expect(true).toBe(true);
8585
});
86+
87+
it('reroutes enter presses on menu items as clicks', async () => {
88+
let alertAppeared = false;
89+
90+
await page.click('#menu-button');
91+
await menuOpen();
92+
93+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
94+
page.on('dialog', async dialog => {
95+
alertAppeared = true;
96+
await dialog.dismiss();
97+
});
98+
99+
await page.focus('#menu-item-3');
100+
await keyboard.down('Enter');
101+
102+
expect(alertAppeared).toBe(true);
103+
});

test/test-component.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,25 @@ const TestComponent: React.FC = () => {
88

99
return (
1010
<React.Fragment>
11-
<button type='button' {...buttonProps} id='menu-button' tabIndex={0}>
11+
<button {...buttonProps} id='menu-button'>
1212
Primary
1313
</button>
1414

15-
<div style={{ display: isOpen ? 'block' : 'none' }} role='menu' id='menu'>
16-
<a style={{ display: 'block' }} {...itemProps[0]} onClick={() => null} id='menu-item-1'>
15+
<div role='menu' id='menu'>
16+
<a {...itemProps[0]} onClick={() => null} id='menu-item-1'>
1717
Item 1
1818
</a>
1919

20-
<a style={{ display: 'block' }} href='https://example.com' {...itemProps[1]} id='menu-item-2'>
20+
<a {...itemProps[1]} href='https://example.com' id='menu-item-2'>
2121
Item 2
2222
</a>
2323

24-
<a style={{ display: 'block' }} href='https://example.com' {...itemProps[2]} id='menu-item-3'>
24+
<a {...itemProps[2]} href='https://example.com' id='menu-item-3'>
2525
Item 3
2626
</a>
2727
</div>
2828

29-
<button type='button' id='second-button' tabIndex={0}>
30-
Another Button
31-
</button>
29+
<button id='second-button'>Another Button</button>
3230

3331
<span id='is-open-indicator'>{isOpen ? 'true' : 'false'}</span>
3432
</React.Fragment>

0 commit comments

Comments
 (0)