feat: close dropdown on escape (#7750)

This commit is contained in:
David Luzar 2024-03-05 23:22:34 +01:00 committed by GitHub
parent a07f6e9e3a
commit a38e82f999
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 2 deletions

View File

@ -0,0 +1,20 @@
import { Excalidraw } from "../../index";
import { KEYS } from "../../keys";
import { Keyboard } from "../../tests/helpers/ui";
import { render, waitFor, getByTestId } from "../../tests/test-utils";
describe("Test <DropdownMenu/>", () => {
it("should", async () => {
const { container } = await render(<Excalidraw />);
expect(window.h.state.openMenu).toBe(null);
getByTestId(container, "main-menu-trigger").click();
expect(window.h.state.openMenu).toBe("canvas");
await waitFor(() => {
Keyboard.keyDown(KEYS.ESCAPE);
expect(window.h.state.openMenu).toBe(null);
});
});
});

View File

@ -2,9 +2,12 @@ import { Island } from "../Island";
import { useDevice } from "../App";
import clsx from "clsx";
import Stack from "../Stack";
import React, { useRef } from "react";
import React, { useEffect, useRef } from "react";
import { DropdownMenuContentPropsContext } from "./common";
import { useOutsideClick } from "../../hooks/useOutsideClick";
import { KEYS } from "../../keys";
import { EVENT } from "../../constants";
import { useStable } from "../../hooks/useStable";
const MenuContent = ({
children,
@ -25,10 +28,30 @@ const MenuContent = ({
const device = useDevice();
const menuRef = useRef<HTMLDivElement>(null);
const callbacksRef = useStable({ onClickOutside });
useOutsideClick(menuRef, () => {
onClickOutside?.();
callbacksRef.onClickOutside?.();
});
useEffect(() => {
const onKeyDown = (event: KeyboardEvent) => {
if (event.key === KEYS.ESCAPE) {
event.stopImmediatePropagation();
callbacksRef.onClickOutside?.();
}
};
document.addEventListener(EVENT.KEYDOWN, onKeyDown, {
// so that we can stop propagation of the event before it reaches
// event handlers that were bound before this one
capture: true,
});
return () => {
document.removeEventListener(EVENT.KEYDOWN, onKeyDown);
};
}, [callbacksRef]);
const classNames = clsx(`dropdown-menu ${className}`, {
"dropdown-menu--mobile": device.editor.isMobile,
}).trim();