Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fixed] switched from KeyboardEvent.keyCode to KeyboardEvent.code #953

Merged
merged 5 commits into from
Oct 14, 2022
Merged
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
38 changes: 38 additions & 0 deletions specs/Modal.events.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import {
mouseDownAt,
mouseUpAt,
escKeyDown,
escKeyDownWithCode,
tabKeyDown,
tabKeyDownWithCode,
withModal,
withElementCollector,
createHTMLElement
Expand Down Expand Up @@ -109,6 +111,23 @@ export default () => {
});
});

it("traps tab in the modal on shift + tab with KeyboardEvent.code", () => {
const topButton = <button>top</button>;
const bottomButton = <button>bottom</button>;
const modalContent = (
<div>
{topButton}
{bottomButton}
</div>
);
const props = { isOpen: true };
withModal(props, modalContent, modal => {
const content = mcontent(modal);
tabKeyDownWithCode(content, { shiftKey: true });
document.activeElement.textContent.should.be.eql("bottom");
});
});

describe("shouldCloseOnEsc", () => {
context("when true", () => {
it("should close on Esc key event", () => {
Expand All @@ -129,6 +148,25 @@ export default () => {
}
);
});

it("should close on Esc key event with KeyboardEvent.code", () => {
const requestCloseCallback = sinon.spy();
withModal(
{
isOpen: true,
shouldCloseOnEsc: true,
onRequestClose: requestCloseCallback
},
null,
modal => {
escKeyDownWithCode(mcontent(modal));
requestCloseCallback.called.should.be.ok();
// Check if event is passed to onRequestClose callback.
const event = requestCloseCallback.getCall(0).args[0];
event.should.be.ok();
}
);
});
});

context("when false", () => {
Expand Down
28 changes: 23 additions & 5 deletions specs/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,23 +182,41 @@ const dispatchMockEvent = eventCtor => (key, code) => (element, opts) =>
{},
{
key: key,
keyCode: code,
which: code
diasbruno marked this conversation as resolved.
Show resolved Hide resolved
},
code,
diasbruno marked this conversation as resolved.
Show resolved Hide resolved
opts
)
);

const dispatchMockKeyDownEvent = dispatchMockEvent(Simulate.keyDown);

/**
* Dispatch an 'esc' key down event from an element.
* @deprecated will be replaced by `escKeyDownWithCode` when `react-modal`
* drops support for React <18.
*
* Dispatch an 'esc' key down event using the legacy KeyboardEvent.keyCode.
*/
export const escKeyDown = dispatchMockKeyDownEvent("ESC", { keyCode: 27 });
/**
* Dispatch an 'esc' key down event.
*/
export const escKeyDownWithCode = dispatchMockKeyDownEvent("ESC", {
code: "Escape"
});
/**
* @deprecated will be replaced by `escKeyDownWithCode` when `react-modal`
* drops support for React <18.
*
* Dispatch a 'tab' key down event using the legacy KeyboardEvent.keyCode.
*/
export const escKeyDown = dispatchMockKeyDownEvent("ESC", 27);
export const tabKeyDown = dispatchMockKeyDownEvent("TAB", { keyCode: 9 });
/**
* Dispatch a 'tab' key down event from an element.
* Dispatch a 'tab' key down event.
*/
export const tabKeyDown = dispatchMockKeyDownEvent("TAB", 9);
export const tabKeyDownWithCode = dispatchMockKeyDownEvent("TAB", {
code: "Tab"
});
/**
* Dispatch a 'click' event at a node.
*/
Expand Down
13 changes: 9 additions & 4 deletions src/components/ModalPortal.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@ const CLASS_NAMES = {
content: "ReactModal__Content"
};

const TAB_KEY = 9;
const ESC_KEY = 27;
/**
* We need to support the deprecated `KeyboardEvent.keyCode` in addition to
* `KeyboardEvent.code` for apps that still support IE11. Can be removed when
* `react-modal` only supports React >18 (which dropped IE support).
*/
const isTabKey = event => event.code === "Tab" || event.keyCode === 9;
const isEscKey = event => event.code === "Escape" || event.keyCode === 27;

let ariaHiddenInstances = 0;

Expand Down Expand Up @@ -274,11 +279,11 @@ export default class ModalPortal extends Component {
};

handleKeyDown = event => {
if (event.keyCode === TAB_KEY) {
robinmetral marked this conversation as resolved.
Show resolved Hide resolved
if (isTabKey(event)) {
scopeTab(this.content, event);
}

if (this.props.shouldCloseOnEsc && event.keyCode === ESC_KEY) {
if (this.props.shouldCloseOnEsc && isEscKey(event)) {
event.stopPropagation();
this.requestClose(event);
}
Expand Down