Simplified menu interaction prevention
This commit is contained in:
parent
6b675d8200
commit
9e01ad1d0e
@ -163,12 +163,12 @@ function Map({
|
|||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
const tokenMenu = isTokenMenuOpen && (
|
const tokenMenu = (
|
||||||
<TokenMenu
|
<TokenMenu
|
||||||
isOpen={isTokenMenuOpen}
|
isOpen={isTokenMenuOpen}
|
||||||
onRequestClose={() => setIsTokenMenuOpen(false)}
|
onRequestClose={() => setIsTokenMenuOpen(false)}
|
||||||
onTokenChange={onMapTokenStateChange}
|
onTokenChange={onMapTokenStateChange}
|
||||||
tokenState={mapState.tokens[tokenMenuOptions.tokenStateId]}
|
tokenState={mapState && mapState.tokens[tokenMenuOptions.tokenStateId]}
|
||||||
tokenImage={tokenMenuOptions.tokenImage}
|
tokenImage={tokenMenuOptions.tokenImage}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -4,6 +4,8 @@ import { useThemeUI } from "theme-ui";
|
|||||||
|
|
||||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||||
|
|
||||||
|
import usePrevious from "../../helpers/usePrevious";
|
||||||
|
|
||||||
function MapMenu({
|
function MapMenu({
|
||||||
isOpen,
|
isOpen,
|
||||||
onRequestClose,
|
onRequestClose,
|
||||||
@ -22,7 +24,16 @@ function MapMenu({
|
|||||||
// callback
|
// callback
|
||||||
const [modalContentNode, setModalContentNode] = useState(null);
|
const [modalContentNode, setModalContentNode] = useState(null);
|
||||||
|
|
||||||
|
// Toggle map interaction when menu is opened
|
||||||
|
const wasOpen = usePrevious(isOpen);
|
||||||
const { setPreventMapInteraction } = useContext(MapInteractionContext);
|
const { setPreventMapInteraction } = useContext(MapInteractionContext);
|
||||||
|
useEffect(() => {
|
||||||
|
if (isOpen && !wasOpen) {
|
||||||
|
setPreventMapInteraction(true);
|
||||||
|
} else if (wasOpen && !isOpen) {
|
||||||
|
setPreventMapInteraction(false);
|
||||||
|
}
|
||||||
|
}, [isOpen, setPreventMapInteraction, wasOpen]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Close modal if interacting with any other element
|
// Close modal if interacting with any other element
|
||||||
@ -32,31 +43,29 @@ function MapMenu({
|
|||||||
!path.includes(modalContentNode) &&
|
!path.includes(modalContentNode) &&
|
||||||
!(excludeNode && path.includes(excludeNode))
|
!(excludeNode && path.includes(excludeNode))
|
||||||
) {
|
) {
|
||||||
setPreventMapInteraction(false);
|
|
||||||
onRequestClose();
|
onRequestClose();
|
||||||
document.body.removeEventListener("pointerdown", handlePointerDown);
|
document.body.removeEventListener("pointerdown", handlePointerDown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modalContentNode) {
|
if (modalContentNode) {
|
||||||
setPreventMapInteraction(true);
|
|
||||||
document.body.addEventListener("pointerdown", handlePointerDown);
|
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",
|
||||||
() => {
|
() => {
|
||||||
setPreventMapInteraction(false);
|
|
||||||
onRequestClose();
|
onRequestClose();
|
||||||
},
|
},
|
||||||
{ once: true }
|
{ once: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (modalContentNode) {
|
if (modalContentNode) {
|
||||||
document.body.removeEventListener("pointerdown", handlePointerDown);
|
document.body.removeEventListener("pointerdown", handlePointerDown);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [modalContentNode, excludeNode, onRequestClose, setPreventMapInteraction]);
|
}, [modalContentNode, excludeNode, onRequestClose]);
|
||||||
|
|
||||||
function handleModalContent(node) {
|
function handleModalContent(node) {
|
||||||
setModalContentNode(node);
|
setModalContentNode(node);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState, useContext } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Box, Input, Slider, Flex, Text } from "theme-ui";
|
import { Box, Input, Slider, Flex, Text } from "theme-ui";
|
||||||
|
|
||||||
import MapMenu from "../map/MapMenu";
|
import MapMenu from "../map/MapMenu";
|
||||||
@ -7,8 +7,6 @@ import colors, { colorOptions } from "../../helpers/colors";
|
|||||||
|
|
||||||
import usePrevious from "../../helpers/usePrevious";
|
import usePrevious from "../../helpers/usePrevious";
|
||||||
|
|
||||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
|
||||||
|
|
||||||
const defaultTokenMaxSize = 6;
|
const defaultTokenMaxSize = 6;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,7 +32,7 @@ function TokenMenu({
|
|||||||
|
|
||||||
const [tokenMaxSize, setTokenMaxSize] = useState(defaultTokenMaxSize);
|
const [tokenMaxSize, setTokenMaxSize] = useState(defaultTokenMaxSize);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen && !wasOpen) {
|
if (isOpen && !wasOpen && tokenState) {
|
||||||
setTokenMaxSize(Math.max(tokenState.size, defaultTokenMaxSize));
|
setTokenMaxSize(Math.max(tokenState.size, defaultTokenMaxSize));
|
||||||
}
|
}
|
||||||
}, [isOpen, tokenState, wasOpen]);
|
}, [isOpen, tokenState, wasOpen]);
|
||||||
@ -99,8 +97,6 @@ function TokenMenu({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { setPreventMapInteraction } = useContext(MapInteractionContext);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MapMenu
|
<MapMenu
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
@ -114,7 +110,6 @@ function TokenMenu({
|
|||||||
as="form"
|
as="form"
|
||||||
onSubmit={(e) => {
|
onSubmit={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setPreventMapInteraction(false);
|
|
||||||
onRequestClose();
|
onRequestClose();
|
||||||
}}
|
}}
|
||||||
sx={{ alignItems: "center" }}
|
sx={{ alignItems: "center" }}
|
||||||
@ -130,7 +125,7 @@ function TokenMenu({
|
|||||||
<Input
|
<Input
|
||||||
id="changeTokenLabel"
|
id="changeTokenLabel"
|
||||||
onChange={handleLabelChange}
|
onChange={handleLabelChange}
|
||||||
value={tokenState.label}
|
value={(tokenState && tokenState.label) || ""}
|
||||||
sx={{
|
sx={{
|
||||||
padding: "4px",
|
padding: "4px",
|
||||||
border: "none",
|
border: "none",
|
||||||
@ -162,18 +157,20 @@ function TokenMenu({
|
|||||||
onClick={() => handleStatusChange(color)}
|
onClick={() => handleStatusChange(color)}
|
||||||
aria-label={`Token label Color ${color}`}
|
aria-label={`Token label Color ${color}`}
|
||||||
>
|
>
|
||||||
{tokenState.statuses && tokenState.statuses.includes(color) && (
|
{tokenState &&
|
||||||
<Box
|
tokenState.statuses &&
|
||||||
sx={{
|
tokenState.statuses.includes(color) && (
|
||||||
width: "100%",
|
<Box
|
||||||
height: "100%",
|
sx={{
|
||||||
border: "2px solid white",
|
width: "100%",
|
||||||
position: "absolute",
|
height: "100%",
|
||||||
top: 0,
|
border: "2px solid white",
|
||||||
borderRadius: "50%",
|
position: "absolute",
|
||||||
}}
|
top: 0,
|
||||||
/>
|
borderRadius: "50%",
|
||||||
)}
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
@ -187,7 +184,7 @@ function TokenMenu({
|
|||||||
Size:
|
Size:
|
||||||
</Text>
|
</Text>
|
||||||
<Slider
|
<Slider
|
||||||
value={tokenState.size || 1}
|
value={(tokenState && tokenState.size) || 1}
|
||||||
onChange={handleSizeChange}
|
onChange={handleSizeChange}
|
||||||
step={1}
|
step={1}
|
||||||
min={1}
|
min={1}
|
||||||
|
Loading…
Reference in New Issue
Block a user