Added map collapsable tool settings for small screens
This commit is contained in:
parent
b7a430ce18
commit
e3704879c9
@ -1,9 +1,11 @@
|
|||||||
import React, { useEffect, useContext } from "react";
|
import React, { useEffect, useContext } from "react";
|
||||||
import { Flex, IconButton } from "theme-ui";
|
import { Flex, IconButton } from "theme-ui";
|
||||||
|
import { useMedia } from "react-media";
|
||||||
|
|
||||||
import ColorControl from "./ColorControl";
|
import ColorControl from "./ColorControl";
|
||||||
import AlphaBlendToggle from "./AlphaBlendToggle";
|
import AlphaBlendToggle from "./AlphaBlendToggle";
|
||||||
import RadioIconButton from "./RadioIconButton";
|
import RadioIconButton from "./RadioIconButton";
|
||||||
|
import ToolSection from "./ToolSection";
|
||||||
|
|
||||||
import BrushIcon from "../../../icons/BrushToolIcon";
|
import BrushIcon from "../../../icons/BrushToolIcon";
|
||||||
import BrushPaintIcon from "../../../icons/BrushPaintIcon";
|
import BrushPaintIcon from "../../../icons/BrushPaintIcon";
|
||||||
@ -78,6 +80,47 @@ function DrawingToolSettings({
|
|||||||
}
|
}
|
||||||
}, [disabledActions, settings, onSettingChange]);
|
}, [disabledActions, settings, onSettingChange]);
|
||||||
|
|
||||||
|
const isSmallScreen = useMedia({ query: "(max-width: 799px)" });
|
||||||
|
|
||||||
|
const tools = [
|
||||||
|
{
|
||||||
|
id: "brush",
|
||||||
|
title: "Brush",
|
||||||
|
isSelected: settings.type === "brush",
|
||||||
|
icon: <BrushIcon />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "paint",
|
||||||
|
title: "Paint",
|
||||||
|
isSelected: settings.type === "paint",
|
||||||
|
icon: <BrushPaintIcon />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "line",
|
||||||
|
title: "Line",
|
||||||
|
isSelected: settings.type === "line",
|
||||||
|
icon: <BrushLineIcon />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "rectangle",
|
||||||
|
title: "Rectangle",
|
||||||
|
isSelected: settings.type === "rectangle",
|
||||||
|
icon: <BrushRectangleIcon />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "circle",
|
||||||
|
title: "Circle",
|
||||||
|
isSelected: settings.type === "circle",
|
||||||
|
icon: <BrushCircleIcon />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "triangle",
|
||||||
|
title: "Triangle",
|
||||||
|
isSelected: settings.type === "triangle",
|
||||||
|
icon: <BrushTriangleIcon />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex sx={{ alignItems: "center" }}>
|
<Flex sx={{ alignItems: "center" }}>
|
||||||
<ColorControl
|
<ColorControl
|
||||||
@ -85,48 +128,11 @@ function DrawingToolSettings({
|
|||||||
onColorChange={(color) => onSettingChange({ color })}
|
onColorChange={(color) => onSettingChange({ color })}
|
||||||
/>
|
/>
|
||||||
<Divider vertical />
|
<Divider vertical />
|
||||||
<RadioIconButton
|
<ToolSection
|
||||||
title="Brush"
|
tools={tools}
|
||||||
onClick={() => onSettingChange({ type: "brush" })}
|
onToolClick={(tool) => onSettingChange({ type: tool.id })}
|
||||||
isSelected={settings.type === "brush"}
|
collapse={isSmallScreen}
|
||||||
>
|
/>
|
||||||
<BrushIcon />
|
|
||||||
</RadioIconButton>
|
|
||||||
<RadioIconButton
|
|
||||||
title="Paint"
|
|
||||||
onClick={() => onSettingChange({ type: "paint" })}
|
|
||||||
isSelected={settings.type === "paint"}
|
|
||||||
>
|
|
||||||
<BrushPaintIcon />
|
|
||||||
</RadioIconButton>
|
|
||||||
<RadioIconButton
|
|
||||||
title="Line"
|
|
||||||
onClick={() => onSettingChange({ type: "line" })}
|
|
||||||
isSelected={settings.type === "line"}
|
|
||||||
>
|
|
||||||
<BrushLineIcon />
|
|
||||||
</RadioIconButton>
|
|
||||||
<RadioIconButton
|
|
||||||
title="Rectangle"
|
|
||||||
onClick={() => onSettingChange({ type: "rectangle" })}
|
|
||||||
isSelected={settings.type === "rectangle"}
|
|
||||||
>
|
|
||||||
<BrushRectangleIcon />
|
|
||||||
</RadioIconButton>
|
|
||||||
<RadioIconButton
|
|
||||||
title="Circle"
|
|
||||||
onClick={() => onSettingChange({ type: "circle" })}
|
|
||||||
isSelected={settings.type === "circle"}
|
|
||||||
>
|
|
||||||
<BrushCircleIcon />
|
|
||||||
</RadioIconButton>
|
|
||||||
<RadioIconButton
|
|
||||||
title="Triangle"
|
|
||||||
onClick={() => onSettingChange({ type: "triangle" })}
|
|
||||||
isSelected={settings.type === "triangle"}
|
|
||||||
>
|
|
||||||
<BrushTriangleIcon />
|
|
||||||
</RadioIconButton>
|
|
||||||
<Divider vertical />
|
<Divider vertical />
|
||||||
<RadioIconButton
|
<RadioIconButton
|
||||||
title="Erase"
|
title="Erase"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useContext, useEffect } from "react";
|
import React, { useContext, useEffect } from "react";
|
||||||
import { Flex } from "theme-ui";
|
import { Flex } from "theme-ui";
|
||||||
|
import { useMedia } from "react-media";
|
||||||
|
|
||||||
import EdgeSnappingToggle from "./EdgeSnappingToggle";
|
import EdgeSnappingToggle from "./EdgeSnappingToggle";
|
||||||
import RadioIconButton from "./RadioIconButton";
|
import RadioIconButton from "./RadioIconButton";
|
||||||
@ -17,6 +18,7 @@ import RedoButton from "./RedoButton";
|
|||||||
import Divider from "../../Divider";
|
import Divider from "../../Divider";
|
||||||
|
|
||||||
import MapInteractionContext from "../../../contexts/MapInteractionContext";
|
import MapInteractionContext from "../../../contexts/MapInteractionContext";
|
||||||
|
import ToolSection from "./ToolSection";
|
||||||
|
|
||||||
function BrushToolSettings({
|
function BrushToolSettings({
|
||||||
settings,
|
settings,
|
||||||
@ -72,22 +74,44 @@ function BrushToolSettings({
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isSmallScreen = useMedia({ query: "(max-width: 799px)" });
|
||||||
|
const drawTools = [
|
||||||
|
{
|
||||||
|
id: "polygon",
|
||||||
|
title: "Fog Polygon",
|
||||||
|
isSelected: settings.type === "polygon",
|
||||||
|
icon: <FogPolygonIcon />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "brush",
|
||||||
|
title: "Fog Brush",
|
||||||
|
isSelected: settings.type === "brush",
|
||||||
|
icon: <FogBrushIcon />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const modeTools = [
|
||||||
|
{
|
||||||
|
id: "add",
|
||||||
|
title: "Add Fog",
|
||||||
|
isSelected: !settings.useFogSubtract,
|
||||||
|
icon: <FogAddIcon />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "subtract",
|
||||||
|
title: "Subtracy Fog",
|
||||||
|
isSelected: settings.useFogSubtract,
|
||||||
|
icon: <FogSubtractIcon />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex sx={{ alignItems: "center" }}>
|
<Flex sx={{ alignItems: "center" }}>
|
||||||
<RadioIconButton
|
<ToolSection
|
||||||
title="Fog Polygon"
|
tools={drawTools}
|
||||||
onClick={() => onSettingChange({ type: "polygon" })}
|
onToolClick={(tool) => onSettingChange({ type: tool.id })}
|
||||||
isSelected={settings.type === "polygon"}
|
collapse={isSmallScreen}
|
||||||
>
|
/>
|
||||||
<FogPolygonIcon />
|
|
||||||
</RadioIconButton>
|
|
||||||
<RadioIconButton
|
|
||||||
title="Fog Brush"
|
|
||||||
onClick={() => onSettingChange({ type: "brush" })}
|
|
||||||
isSelected={settings.type === "brush"}
|
|
||||||
>
|
|
||||||
<FogBrushIcon />
|
|
||||||
</RadioIconButton>
|
|
||||||
<Divider vertical />
|
<Divider vertical />
|
||||||
<RadioIconButton
|
<RadioIconButton
|
||||||
title="Toggle Fog"
|
title="Toggle Fog"
|
||||||
@ -104,20 +128,13 @@ function BrushToolSettings({
|
|||||||
<FogRemoveIcon />
|
<FogRemoveIcon />
|
||||||
</RadioIconButton>
|
</RadioIconButton>
|
||||||
<Divider vertical />
|
<Divider vertical />
|
||||||
<RadioIconButton
|
<ToolSection
|
||||||
title="Add Fog"
|
tools={modeTools}
|
||||||
onClick={() => onSettingChange({ useFogSubtract: false })}
|
onToolClick={(tool) =>
|
||||||
isSelected={!settings.useFogSubtract}
|
onSettingChange({ useFogSubtract: tool.id === "subtract" })
|
||||||
>
|
}
|
||||||
<FogAddIcon />
|
collapse={isSmallScreen}
|
||||||
</RadioIconButton>
|
/>
|
||||||
<RadioIconButton
|
|
||||||
title="Subtract Fog"
|
|
||||||
onClick={() => onSettingChange({ useFogSubtract: true })}
|
|
||||||
isSelected={settings.useFogSubtract}
|
|
||||||
>
|
|
||||||
<FogSubtractIcon />
|
|
||||||
</RadioIconButton>
|
|
||||||
<Divider vertical />
|
<Divider vertical />
|
||||||
<EdgeSnappingToggle
|
<EdgeSnappingToggle
|
||||||
useEdgeSnapping={settings.useEdgeSnapping}
|
useEdgeSnapping={settings.useEdgeSnapping}
|
||||||
|
99
src/components/map/controls/ToolSection.js
Normal file
99
src/components/map/controls/ToolSection.js
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { Box, Flex } from "theme-ui";
|
||||||
|
|
||||||
|
import RadioIconButton from "./RadioIconButton";
|
||||||
|
|
||||||
|
// Section of map tools with the option to collapse into a vertical list
|
||||||
|
function ToolSection({ collapse, tools, onToolClick }) {
|
||||||
|
const [showMore, setShowMore] = useState(false);
|
||||||
|
const [collapsedTool, setCollapsedTool] = useState();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const selectedTool = tools.find((tool) => tool.isSelected);
|
||||||
|
if (selectedTool) {
|
||||||
|
setCollapsedTool(selectedTool);
|
||||||
|
} else {
|
||||||
|
setCollapsedTool(
|
||||||
|
(prevTool) => prevTool && { ...prevTool, isSelected: false }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, [tools]);
|
||||||
|
|
||||||
|
function handleToolClick(tool) {
|
||||||
|
if (collapse && tool.isSelected) {
|
||||||
|
setShowMore(!showMore);
|
||||||
|
} else if (collapse && !tool.isSelected) {
|
||||||
|
setShowMore(false);
|
||||||
|
}
|
||||||
|
onToolClick(tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTool(tool) {
|
||||||
|
return (
|
||||||
|
<RadioIconButton
|
||||||
|
title={tool.title}
|
||||||
|
onClick={() => handleToolClick(tool)}
|
||||||
|
key={tool.id}
|
||||||
|
isSelected={tool.isSelected}
|
||||||
|
>
|
||||||
|
{tool.icon}
|
||||||
|
</RadioIconButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collapse) {
|
||||||
|
if (!collapsedTool) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Box sx={{ position: "relative" }}>
|
||||||
|
{renderTool(collapsedTool)}
|
||||||
|
{/* Render chevron when more tools is available */}
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
position: "absolute",
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
borderTop: "4px solid",
|
||||||
|
borderTopColor: "text",
|
||||||
|
borderLeft: "4px solid transparent",
|
||||||
|
borderRight: "4px solid transparent",
|
||||||
|
transform: "translate(0, -4px) rotate(-45deg)",
|
||||||
|
bottom: 0,
|
||||||
|
right: 0,
|
||||||
|
pointerEvents: "none",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{showMore && (
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
position: "absolute",
|
||||||
|
top: "40px",
|
||||||
|
left: "50%",
|
||||||
|
transform: "translateX(-50%)",
|
||||||
|
flexDirection: "column",
|
||||||
|
borderRadius: "4px",
|
||||||
|
}}
|
||||||
|
bg="overlay"
|
||||||
|
p={2}
|
||||||
|
>
|
||||||
|
{tools.filter((tool) => !tool.isSelected).map(renderTool)}
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return tools.map((tool) => (
|
||||||
|
<RadioIconButton
|
||||||
|
title={tool.title}
|
||||||
|
onClick={() => handleToolClick(tool)}
|
||||||
|
key={tool.id}
|
||||||
|
isSelected={tool.isSelected}
|
||||||
|
>
|
||||||
|
{tool.icon}
|
||||||
|
</RadioIconButton>
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ToolSection;
|
Loading…
Reference in New Issue
Block a user