mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-02-18 13:29:36 +01:00
feat: close dropdown on escape (#7750)
This commit is contained in:
parent
a07f6e9e3a
commit
a38e82f999
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user