Add type to controls and change colour types
This commit is contained in:
@@ -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)"}
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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 />
|
||||
@@ -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={
|
||||
@@ -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={
|
||||
@@ -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;
|
||||
@@ -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={
|
||||
@@ -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
|
||||
@@ -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)`}
|
||||
@@ -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>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)`}
|
||||
Reference in New Issue
Block a user