Added map collapsable tool settings for small screens

This commit is contained in:
Mitchell McCaffrey 2020-06-25 18:56:51 +10:00
parent b7a430ce18
commit e3704879c9
3 changed files with 192 additions and 70 deletions

View File

@ -1,9 +1,11 @@
import React, { useEffect, useContext } from "react";
import { Flex, IconButton } from "theme-ui";
import { useMedia } from "react-media";
import ColorControl from "./ColorControl";
import AlphaBlendToggle from "./AlphaBlendToggle";
import RadioIconButton from "./RadioIconButton";
import ToolSection from "./ToolSection";
import BrushIcon from "../../../icons/BrushToolIcon";
import BrushPaintIcon from "../../../icons/BrushPaintIcon";
@ -78,6 +80,47 @@ function DrawingToolSettings({
}
}, [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 (
<Flex sx={{ alignItems: "center" }}>
<ColorControl
@ -85,48 +128,11 @@ function DrawingToolSettings({
onColorChange={(color) => onSettingChange({ color })}
/>
<Divider vertical />
<RadioIconButton
title="Brush"
onClick={() => onSettingChange({ type: "brush" })}
isSelected={settings.type === "brush"}
>
<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>
<ToolSection
tools={tools}
onToolClick={(tool) => onSettingChange({ type: tool.id })}
collapse={isSmallScreen}
/>
<Divider vertical />
<RadioIconButton
title="Erase"

View File

@ -1,5 +1,6 @@
import React, { useContext, useEffect } from "react";
import { Flex } from "theme-ui";
import { useMedia } from "react-media";
import EdgeSnappingToggle from "./EdgeSnappingToggle";
import RadioIconButton from "./RadioIconButton";
@ -17,6 +18,7 @@ import RedoButton from "./RedoButton";
import Divider from "../../Divider";
import MapInteractionContext from "../../../contexts/MapInteractionContext";
import ToolSection from "./ToolSection";
function BrushToolSettings({
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 (
<Flex sx={{ alignItems: "center" }}>
<RadioIconButton
title="Fog Polygon"
onClick={() => onSettingChange({ type: "polygon" })}
isSelected={settings.type === "polygon"}
>
<FogPolygonIcon />
</RadioIconButton>
<RadioIconButton
title="Fog Brush"
onClick={() => onSettingChange({ type: "brush" })}
isSelected={settings.type === "brush"}
>
<FogBrushIcon />
</RadioIconButton>
<ToolSection
tools={drawTools}
onToolClick={(tool) => onSettingChange({ type: tool.id })}
collapse={isSmallScreen}
/>
<Divider vertical />
<RadioIconButton
title="Toggle Fog"
@ -104,20 +128,13 @@ function BrushToolSettings({
<FogRemoveIcon />
</RadioIconButton>
<Divider vertical />
<RadioIconButton
title="Add Fog"
onClick={() => onSettingChange({ useFogSubtract: false })}
isSelected={!settings.useFogSubtract}
>
<FogAddIcon />
</RadioIconButton>
<RadioIconButton
title="Subtract Fog"
onClick={() => onSettingChange({ useFogSubtract: true })}
isSelected={settings.useFogSubtract}
>
<FogSubtractIcon />
</RadioIconButton>
<ToolSection
tools={modeTools}
onToolClick={(tool) =>
onSettingChange({ useFogSubtract: tool.id === "subtract" })
}
collapse={isSmallScreen}
/>
<Divider vertical />
<EdgeSnappingToggle
useEdgeSnapping={settings.useEdgeSnapping}

View 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;