Skip to content

Commit eac6df1

Browse files
authored
Merge pull request #198 from GavinJoyce/gj/menu-enter-prevent-default
Add preventDefault to Enter key handler on menu items
2 parents 48a9a08 + 33eb473 commit eac6df1

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

ember-headlessui/addon/components/menu/items.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export default class Items extends Component {
2121
}
2222
// eslint-disable-next-line no-fallthrough
2323
case Keys.Enter:
24+
event.preventDefault();
25+
event.stopPropagation();
2426
if (this.args.activeItem) {
2527
this.args.activeItem.element.click();
2628
}

test-app/tests/integration/components/menu-test.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,60 @@ module('Integration | Component | <Menu>', (hooks) => {
533533
assert.dom(itemClicked).hasText('Item B');
534534
});
535535

536+
test('it should call preventDefault when pressing Enter on menu item', async function (assert) {
537+
await render(hbs`
538+
<Menu as |menu|>
539+
<menu.Button data-test-menu-button>Trigger</menu.Button>
540+
<menu.Items data-test-menu-items as |items|>
541+
<items.Item as |item|>
542+
<item.Element data-test-item-a>
543+
Item A
544+
</item.Element>
545+
</items.Item>
546+
<items.Item as |item|>
547+
<item.Element data-test-item-b>
548+
Item B
549+
</item.Element>
550+
</items.Item>
551+
</menu.Items>
552+
</Menu>
553+
`);
554+
555+
// Open menu
556+
await click('[data-test-menu-button]');
557+
558+
// Verify it is open
559+
assertOpenMenuButton('[data-test-menu-button]');
560+
561+
// Activate first menu item
562+
await triggerEvent('[data-test-item-a]', 'mouseover');
563+
564+
// Set up a listener on the menu items to capture the event after the component handles it
565+
let capturedEvent = null;
566+
const menuItems = find('[data-test-menu-items]');
567+
const captureHandler = (event) => {
568+
// We store the event after the menu component's handler has processed it
569+
// Using setTimeout to check after the synchronous handler completes
570+
capturedEvent = event;
571+
};
572+
menuItems.addEventListener('keydown', captureHandler);
573+
574+
// Press Enter on the menu item
575+
await triggerKeyEvent('[data-test-item-a]', 'keydown', Keys.Enter);
576+
577+
// Clean up listener
578+
menuItems.removeEventListener('keydown', captureHandler);
579+
580+
// Verify that preventDefault was called on the event
581+
assert.true(
582+
capturedEvent?.defaultPrevented,
583+
'preventDefault should be called when pressing Enter on menu item'
584+
);
585+
586+
// Verify the menu closed
587+
assertClosedMenuButton('[data-test-menu-button]');
588+
});
589+
536590
test('it should be possible to use a button as a menu item and invoke it upon Enter', async function (assert) {
537591
let itemClicked = 0;
538592
this.set('onClick', (item) => (itemClicked = item.target));

0 commit comments

Comments
 (0)