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 { Flex, Box, IconButton, Label } from "theme-ui";
|
||||||
|
|
||||||
import AddMapButton from "./AddMapButton";
|
import AddMapButton from "./AddMapButton";
|
||||||
@ -135,6 +135,9 @@ function MapControls({
|
|||||||
function handleToolClick(event, tool) {
|
function handleToolClick(event, tool) {
|
||||||
if (tool !== selectedTool) {
|
if (tool !== selectedTool) {
|
||||||
onToolChange(tool);
|
onToolChange(tool);
|
||||||
|
} else if (currentSubmenu) {
|
||||||
|
setCurrentSubmenu(null);
|
||||||
|
setCurrentSubmenuOptions({});
|
||||||
} else if (subMenus[tool]) {
|
} else if (subMenus[tool]) {
|
||||||
const toolRect = event.target.getBoundingClientRect();
|
const toolRect = event.target.getBoundingClientRect();
|
||||||
setCurrentSubmenu(tool);
|
setCurrentSubmenu(tool);
|
||||||
@ -143,6 +146,8 @@ function MapControls({
|
|||||||
left: `${toolRect.left - 16}px`,
|
left: `${toolRect.left - 16}px`,
|
||||||
top: `${toolRect.bottom - toolRect.height / 2}px`,
|
top: `${toolRect.bottom - toolRect.height / 2}px`,
|
||||||
style: { transform: "translate(-100%, -50%)" },
|
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 }}
|
sx={{ height: "2px", width: "24px", borderRadius: "2px", opacity: 0.5 }}
|
||||||
></Box>
|
></Box>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const expanedMenuRef = useRef();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex
|
<Flex
|
||||||
@ -195,6 +203,7 @@ function MapControls({
|
|||||||
borderRadius: "4px",
|
borderRadius: "4px",
|
||||||
}}
|
}}
|
||||||
p={2}
|
p={2}
|
||||||
|
ref={expanedMenuRef}
|
||||||
>
|
>
|
||||||
<AddMapButton onMapChange={onMapChange} />
|
<AddMapButton onMapChange={onMapChange} />
|
||||||
{divider}
|
{divider}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Modal from "react-modal";
|
import Modal from "react-modal";
|
||||||
|
|
||||||
import { useThemeUI } from "theme-ui";
|
import { useThemeUI } from "theme-ui";
|
||||||
@ -13,19 +13,29 @@ function MapMenu({
|
|||||||
right,
|
right,
|
||||||
children,
|
children,
|
||||||
style,
|
style,
|
||||||
|
// A node to exclude from the pointer event for closing
|
||||||
|
excludeNode,
|
||||||
}) {
|
}) {
|
||||||
function handleModalContent(node) {
|
// Save modal node in state to ensure that the pointer listeners
|
||||||
if (node) {
|
// 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
|
// Close modal if interacting with any other element
|
||||||
function handlePointerDown(event) {
|
function handlePointerDown(event) {
|
||||||
const path = event.composedPath();
|
const path = event.composedPath();
|
||||||
if (!path.includes(node)) {
|
if (
|
||||||
|
!path.includes(modalContentNode) &&
|
||||||
|
!(excludeNode && path.includes(excludeNode))
|
||||||
|
) {
|
||||||
onRequestClose();
|
onRequestClose();
|
||||||
document.body.removeEventListener("pointerdown", handlePointerDown);
|
document.body.removeEventListener("pointerdown", handlePointerDown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
document.body.addEventListener("pointerdown", handlePointerDown);
|
|
||||||
|
|
||||||
|
if (modalContentNode) {
|
||||||
|
document.body.addEventListener("pointerdown", handlePointerDown);
|
||||||
// Check for wheel event to close modal as well
|
// Check for wheel event to close modal as well
|
||||||
document.body.addEventListener(
|
document.body.addEventListener(
|
||||||
"wheel",
|
"wheel",
|
||||||
@ -35,6 +45,15 @@ function MapMenu({
|
|||||||
{ once: true }
|
{ once: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return () => {
|
||||||
|
if (modalContentNode) {
|
||||||
|
document.body.removeEventListener("pointerdown", handlePointerDown);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [modalContentNode, excludeNode, onRequestClose]);
|
||||||
|
|
||||||
|
function handleModalContent(node) {
|
||||||
|
setModalContentNode(node);
|
||||||
onModalContent(node);
|
onModalContent(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +91,7 @@ MapMenu.defaultProps = {
|
|||||||
right: "initial",
|
right: "initial",
|
||||||
bottom: "initial",
|
bottom: "initial",
|
||||||
style: {},
|
style: {},
|
||||||
|
excludeNode: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MapMenu;
|
export default MapMenu;
|
||||||
|
Loading…
Reference in New Issue
Block a user