diff --git a/src/actions/actionFinalize.tsx b/src/actions/actionFinalize.tsx
index 2baa25081875..8092b1918b7f 100644
--- a/src/actions/actionFinalize.tsx
+++ b/src/actions/actionFinalize.tsx
@@ -54,18 +54,13 @@ export const actionFinalize: Action = {
((event.key === KEYS.ESCAPE || event.key === KEYS.ENTER) &&
appState.multiElement !== null),
PanelComponent: ({ appState, updateData }) => (
-
- updateData(null)}
- />
-
+
),
};
diff --git a/src/actions/actionHistory.tsx b/src/actions/actionHistory.tsx
new file mode 100644
index 000000000000..9c05e79c222b
--- /dev/null
+++ b/src/actions/actionHistory.tsx
@@ -0,0 +1,73 @@
+import { Action } from "./types";
+import React from "react";
+import { undo, redo } from "../components/icons";
+import { ToolButton } from "../components/ToolButton";
+import { t } from "../i18n";
+import { SceneHistory } from "../history";
+import { ExcalidrawElement } from "../element/types";
+import { AppState } from "../types";
+import { KEYS } from "../keys";
+
+const writeData = (
+ appState: AppState,
+ data: { elements: ExcalidrawElement[]; appState: AppState } | null,
+) => {
+ if (data !== null) {
+ return {
+ elements: data.elements,
+ appState: { ...appState, ...data.appState },
+ };
+ }
+ return {};
+};
+
+const testUndo = (shift: boolean) => (
+ event: KeyboardEvent,
+ appState: AppState,
+) => event[KEYS.META] && /z/i.test(event.key) && event.shiftKey === shift;
+
+export const createUndoAction: (h: SceneHistory) => Action = history => ({
+ name: "undo",
+ perform: (_, appState) =>
+ [
+ appState.multiElement,
+ appState.resizingElement,
+ appState.editingElement,
+ appState.draggingElement,
+ ].every(x => x === null)
+ ? writeData(appState, history.undoOnce())
+ : {},
+ keyTest: testUndo(false),
+ PanelComponent: ({ updateData }) => (
+
+ ),
+ commitToHistory: () => false,
+});
+
+export const createRedoAction: (h: SceneHistory) => Action = history => ({
+ name: "redo",
+ perform: (_, appState) =>
+ [
+ appState.multiElement,
+ appState.resizingElement,
+ appState.editingElement,
+ appState.draggingElement,
+ ].every(x => x === null)
+ ? writeData(appState, history.redoOnce())
+ : {},
+ keyTest: testUndo(true),
+ PanelComponent: ({ updateData }) => (
+
+ ),
+ commitToHistory: () => false,
+});
diff --git a/src/actions/actionMenu.tsx b/src/actions/actionMenu.tsx
new file mode 100644
index 000000000000..153a6c965b0d
--- /dev/null
+++ b/src/actions/actionMenu.tsx
@@ -0,0 +1,45 @@
+import { Action } from "./types";
+import React from "react";
+import { menu, palette } from "../components/icons";
+import { ToolButton } from "../components/ToolButton";
+import { t } from "../i18n";
+import { showSelectedShapeActions } from "../element";
+
+export const actionToggleCanvasMenu: Action = {
+ name: "toggleCanvasMenu",
+ perform: (_, appState) => ({
+ appState: {
+ ...appState,
+ openMenu: appState.openMenu === "canvas" ? null : "canvas",
+ },
+ }),
+ PanelComponent: ({ appState, updateData }) => (
+
+ ),
+};
+
+export const actionToggleEditMenu: Action = {
+ name: "toggleEditMenu",
+ perform: (_elements, appState) => ({
+ appState: {
+ ...appState,
+ openMenu: appState.openMenu === "shape" ? null : "shape",
+ },
+ }),
+ PanelComponent: ({ elements, appState, updateData }) => (
+
+ ),
+};
diff --git a/src/actions/index.ts b/src/actions/index.ts
index 659c9d4b0930..e366adebe0dd 100644
--- a/src/actions/index.ts
+++ b/src/actions/index.ts
@@ -36,3 +36,4 @@ export {
} from "./actionExport";
export { actionCopyStyles, actionPasteStyles } from "./actionStyles";
+export { actionToggleCanvasMenu, actionToggleEditMenu } from "./actionMenu";
diff --git a/src/actions/manager.tsx b/src/actions/manager.tsx
index 9f4481580905..e9cb310e8454 100644
--- a/src/actions/manager.tsx
+++ b/src/actions/manager.tsx
@@ -83,7 +83,7 @@ export class ActionManager implements ActionsManagerInterface {
if (this.actions[name] && "PanelComponent" in this.actions[name]) {
const action = this.actions[name];
const PanelComponent = action.PanelComponent!;
- const updateData = (formState: any) => {
+ const updateData = (formState?: any) => {
const commitToHistory =
action.commitToHistory &&
action.commitToHistory(this.getAppState(), this.getElements());
diff --git a/src/actions/types.ts b/src/actions/types.ts
index 5e57d7ab695b..c1fe7251f416 100644
--- a/src/actions/types.ts
+++ b/src/actions/types.ts
@@ -21,7 +21,7 @@ export interface Action {
PanelComponent?: React.FC<{
elements: readonly ExcalidrawElement[];
appState: AppState;
- updateData: (formData: any) => void;
+ updateData: (formData?: any) => void;
}>;
perform: ActionFn;
keyPriority?: number;
diff --git a/src/appState.ts b/src/appState.ts
index e282d4fd8f6e..3ed68f559ae2 100644
--- a/src/appState.ts
+++ b/src/appState.ts
@@ -30,7 +30,7 @@ export function getDefaultAppState(): AppState {
isResizing: false,
selectionElement: null,
zoom: 1,
- openedMenu: null,
+ openMenu: null,
lastPointerDownWith: "mouse",
};
}
diff --git a/src/components/HintViewer.css b/src/components/HintViewer.css
index f5049b3655e7..fdd44793ed6d 100644
--- a/src/components/HintViewer.css
+++ b/src/components/HintViewer.css
@@ -1,5 +1,4 @@
.HintViewer {
- background-color: rgba(255, 255, 255, 0.88);
color: #868e96; /* OC: GRAY 6*/
font-size: 0.8rem;
left: 50%;
@@ -9,9 +8,16 @@
transform: translateX(calc(-50% - 16px)); /* 16px is half of lock icon */
}
+.HintViewer > span {
+ background-color: rgba(255, 255, 255, 0.88);
+ padding: 0.2rem 0.4rem;
+ border-radius: 3px;
+}
+
@media (max-width: 600px), (max-height: 500px) and (max-width: 1000px) {
.HintViewer {
position: static;
+ transform: none;
margin-top: 0.5rem;
text-align: center;
}
diff --git a/src/components/HintViewer.tsx b/src/components/HintViewer.tsx
index 85b8454da9f8..0111be10ceaa 100644
--- a/src/components/HintViewer.tsx
+++ b/src/components/HintViewer.tsx
@@ -52,5 +52,9 @@ export const HintViewer = ({
return null;
}
- return {hint}
;
+ return (
+
+ {hint}
+
+ );
};
diff --git a/src/components/ToolButton.tsx b/src/components/ToolButton.tsx
index 161af0824a15..e41184958853 100644
--- a/src/components/ToolButton.tsx
+++ b/src/components/ToolButton.tsx
@@ -16,6 +16,7 @@ type ToolButtonBaseProps = {
keyBindingLabel?: string;
showAriaLabel?: boolean;
visible?: boolean;
+ selected?: boolean;
};
type ToolButtonProps =
@@ -40,7 +41,9 @@ export const ToolButton = React.forwardRef(function(
if (props.type === "button") {
return (