Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ class AriaMenuButtonButton extends React.Component {
this.context.ambManager.toggleMenu({}, { focusMenu: false });
};

// The Space key behaves like mousedown/mouseup in some browsers such as Firefox.
// To prevent an unexpected click event when the space key is released, event.preventDefault () is set in keyUp.
handleKeyUp = (event) => {
if (event.key === ' ' || event.key === 'Enter') {
event.preventDefault();
}
}

render() {
const props = this.props;
const ambManager = this.context.ambManager;
Expand All @@ -82,6 +90,7 @@ class AriaMenuButtonButton extends React.Component {
'aria-expanded': ambManager.isOpen,
'aria-disabled': props.disabled,
onKeyDown: this.handleKeyDown,
onKeyUp: this.handleKeyUp,
onClick: this.handleClick
};

Expand Down
40 changes: 40 additions & 0 deletions src/__tests__/Button.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,46 @@ describe('<Button>', function() {
expect(enterEvent.preventDefault).not.toHaveBeenCalled();
expect(ambManager.toggleMenu).not.toHaveBeenCalled();
});

test('prevent manager event when enter key is released.', function() {
const wrapper = shallow(
el(Button, { tag: 'button' }, 'foo'),
shallowOptions
);
jest.spyOn(ambManager, 'toggleMenu').mockImplementation(() => {
ambManager.isOpen = !ambManager.isOpen;
});

wrapper.simulate('click');
expect(ambManager.isOpen).toBe(true);

wrapper.simulate('keydown', enterEvent);
expect(ambManager.isOpen).toBe(false);

wrapper.simulate('keyup', enterEvent);
expect(ambManager.isOpen).toBe(false);
expect(enterEvent.preventDefault).toHaveBeenCalled();
});

test('prevent manager event when space key is released.', function() {
const wrapper = shallow(
el(Button, { tag: 'button' }, 'foo'),
shallowOptions
);
jest.spyOn(ambManager, 'toggleMenu').mockImplementation(() => {
ambManager.isOpen = !ambManager.isOpen;
});

wrapper.simulate('click');
expect(ambManager.isOpen).toBe(true);

wrapper.simulate('keydown', spaceEvent);
expect(ambManager.isOpen).toBe(false);

wrapper.simulate('keyup', spaceEvent);
expect(ambManager.isOpen).toBe(false);
expect(spaceEvent.preventDefault).toHaveBeenCalled();
});
});

describe('<Button> rendered via renderToString', function() {
Expand Down
2 changes: 2 additions & 0 deletions src/__tests__/__snapshots__/Button.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ exports[`<Button> DOM with all possible props and element child 1`] = `
id="foo"
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
role="button"
style={
Object {
Expand All @@ -31,6 +32,7 @@ exports[`<Button> DOM with only required props and text child 1`] = `
aria-haspopup={true}
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
role="button"
tabIndex="0"
>
Expand Down