Add type to controls and change colour types

This commit is contained in:
Mitchell McCaffrey
2021-07-09 22:06:32 +10:00
parent 72b6994a2e
commit 49b8caa2d7
21 changed files with 238 additions and 148 deletions

View File

@@ -1,10 +1,17 @@
import React from "react";
import { IconButton } from "theme-ui";
import BlendOnIcon from "../../../icons/BlendOnIcon";
import BlendOffIcon from "../../../icons/BlendOffIcon";
function AlphaBlendToggle({ useBlending, onBlendingChange }) {
type AlphaBlendToggleProps = {
useBlending: boolean;
onBlendingChange: (useBlending: boolean) => void;
};
function AlphaBlendToggle({
useBlending,
onBlendingChange,
}: AlphaBlendToggleProps) {
return (
<IconButton
aria-label={useBlending ? "Disable Blending (O)" : "Enable Blending (O)"}

View File

@@ -1,10 +1,16 @@
import React, { useState } from "react";
import { Box } from "theme-ui";
import { Box, SxProp } from "theme-ui";
import colors, { colorOptions } from "../../../helpers/colors";
import colors, { colorOptions, Color } from "../../../helpers/colors";
import MapMenu from "../MapMenu";
function ColorCircle({ color, selected, onClick, sx }) {
type ColorCircleProps = {
color: Color;
selected: boolean;
onClick?: React.MouseEventHandler<HTMLDivElement>;
} & SxProp;
function ColorCircle({ color, selected, onClick, sx }: ColorCircleProps) {
return (
<Box
key={color}
@@ -34,24 +40,30 @@ function ColorCircle({ color, selected, onClick, sx }) {
);
}
function ColorControl({ color, onColorChange, exclude }) {
type ColorControlProps = {
color: Color;
onColorChange: (newColor: Color) => void;
exclude: Color[];
};
function ColorControl({ color, onColorChange, exclude }: ColorControlProps) {
const [showColorMenu, setShowColorMenu] = useState(false);
const [colorMenuOptions, setColorMenuOptions] = useState({});
function handleControlClick(event) {
function handleControlClick(event: React.MouseEvent<HTMLDivElement>) {
if (showColorMenu) {
setShowColorMenu(false);
setColorMenuOptions({});
} else {
setShowColorMenu(true);
const rect = event.target.getBoundingClientRect();
const rect = event.currentTarget.getBoundingClientRect();
setColorMenuOptions({
// Align the right of the submenu to the left of the tool and center vertically
left: `${rect.left + rect.width / 2}px`,
top: `${rect.bottom + 16}px`,
style: { transform: "translateX(-50%)" },
// Exclude this node from the sub menus auto close
excludeNode: event.target,
excludeNode: event.currentTarget,
});
}
}

View File

@@ -1,4 +1,4 @@
import React, { useEffect } from "react";
import { useEffect } from "react";
import { Flex, IconButton } from "theme-ui";
import { useMedia } from "react-media";
@@ -26,14 +26,23 @@ import { useKeyboard } from "../../../contexts/KeyboardContext";
import shortcuts from "../../../shortcuts";
import { DrawingToolSettings, DrawingToolType } from "../../../types/Drawing";
type DrawingToolSettingsProps = {
settings: DrawingToolSettings;
onSettingChange: (change: Partial<DrawingToolSettings>) => void;
onToolAction: (action: string) => void;
disabledActions: string[];
};
function DrawingToolSettings({
settings,
onSettingChange,
onToolAction,
disabledActions,
}) {
}: DrawingToolSettingsProps) {
// Keyboard shotcuts
function handleKeyDown(event) {
function handleKeyDown(event: KeyboardEvent) {
if (shortcuts.drawBrush(event)) {
onSettingChange({ type: "brush" });
} else if (shortcuts.drawPaint(event)) {
@@ -115,7 +124,9 @@ function DrawingToolSettings({
<Divider vertical />
<ToolSection
tools={tools}
onToolClick={(tool) => onSettingChange({ type: tool.id })}
onToolClick={(tool) =>
onSettingChange({ type: tool.id as DrawingToolType })
}
collapse={isSmallScreen}
/>
<Divider vertical />

View File

@@ -1,10 +1,19 @@
import React from "react";
import { IconButton } from "theme-ui";
import CutOnIcon from "../../../icons/FogCutOnIcon";
import CutOffIcon from "../../../icons/FogCutOffIcon";
function FogCutToggle({ useFogCut, onFogCutChange, disabled }) {
type FogCutToggleProps = {
useFogCut: boolean;
onFogCutChange: (useFogCut: boolean) => void;
disabled?: boolean;
};
function FogCutToggle({
useFogCut,
onFogCutChange,
disabled,
}: FogCutToggleProps) {
return (
<IconButton
aria-label={

View File

@@ -1,10 +1,17 @@
import React from "react";
import { IconButton } from "theme-ui";
import PreviewOnIcon from "../../../icons/FogPreviewOnIcon";
import PreviewOffIcon from "../../../icons/FogPreviewOffIcon";
function FogPreviewToggle({ useFogPreview, onFogPreviewChange }) {
type FogPreviewToggleProps = {
useFogPreview: boolean;
onFogPreviewChange: (useFogCut: boolean) => void;
};
function FogPreviewToggle({
useFogPreview,
onFogPreviewChange,
}: FogPreviewToggleProps) {
return (
<IconButton
aria-label={

View File

@@ -1,4 +1,3 @@
import React from "react";
import { Flex } from "theme-ui";
import { useMedia } from "react-media";
@@ -24,14 +23,23 @@ import { useKeyboard } from "../../../contexts/KeyboardContext";
import shortcuts from "../../../shortcuts";
function BrushToolSettings({
import { FogToolSettings, FogToolType } from "../../../types/Fog";
type FogToolSettingsProps = {
settings: FogToolSettings;
onSettingChange: (change: Partial<FogToolSettings>) => void;
onToolAction: (action: string) => void;
disabledActions: string[];
};
function FogToolSettings({
settings,
onSettingChange,
onToolAction,
disabledActions,
}) {
}: FogToolSettingsProps) {
// Keyboard shortcuts
function handleKeyDown(event) {
function handleKeyDown(event: KeyboardEvent) {
if (shortcuts.fogPolygon(event)) {
onSettingChange({ type: "polygon" });
} else if (shortcuts.fogBrush(event)) {
@@ -86,7 +94,9 @@ function BrushToolSettings({
<Flex sx={{ alignItems: "center" }}>
<ToolSection
tools={drawTools}
onToolClick={(tool) => onSettingChange({ type: tool.id })}
onToolClick={(tool) =>
onSettingChange({ type: tool.id as FogToolType })
}
collapse={isSmallScreen}
/>
<Divider vertical />
@@ -134,4 +144,4 @@ function BrushToolSettings({
);
}
export default BrushToolSettings;
export default FogToolSettings;

View File

@@ -1,10 +1,19 @@
import React from "react";
import { IconButton } from "theme-ui";
import MultilayerOnIcon from "../../../icons/FogMultilayerOnIcon";
import MultilayerOffIcon from "../../../icons/FogMultilayerOffIcon";
function MultilayerToggle({ multilayer, onMultilayerChange, disabled }) {
type MultilayerToggleProps = {
multilayer: boolean;
onMultilayerChange: (multilayer: boolean) => void;
disabled?: boolean;
};
function MultilayerToggle({
multilayer,
onMultilayerChange,
disabled,
}: MultilayerToggleProps) {
return (
<IconButton
aria-label={

View File

@@ -1,9 +1,18 @@
import React from "react";
import { Flex } from "theme-ui";
import ColorControl from "./ColorControl";
function PointerToolSettings({ settings, onSettingChange }) {
import { PointerToolSettings } from "../../../types/Pointer";
type PointerToolSettingsProps = {
settings: PointerToolSettings;
onSettingChange: (change: Partial<PointerToolSettings>) => void;
};
function PointerToolSettings({
settings,
onSettingChange,
}: PointerToolSettingsProps) {
return (
<Flex sx={{ alignItems: "center" }}>
<ColorControl

View File

@@ -5,7 +5,12 @@ import RedoIcon from "../../../icons/RedoIcon";
import { isMacLike } from "../../../helpers/shared";
function RedoButton({ onClick, disabled }) {
type RedoButtonProps = {
onClick?: React.MouseEventHandler<HTMLButtonElement>;
disabled?: boolean;
};
function RedoButton({ onClick, disabled }: RedoButtonProps) {
return (
<IconButton
title={`Redo (${isMacLike ? "Cmd" : "Ctrl"} + Shift + Z)`}

View File

@@ -3,10 +3,24 @@ import { Box, Flex } from "theme-ui";
import RadioIconButton from "../../RadioIconButton";
export type Tool = {
id: string;
title: string;
isSelected: boolean;
icon: React.ReactNode;
disabled?: boolean;
};
type ToolSectionProps = {
collapse: boolean;
tools: Tool[];
onToolClick: (tool: Tool) => void;
};
// Section of map tools with the option to collapse into a vertical list
function ToolSection({ collapse, tools, onToolClick }) {
function ToolSection({ collapse, tools, onToolClick }: ToolSectionProps) {
const [showMore, setShowMore] = useState(false);
const [collapsedTool, setCollapsedTool] = useState();
const [collapsedTool, setCollapsedTool] = useState<Tool>();
useEffect(() => {
const selectedTool = tools.find((tool) => tool.isSelected);
@@ -20,7 +34,7 @@ function ToolSection({ collapse, tools, onToolClick }) {
}
}, [tools]);
function handleToolClick(tool) {
function handleToolClick(tool: Tool) {
if (collapse && tool.isSelected) {
setShowMore(!showMore);
} else if (collapse && !tool.isSelected) {
@@ -29,7 +43,7 @@ function ToolSection({ collapse, tools, onToolClick }) {
onToolClick(tool);
}
function renderTool(tool) {
function renderTool(tool: Tool) {
return (
<RadioIconButton
title={tool.title}
@@ -85,17 +99,21 @@ function ToolSection({ collapse, tools, onToolClick }) {
</Box>
);
} else {
return tools.map((tool) => (
<RadioIconButton
title={tool.title}
onClick={() => handleToolClick(tool)}
key={tool.id}
isSelected={tool.isSelected}
disabled={tool.disabled}
>
{tool.icon}
</RadioIconButton>
));
return (
<>
{tools.map((tool) => (
<RadioIconButton
title={tool.title}
onClick={() => handleToolClick(tool)}
key={tool.id}
isSelected={tool.isSelected}
disabled={tool.disabled}
>
{tool.icon}
</RadioIconButton>
))}
</>
);
}
}

View File

@@ -5,7 +5,12 @@ import UndoIcon from "../../../icons/UndoIcon";
import { isMacLike } from "../../../helpers/shared";
function UndoButton({ onClick, disabled }) {
type UndoButtonProps = {
onClick?: React.MouseEventHandler<HTMLButtonElement>;
disabled?: boolean;
};
function UndoButton({ onClick, disabled }: UndoButtonProps) {
return (
<IconButton
title={`Undo (${isMacLike ? "Cmd" : "Ctrl"} + Z)`}