Fixed a possible bug with callbacks and map menus
also made it so clicking on a map control button with a sub menu open will close it
This commit is contained in:
parent
35523fd8ce
commit
0a1aed30b3
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { Flex, Box, IconButton, Label } from "theme-ui";
|
||||
|
||||
import AddMapButton from "./AddMapButton";
|
||||
@ -135,6 +135,9 @@ function MapControls({
|
||||
function handleToolClick(event, tool) {
|
||||
if (tool !== selectedTool) {
|
||||
onToolChange(tool);
|
||||
} else if (currentSubmenu) {
|
||||
setCurrentSubmenu(null);
|
||||
setCurrentSubmenuOptions({});
|
||||
} else if (subMenus[tool]) {
|
||||
const toolRect = event.target.getBoundingClientRect();
|
||||
setCurrentSubmenu(tool);
|
||||
@ -143,6 +146,8 @@ function MapControls({
|
||||
left: `${toolRect.left - 16}px`,
|
||||
top: `${toolRect.bottom - toolRect.height / 2}px`,
|
||||
style: { transform: "translate(-100%, -50%)" },
|
||||
// Exclude this node from the sub menus auto close
|
||||
excludeNode: event.target,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -161,6 +166,9 @@ function MapControls({
|
||||
sx={{ height: "2px", width: "24px", borderRadius: "2px", opacity: 0.5 }}
|
||||
></Box>
|
||||
);
|
||||
|
||||
const expanedMenuRef = useRef();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
@ -195,6 +203,7 @@ function MapControls({
|
||||
borderRadius: "4px",
|
||||
}}
|
||||
p={2}
|
||||
ref={expanedMenuRef}
|
||||
>
|
||||
<AddMapButton onMapChange={onMapChange} />
|
||||
{divider}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Modal from "react-modal";
|
||||
|
||||
import { useThemeUI } from "theme-ui";
|
||||
@ -13,19 +13,29 @@ function MapMenu({
|
||||
right,
|
||||
children,
|
||||
style,
|
||||
// A node to exclude from the pointer event for closing
|
||||
excludeNode,
|
||||
}) {
|
||||
function handleModalContent(node) {
|
||||
if (node) {
|
||||
// Close modal if interacting with any other element
|
||||
function handlePointerDown(event) {
|
||||
const path = event.composedPath();
|
||||
if (!path.includes(node)) {
|
||||
onRequestClose();
|
||||
document.body.removeEventListener("pointerdown", handlePointerDown);
|
||||
}
|
||||
}
|
||||
document.body.addEventListener("pointerdown", handlePointerDown);
|
||||
// Save modal node in state to ensure that the pointer listeners
|
||||
// are removed if the open state changed not from the onRequestClose
|
||||
// callback
|
||||
const [modalContentNode, setModalContentNode] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Close modal if interacting with any other element
|
||||
function handlePointerDown(event) {
|
||||
const path = event.composedPath();
|
||||
if (
|
||||
!path.includes(modalContentNode) &&
|
||||
!(excludeNode && path.includes(excludeNode))
|
||||
) {
|
||||
onRequestClose();
|
||||
document.body.removeEventListener("pointerdown", handlePointerDown);
|
||||
}
|
||||
}
|
||||
|
||||
if (modalContentNode) {
|
||||
document.body.addEventListener("pointerdown", handlePointerDown);
|
||||
// Check for wheel event to close modal as well
|
||||
document.body.addEventListener(
|
||||
"wheel",
|
||||
@ -35,6 +45,15 @@ function MapMenu({
|
||||
{ once: true }
|
||||
);
|
||||
}
|
||||
return () => {
|
||||
if (modalContentNode) {
|
||||
document.body.removeEventListener("pointerdown", handlePointerDown);
|
||||
}
|
||||
};
|
||||
}, [modalContentNode, excludeNode, onRequestClose]);
|
||||
|
||||
function handleModalContent(node) {
|
||||
setModalContentNode(node);
|
||||
onModalContent(node);
|
||||
}
|
||||
|
||||
@ -72,6 +91,7 @@ MapMenu.defaultProps = {
|
||||
right: "initial",
|
||||
bottom: "initial",
|
||||
style: {},
|
||||
excludeNode: null,
|
||||
};
|
||||
|
||||
export default MapMenu;
|
||||
|
Loading…
Reference in New Issue
Block a user