Added map control submenus for brush color and erase all
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from "react";
|
||||
import { Flex, Box, IconButton } from "theme-ui";
|
||||
import { Flex, Box, IconButton, Button } from "theme-ui";
|
||||
|
||||
import AddMapButton from "./AddMapButton";
|
||||
import ExpandMoreIcon from "../icons/ExpandMoreIcon";
|
||||
@@ -9,6 +9,10 @@ import EraseToolIcon from "../icons/EraseToolIcon";
|
||||
import UndoIcon from "../icons/UndoIcon";
|
||||
import RedoIcon from "../icons/RedoIcon";
|
||||
|
||||
import colors, { colorOptions } from "../helpers/colors";
|
||||
|
||||
import MapMenu from "./MapMenu";
|
||||
|
||||
function MapControls({
|
||||
onMapChange,
|
||||
onToolChange,
|
||||
@@ -18,9 +22,85 @@ function MapControls({
|
||||
onRedo,
|
||||
undoDisabled,
|
||||
redoDisabled,
|
||||
brushColor,
|
||||
onBrushColorChange,
|
||||
onEraseAll,
|
||||
}) {
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
|
||||
const subMenus = {
|
||||
brush: (
|
||||
<Box sx={{ width: "104px" }} p={1}>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
{colorOptions.map((color) => (
|
||||
<Box
|
||||
key={color}
|
||||
sx={{
|
||||
width: "25%",
|
||||
paddingTop: "25%",
|
||||
borderRadius: "50%",
|
||||
transform: "scale(0.75)",
|
||||
backgroundColor: colors[color],
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => onBrushColorChange(color)}
|
||||
>
|
||||
{brushColor === color && (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
border: "2px solid white",
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
borderRadius: "50%",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
),
|
||||
erase: (
|
||||
<Box p={1}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => {
|
||||
onEraseAll();
|
||||
setCurrentSubmenu({});
|
||||
}}
|
||||
>
|
||||
Erase All
|
||||
</Button>
|
||||
</Box>
|
||||
),
|
||||
};
|
||||
|
||||
const [currentSubmenu, setCurrentSubmenu] = useState(null);
|
||||
const [currentSubmenuOptions, setCurrentSubmenuOptions] = useState({});
|
||||
|
||||
function handleToolClick(event, tool) {
|
||||
if (tool !== selectedTool) {
|
||||
onToolChange(tool);
|
||||
} else if (subMenus[tool]) {
|
||||
const toolRect = event.target.getBoundingClientRect();
|
||||
setCurrentSubmenu(tool);
|
||||
setCurrentSubmenuOptions({
|
||||
// Align the right of the submenu to the left of the tool and center vertically
|
||||
left: `${toolRect.left - 4}px`,
|
||||
top: `${toolRect.bottom - toolRect.height / 2}px`,
|
||||
style: { transform: "translate(-100%, -50%)" },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const divider = (
|
||||
<Box
|
||||
my={2}
|
||||
@@ -29,82 +109,94 @@ function MapControls({
|
||||
></Box>
|
||||
);
|
||||
return (
|
||||
<Flex
|
||||
p={2}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
right: 0,
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<IconButton
|
||||
aria-label={isExpanded ? "Hide Map Controls" : "Show Map Controls"}
|
||||
title={isExpanded ? "Hide Map Controls" : "Show Map Controls"}
|
||||
onClick={() => setIsExpanded(!isExpanded)}
|
||||
sx={{
|
||||
transform: `rotate(${isExpanded ? "0" : "180deg"})`,
|
||||
display: "block",
|
||||
}}
|
||||
>
|
||||
<ExpandMoreIcon />
|
||||
</IconButton>
|
||||
<Box
|
||||
<>
|
||||
<Flex
|
||||
p={2}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
right: 0,
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
display: isExpanded ? "flex" : "none",
|
||||
}}
|
||||
>
|
||||
<AddMapButton onMapChange={onMapChange} />
|
||||
{divider}
|
||||
<IconButton
|
||||
aria-label="Pan Tool"
|
||||
title="Pan Tool"
|
||||
onClick={() => onToolChange("pan")}
|
||||
sx={{ color: selectedTool === "pan" ? "primary" : "text" }}
|
||||
disabled={disabledTools.includes("pan")}
|
||||
aria-label={isExpanded ? "Hide Map Controls" : "Show Map Controls"}
|
||||
title={isExpanded ? "Hide Map Controls" : "Show Map Controls"}
|
||||
onClick={() => setIsExpanded(!isExpanded)}
|
||||
sx={{
|
||||
transform: `rotate(${isExpanded ? "0" : "180deg"})`,
|
||||
display: "block",
|
||||
}}
|
||||
>
|
||||
<PanToolIcon />
|
||||
<ExpandMoreIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
aria-label="Brush Tool"
|
||||
title="Brush Tool"
|
||||
onClick={() => onToolChange("brush")}
|
||||
sx={{ color: selectedTool === "brush" ? "primary" : "text" }}
|
||||
disabled={disabledTools.includes("brush")}
|
||||
<Box
|
||||
sx={{
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
display: isExpanded ? "flex" : "none",
|
||||
}}
|
||||
>
|
||||
<BrushToolIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
aria-label="Erase Tool"
|
||||
title="Erase Tool"
|
||||
onClick={() => onToolChange("erase")}
|
||||
sx={{ color: selectedTool === "erase" ? "primary" : "text" }}
|
||||
disabled={disabledTools.includes("erase")}
|
||||
>
|
||||
<EraseToolIcon />
|
||||
</IconButton>
|
||||
{divider}
|
||||
<IconButton
|
||||
aria-label="Undo"
|
||||
title="Undo"
|
||||
onClick={() => onUndo()}
|
||||
disabled={undoDisabled}
|
||||
>
|
||||
<UndoIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
aria-label="Redo"
|
||||
title="Redo"
|
||||
onClick={() => onRedo()}
|
||||
disabled={redoDisabled}
|
||||
>
|
||||
<RedoIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</Flex>
|
||||
<AddMapButton onMapChange={onMapChange} />
|
||||
{divider}
|
||||
<IconButton
|
||||
aria-label="Pan Tool"
|
||||
title="Pan Tool"
|
||||
onClick={(e) => handleToolClick(e, "pan")}
|
||||
sx={{ color: selectedTool === "pan" ? "primary" : "text" }}
|
||||
disabled={disabledTools.includes("pan")}
|
||||
>
|
||||
<PanToolIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
aria-label="Brush Tool"
|
||||
title="Brush Tool"
|
||||
onClick={(e) => handleToolClick(e, "brush")}
|
||||
sx={{ color: selectedTool === "brush" ? "primary" : "text" }}
|
||||
disabled={disabledTools.includes("brush")}
|
||||
>
|
||||
<BrushToolIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
aria-label="Erase Tool"
|
||||
title="Erase Tool"
|
||||
onClick={(e) => handleToolClick(e, "erase")}
|
||||
sx={{ color: selectedTool === "erase" ? "primary" : "text" }}
|
||||
disabled={disabledTools.includes("erase")}
|
||||
>
|
||||
<EraseToolIcon />
|
||||
</IconButton>
|
||||
{divider}
|
||||
<IconButton
|
||||
aria-label="Undo"
|
||||
title="Undo"
|
||||
onClick={() => onUndo()}
|
||||
disabled={undoDisabled}
|
||||
>
|
||||
<UndoIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
aria-label="Redo"
|
||||
title="Redo"
|
||||
onClick={() => onRedo()}
|
||||
disabled={redoDisabled}
|
||||
>
|
||||
<RedoIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</Flex>
|
||||
<MapMenu
|
||||
isOpen={!!currentSubmenu}
|
||||
onRequestClose={() => {
|
||||
setCurrentSubmenu(null);
|
||||
setCurrentSubmenuOptions({});
|
||||
}}
|
||||
{...currentSubmenuOptions}
|
||||
>
|
||||
{currentSubmenu && subMenus[currentSubmenu]}
|
||||
</MapMenu>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user