diff --git a/src/actions/actionBoundText.tsx b/src/actions/actionBoundText.tsx
index 812e10b3..ed6efe97 100644
--- a/src/actions/actionBoundText.tsx
+++ b/src/actions/actionBoundText.tsx
@@ -26,7 +26,7 @@ export const actionUnbindText = register({
name: "unbindText",
contextItemLabel: "labels.unbindText",
trackEvent: { category: "element" },
- contextItemPredicate: (elements, appState) => {
+ predicate: (elements, appState) => {
const selectedElements = getSelectedElements(elements, appState);
return selectedElements.some((element) => hasBoundTextElement(element));
},
@@ -76,7 +76,7 @@ export const actionBindText = register({
name: "bindText",
contextItemLabel: "labels.bindText",
trackEvent: { category: "element" },
- contextItemPredicate: (elements, appState) => {
+ predicate: (elements, appState) => {
const selectedElements = getSelectedElements(elements, appState);
if (selectedElements.length === 2) {
diff --git a/src/actions/actionCanvas.tsx b/src/actions/actionCanvas.tsx
index acfee472..259b43e0 100644
--- a/src/actions/actionCanvas.tsx
+++ b/src/actions/actionCanvas.tsx
@@ -1,11 +1,5 @@
import { ColorPicker } from "../components/ColorPicker";
-import {
- eraser,
- MoonIcon,
- SunIcon,
- ZoomInIcon,
- ZoomOutIcon,
-} from "../components/icons";
+import { eraser, ZoomInIcon, ZoomOutIcon } from "../components/icons";
import { ToolButton } from "../components/ToolButton";
import { MIN_ZOOM, THEME, ZOOM_STEP } from "../constants";
import { getCommonBounds, getNonDeletedElements } from "../element";
@@ -21,14 +15,17 @@ import { register } from "./register";
import { Tooltip } from "../components/Tooltip";
import { newElementWith } from "../element/mutateElement";
import { getDefaultAppState, isEraserActive } from "../appState";
-import ClearCanvas from "../components/ClearCanvas";
import clsx from "clsx";
-import DropdownMenuItem from "../components/dropdownMenu/DropdownMenuItem";
-import { getShortcutFromShortcutName } from "./shortcuts";
export const actionChangeViewBackgroundColor = register({
name: "changeViewBackgroundColor",
trackEvent: false,
+ predicate: (elements, appState, props, app) => {
+ return (
+ !!app.props.UIOptions.canvasActions.changeViewBackgroundColor &&
+ !appState.viewModeEnabled
+ );
+ },
perform: (_, appState, value) => {
return {
appState: { ...appState, ...value },
@@ -36,6 +33,7 @@ export const actionChangeViewBackgroundColor = register({
};
},
PanelComponent: ({ elements, appState, updateData }) => {
+ // FIXME move me to src/components/mainMenu/DefaultItems.tsx
return (
{
+ return (
+ !!app.props.UIOptions.canvasActions.clearCanvas &&
+ !appState.viewModeEnabled
+ );
+ },
perform: (elements, appState, _, app) => {
app.imageCache.clear();
return {
@@ -84,8 +88,6 @@ export const actionClearCanvas = register({
commitToHistory: true,
};
},
-
- PanelComponent: ({ updateData }) => ,
});
export const actionZoomIn = register({
@@ -298,26 +300,10 @@ export const actionToggleTheme = register({
commitToHistory: false,
};
},
- PanelComponent: ({ appState, updateData }) => (
- {
- updateData(appState.theme === THEME.LIGHT ? THEME.DARK : THEME.LIGHT);
- }}
- icon={appState.theme === "dark" ? SunIcon : MoonIcon}
- dataTestId="toggle-dark-mode"
- shortcut={getShortcutFromShortcutName("toggleTheme")}
- ariaLabel={
- appState.theme === "dark"
- ? t("buttons.lightMode")
- : t("buttons.darkMode")
- }
- >
- {appState.theme === "dark"
- ? t("buttons.lightMode")
- : t("buttons.darkMode")}
-
- ),
keyTest: (event) => event.altKey && event.shiftKey && event.code === CODES.D,
+ predicate: (elements, appState, props, app) => {
+ return !!app.props.UIOptions.canvasActions.toggleTheme;
+ },
});
export const actionErase = register({
diff --git a/src/actions/actionClipboard.tsx b/src/actions/actionClipboard.tsx
index 5be391d3..661f65f3 100644
--- a/src/actions/actionClipboard.tsx
+++ b/src/actions/actionClipboard.tsx
@@ -24,7 +24,7 @@ export const actionCopy = register({
commitToHistory: false,
};
},
- contextItemPredicate: (elements, appState, appProps, app) => {
+ predicate: (elements, appState, appProps, app) => {
return app.device.isMobile && !!navigator.clipboard;
},
contextItemLabel: "labels.copy",
@@ -41,7 +41,7 @@ export const actionPaste = register({
commitToHistory: false,
};
},
- contextItemPredicate: (elements, appState, appProps, app) => {
+ predicate: (elements, appState, appProps, app) => {
return app.device.isMobile && !!navigator.clipboard;
},
contextItemLabel: "labels.paste",
@@ -56,7 +56,7 @@ export const actionCut = register({
actionCopy.perform(elements, appState, data, app);
return actionDeleteSelected.perform(elements, appState);
},
- contextItemPredicate: (elements, appState, appProps, app) => {
+ predicate: (elements, appState, appProps, app) => {
return app.device.isMobile && !!navigator.clipboard;
},
contextItemLabel: "labels.cut",
@@ -101,7 +101,7 @@ export const actionCopyAsSvg = register({
};
}
},
- contextItemPredicate: (elements) => {
+ predicate: (elements) => {
return probablySupportsClipboardWriteText && elements.length > 0;
},
contextItemLabel: "labels.copyAsSvg",
@@ -158,7 +158,7 @@ export const actionCopyAsPng = register({
};
}
},
- contextItemPredicate: (elements) => {
+ predicate: (elements) => {
return probablySupportsClipboardBlob && elements.length > 0;
},
contextItemLabel: "labels.copyAsPng",
@@ -188,7 +188,7 @@ export const copyText = register({
commitToHistory: false,
};
},
- contextItemPredicate: (elements, appState) => {
+ predicate: (elements, appState) => {
return (
probablySupportsClipboardWriteText &&
getSelectedElements(elements, appState, true).some(isTextElement)
diff --git a/src/actions/actionExport.tsx b/src/actions/actionExport.tsx
index e0f6c95f..f142eac8 100644
--- a/src/actions/actionExport.tsx
+++ b/src/actions/actionExport.tsx
@@ -1,7 +1,6 @@
-import { LoadIcon, questionCircle, saveAs } from "../components/icons";
+import { questionCircle, saveAs } from "../components/icons";
import { ProjectName } from "../components/ProjectName";
import { ToolButton } from "../components/ToolButton";
-import "../components/ToolIcon.scss";
import { Tooltip } from "../components/Tooltip";
import { DarkModeToggle } from "../components/DarkModeToggle";
import { loadFromJSON, saveAsJSON } from "../data";
@@ -15,12 +14,11 @@ import { getExportSize } from "../scene/export";
import { DEFAULT_EXPORT_PADDING, EXPORT_SCALES, THEME } from "../constants";
import { getSelectedElements, isSomeElementSelected } from "../scene";
import { getNonDeletedElements } from "../element";
-import { ActiveFile } from "../components/ActiveFile";
import { isImageFileHandle } from "../data/blob";
import { nativeFileSystemSupported } from "../data/filesystem";
import { Theme } from "../element/types";
-import DropdownMenuItem from "../components/dropdownMenu/DropdownMenuItem";
-import { getShortcutFromShortcutName } from "./shortcuts";
+
+import "../components/ToolIcon.scss";
export const actionChangeProjectName = register({
name: "changeProjectName",
@@ -133,6 +131,13 @@ export const actionChangeExportEmbedScene = register({
export const actionSaveToActiveFile = register({
name: "saveToActiveFile",
trackEvent: { category: "export" },
+ predicate: (elements, appState, props, app) => {
+ return (
+ !!app.props.UIOptions.canvasActions.saveToActiveFile &&
+ !!appState.fileHandle &&
+ !appState.viewModeEnabled
+ );
+ },
perform: async (elements, appState, value, app) => {
const fileHandleExists = !!appState.fileHandle;
@@ -169,12 +174,6 @@ export const actionSaveToActiveFile = register({
},
keyTest: (event) =>
event.key === KEYS.S && event[KEYS.CTRL_OR_CMD] && !event.shiftKey,
- PanelComponent: ({ updateData, appState }) => (
- updateData(null)}
- fileName={appState.fileHandle?.name}
- />
- ),
});
export const actionSaveFileToDisk = register({
@@ -220,6 +219,11 @@ export const actionSaveFileToDisk = register({
export const actionLoadScene = register({
name: "loadScene",
trackEvent: { category: "export" },
+ predicate: (elements, appState, props, app) => {
+ return (
+ !!app.props.UIOptions.canvasActions.loadScene && !appState.viewModeEnabled
+ );
+ },
perform: async (elements, appState, _, app) => {
try {
const {
@@ -247,19 +251,6 @@ export const actionLoadScene = register({
}
},
keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.key === KEYS.O,
- PanelComponent: ({ updateData }) => {
- return (
-
- {t("buttons.load")}
-
- );
- },
});
export const actionExportWithDarkMode = register({
diff --git a/src/actions/actionFlip.ts b/src/actions/actionFlip.ts
index 31aefdc0..ff6bfe4b 100644
--- a/src/actions/actionFlip.ts
+++ b/src/actions/actionFlip.ts
@@ -50,7 +50,7 @@ export const actionFlipHorizontal = register({
},
keyTest: (event) => event.shiftKey && event.code === "KeyH",
contextItemLabel: "labels.flipHorizontal",
- contextItemPredicate: (elements, appState) =>
+ predicate: (elements, appState) =>
enableActionFlipHorizontal(elements, appState),
});
@@ -67,7 +67,7 @@ export const actionFlipVertical = register({
keyTest: (event) =>
event.shiftKey && event.code === "KeyV" && !event[KEYS.CTRL_OR_CMD],
contextItemLabel: "labels.flipVertical",
- contextItemPredicate: (elements, appState) =>
+ predicate: (elements, appState) =>
enableActionFlipVertical(elements, appState),
});
diff --git a/src/actions/actionGroup.tsx b/src/actions/actionGroup.tsx
index 273888d7..1e6bcfbb 100644
--- a/src/actions/actionGroup.tsx
+++ b/src/actions/actionGroup.tsx
@@ -129,8 +129,7 @@ export const actionGroup = register({
};
},
contextItemLabel: "labels.group",
- contextItemPredicate: (elements, appState) =>
- enableActionGroup(elements, appState),
+ predicate: (elements, appState) => enableActionGroup(elements, appState),
keyTest: (event) =>
!event.shiftKey && event[KEYS.CTRL_OR_CMD] && event.key === KEYS.G,
PanelComponent: ({ elements, appState, updateData }) => (
@@ -193,8 +192,7 @@ export const actionUngroup = register({
event[KEYS.CTRL_OR_CMD] &&
event.key === KEYS.G.toUpperCase(),
contextItemLabel: "labels.ungroup",
- contextItemPredicate: (elements, appState) =>
- getSelectedGroupIds(appState).length > 0,
+ predicate: (elements, appState) => getSelectedGroupIds(appState).length > 0,
PanelComponent: ({ elements, appState, updateData }) => (
{
+ predicate: (elements, appState) => {
const selectedElements = getSelectedElements(elements, appState);
if (selectedElements.length === 1 && isLinearElement(selectedElements[0])) {
return true;
diff --git a/src/actions/actionMenu.tsx b/src/actions/actionMenu.tsx
index f0337128..27bd3b37 100644
--- a/src/actions/actionMenu.tsx
+++ b/src/actions/actionMenu.tsx
@@ -1,12 +1,10 @@
-import { HamburgerMenuIcon, HelpIcon, palette } from "../components/icons";
+import { HamburgerMenuIcon, palette } from "../components/icons";
import { ToolButton } from "../components/ToolButton";
import { t } from "../i18n";
import { showSelectedShapeActions, getNonDeletedElements } from "../element";
import { register } from "./register";
import { allowFullScreen, exitFullScreen, isFullScreen } from "../utils";
import { KEYS } from "../keys";
-import { HelpButton } from "../components/HelpButton";
-import DropdownMenuItem from "../components/dropdownMenu/DropdownMenuItem";
export const actionToggleCanvasMenu = register({
name: "toggleCanvasMenu",
@@ -88,19 +86,5 @@ export const actionShortcuts = register({
commitToHistory: false,
};
},
- PanelComponent: ({ updateData, isInHamburgerMenu }) =>
- isInHamburgerMenu ? (
-
- {t("helpDialog.title")}
-
- ) : (
-
- ),
keyTest: (event) => event.key === KEYS.QUESTION_MARK,
});
diff --git a/src/actions/actionToggleGridMode.tsx b/src/actions/actionToggleGridMode.tsx
index f8336a4b..8841cad5 100644
--- a/src/actions/actionToggleGridMode.tsx
+++ b/src/actions/actionToggleGridMode.tsx
@@ -20,7 +20,7 @@ export const actionToggleGridMode = register({
};
},
checked: (appState: AppState) => appState.gridSize !== null,
- contextItemPredicate: (element, appState, props) => {
+ predicate: (element, appState, props) => {
return typeof props.gridModeEnabled === "undefined";
},
contextItemLabel: "labels.showGrid",
diff --git a/src/actions/actionToggleViewMode.tsx b/src/actions/actionToggleViewMode.tsx
index b2f529c1..dc9db0c3 100644
--- a/src/actions/actionToggleViewMode.tsx
+++ b/src/actions/actionToggleViewMode.tsx
@@ -18,7 +18,7 @@ export const actionToggleViewMode = register({
};
},
checked: (appState) => appState.viewModeEnabled,
- contextItemPredicate: (elements, appState, appProps) => {
+ predicate: (elements, appState, appProps) => {
return typeof appProps.viewModeEnabled === "undefined";
},
contextItemLabel: "labels.viewMode",
diff --git a/src/actions/actionToggleZenMode.tsx b/src/actions/actionToggleZenMode.tsx
index 7578c02e..28956640 100644
--- a/src/actions/actionToggleZenMode.tsx
+++ b/src/actions/actionToggleZenMode.tsx
@@ -18,7 +18,7 @@ export const actionToggleZenMode = register({
};
},
checked: (appState) => appState.zenModeEnabled,
- contextItemPredicate: (elements, appState, appProps) => {
+ predicate: (elements, appState, appProps) => {
return typeof appProps.zenModeEnabled === "undefined";
},
contextItemLabel: "buttons.zenMode",
diff --git a/src/actions/manager.tsx b/src/actions/manager.tsx
index 6c87aa03..60648e41 100644
--- a/src/actions/manager.tsx
+++ b/src/actions/manager.tsx
@@ -131,11 +131,7 @@ export class ActionManager {
/**
* @param data additional data sent to the PanelComponent
*/
- renderAction = (
- name: ActionName,
- data?: PanelComponentProps["data"],
- isInHamburgerMenu = false,
- ) => {
+ renderAction = (name: ActionName, data?: PanelComponentProps["data"]) => {
const canvasActions = this.app.props.UIOptions.canvasActions;
if (
@@ -170,11 +166,20 @@ export class ActionManager {
updateData={updateData}
appProps={this.app.props}
data={data}
- isInHamburgerMenu={isInHamburgerMenu}
/>
);
}
return null;
};
+
+ isActionEnabled = (action: Action) => {
+ const elements = this.getElementsIncludingDeleted();
+ const appState = this.getAppState();
+
+ return (
+ !action.predicate ||
+ action.predicate(elements, appState, this.app.props, this.app)
+ );
+ };
}
diff --git a/src/actions/types.ts b/src/actions/types.ts
index 93e29cfc..4a7a4fe5 100644
--- a/src/actions/types.ts
+++ b/src/actions/types.ts
@@ -124,9 +124,7 @@ export type PanelComponentProps = {
export interface Action {
name: ActionName;
- PanelComponent?: React.FC<
- PanelComponentProps & { isInHamburgerMenu: boolean }
- >;
+ PanelComponent?: React.FC;
perform: ActionFn;
keyPriority?: number;
keyTest?: (
@@ -140,7 +138,7 @@ export interface Action {
elements: readonly ExcalidrawElement[],
appState: Readonly,
) => string);
- contextItemPredicate?: (
+ predicate?: (
elements: readonly ExcalidrawElement[],
appState: AppState,
appProps: ExcalidrawProps,
diff --git a/src/components/ActiveFile.tsx b/src/components/ActiveFile.tsx
deleted file mode 100644
index ac9ee89b..00000000
--- a/src/components/ActiveFile.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-// TODO barnabasmolnar/editor-redesign
-// this icon is not great
-import { getShortcutFromShortcutName } from "../actions/shortcuts";
-import { save } from "../components/icons";
-import { t } from "../i18n";
-
-import "./ActiveFile.scss";
-import DropdownMenuItem from "./dropdownMenu/DropdownMenuItem";
-
-type ActiveFileProps = {
- fileName?: string;
- onSave: () => void;
-};
-
-export const ActiveFile = ({ fileName, onSave }: ActiveFileProps) => (
- {`${t("buttons.save")}`}
-);
diff --git a/src/components/App.tsx b/src/components/App.tsx
index c0275dbf..9ce9dfc4 100644
--- a/src/components/App.tsx
+++ b/src/components/App.tsx
@@ -312,9 +312,9 @@ const ExcalidrawSetAppStateContext = React.createContext<
>(() => {});
ExcalidrawSetAppStateContext.displayName = "ExcalidrawSetAppStateContext";
-const ExcalidrawActionManagerContext = React.createContext<
- ActionManager | { renderAction: ActionManager["renderAction"] }
->({ renderAction: () => null });
+const ExcalidrawActionManagerContext = React.createContext(
+ null!,
+);
ExcalidrawActionManagerContext.displayName = "ExcalidrawActionManagerContext";
export const useExcalidrawElements = () =>
diff --git a/src/components/ClearCanvas.tsx b/src/components/ClearCanvas.tsx
deleted file mode 100644
index 354838aa..00000000
--- a/src/components/ClearCanvas.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { useState } from "react";
-import { t } from "../i18n";
-import { TrashIcon } from "./icons";
-
-import ConfirmDialog from "./ConfirmDialog";
-import DropdownMenuItem from "./dropdownMenu/DropdownMenuItem";
-
-const ClearCanvas = ({ onConfirm }: { onConfirm: () => void }) => {
- const [showDialog, setShowDialog] = useState(false);
- const toggleDialog = () => {
- setShowDialog(!showDialog);
- };
-
- return (
- <>
-
- {t("buttons.clearReset")}
-
-
- {showDialog && (
- {
- onConfirm();
- toggleDialog();
- }}
- onCancel={toggleDialog}
- title={t("clearCanvasDialog.title")}
- >
- {t("alerts.clearReset")}
-
- )}
- >
- );
-};
-
-export default ClearCanvas;
diff --git a/src/components/CollabButton.tsx b/src/components/CollabButton.tsx
index 08ad71c6..d63444a2 100644
--- a/src/components/CollabButton.tsx
+++ b/src/components/CollabButton.tsx
@@ -2,48 +2,30 @@ import { t } from "../i18n";
import { UsersIcon } from "./icons";
import "./CollabButton.scss";
-import DropdownMenuItem from "./dropdownMenu/DropdownMenuItem";
import clsx from "clsx";
const CollabButton = ({
isCollaborating,
collaboratorCount,
onClick,
- isInHamburgerMenu = true,
}: {
isCollaborating: boolean;
collaboratorCount: number;
onClick: () => void;
- isInHamburgerMenu?: boolean;
}) => {
return (
- <>
- {isInHamburgerMenu ? (
-
- {t("labels.liveCollaboration")}
-
- ) : (
-
- {UsersIcon}
- {collaboratorCount > 0 && (
-
- {collaboratorCount}
-
- )}
-
+
+ {UsersIcon}
+ {collaboratorCount > 0 && (
+ {collaboratorCount}
)}
- >
+
);
};
diff --git a/src/components/ContextMenu.tsx b/src/components/ContextMenu.tsx
index 2ec72e5e..1463f103 100644
--- a/src/components/ContextMenu.tsx
+++ b/src/components/ContextMenu.tsx
@@ -39,8 +39,8 @@ export const ContextMenu = React.memo(
if (
item &&
(item === CONTEXT_MENU_SEPARATOR ||
- !item.contextItemPredicate ||
- item.contextItemPredicate(
+ !item.predicate ||
+ item.predicate(
elements,
appState,
actionManager.app.props,
diff --git a/src/components/LayerUI.tsx b/src/components/LayerUI.tsx
index 57047a8d..e8a385d0 100644
--- a/src/components/LayerUI.tsx
+++ b/src/components/LayerUI.tsx
@@ -183,7 +183,9 @@ const LayerUI = ({
+ {/* FIXME we should to test for this inside the item itself */}
{UIOptions.canvasActions.export && }
+ {/* FIXME we should to test for this inside the item itself */}
{UIOptions.canvasActions.saveAsImage && (
)}
@@ -350,7 +352,6 @@ const LayerUI = ({
{onCollabButtonClick && (
- {actionManager.renderAction("toggleShortcuts")}
+ actionManager.executeAction(actionShortcuts)}
+ />
{
+ // FIXME Hack until we tie "t" to lang state
+ // eslint-disable-next-line
const appState = useExcalidrawAppState();
const actionManager = useExcalidrawActionManager();
- if (appState.viewModeEnabled) {
+
+ if (!actionManager.isActionEnabled(actionLoadScene)) {
return null;
}
- return actionManager.renderAction("loadScene");
+
+ return (
+ actionManager.executeAction(actionLoadScene)}
+ dataTestId="load-button"
+ shortcut={getShortcutFromShortcutName("loadScene")}
+ ariaLabel={t("buttons.load")}
+ >
+ {t("buttons.load")}
+
+ );
};
LoadScene.displayName = "LoadScene";
export const SaveToActiveFile = () => {
+ // FIXME Hack until we tie "t" to lang state
+ // eslint-disable-next-line
const appState = useExcalidrawAppState();
const actionManager = useExcalidrawActionManager();
- if (!appState.fileHandle) {
+
+ if (!actionManager.isActionEnabled(actionSaveToActiveFile)) {
return null;
}
- return actionManager.renderAction("saveToActiveFile");
+
+ return (
+ actionManager.executeAction(actionSaveToActiveFile)}
+ icon={save}
+ ariaLabel={`${t("buttons.save")}`}
+ >{`${t("buttons.save")}`}
+ );
};
SaveToActiveFile.displayName = "SaveToActiveFile";
export const SaveAsImage = () => {
const setAppState = useExcalidrawSetAppState();
- // Hack until we tie "t" to lang state
+ // FIXME Hack until we tie "t" to lang state
// eslint-disable-next-line
const appState = useExcalidrawAppState();
return (
@@ -51,32 +98,96 @@ export const SaveAsImage = () => {
SaveAsImage.displayName = "SaveAsImage";
export const Help = () => {
- // Hack until we tie "t" to lang state
+ // FIXME Hack until we tie "t" to lang state
// eslint-disable-next-line
const appState = useExcalidrawAppState();
const actionManager = useExcalidrawActionManager();
- return actionManager.renderAction("toggleShortcuts", undefined, true);
+
+ return (
+ actionManager.executeAction(actionShortcuts)}
+ shortcut="?"
+ ariaLabel={t("helpDialog.title")}
+ >
+ {t("helpDialog.title")}
+
+ );
};
Help.displayName = "Help";
export const ClearCanvas = () => {
+ // FIXME Hack until we tie "t" to lang state
+ // eslint-disable-next-line
const appState = useExcalidrawAppState();
const actionManager = useExcalidrawActionManager();
- if (appState.viewModeEnabled) {
+ const [showDialog, setShowDialog] = useState(false);
+ const toggleDialog = () => setShowDialog(!showDialog);
+
+ if (!actionManager.isActionEnabled(actionClearCanvas)) {
return null;
}
- return actionManager.renderAction("clearCanvas");
+
+ return (
+ <>
+
+ {t("buttons.clearReset")}
+
+
+ {/* FIXME this should live outside MainMenu so it stays open
+ if menu is closed */}
+ {showDialog && (
+ {
+ actionManager.executeAction(actionClearCanvas);
+ toggleDialog();
+ }}
+ onCancel={toggleDialog}
+ title={t("clearCanvasDialog.title")}
+ >
+ {t("alerts.clearReset")}
+
+ )}
+ >
+ );
};
ClearCanvas.displayName = "ClearCanvas";
export const ToggleTheme = () => {
- // Hack until we tie "t" to lang state
- // eslint-disable-next-line
const appState = useExcalidrawAppState();
const actionManager = useExcalidrawActionManager();
- return actionManager.renderAction("toggleTheme");
+
+ if (!actionManager.isActionEnabled(actionToggleTheme)) {
+ return null;
+ }
+
+ return (
+ {
+ return actionManager.executeAction(actionToggleTheme);
+ }}
+ icon={appState.theme === "dark" ? SunIcon : MoonIcon}
+ dataTestId="toggle-dark-mode"
+ shortcut={getShortcutFromShortcutName("toggleTheme")}
+ ariaLabel={
+ appState.theme === "dark"
+ ? t("buttons.lightMode")
+ : t("buttons.darkMode")
+ }
+ >
+ {appState.theme === "dark"
+ ? t("buttons.lightMode")
+ : t("buttons.darkMode")}
+
+ );
};
ToggleTheme.displayName = "ToggleTheme";
@@ -101,7 +212,7 @@ export const ChangeCanvasBackground = () => {
ChangeCanvasBackground.displayName = "ChangeCanvasBackground";
export const Export = () => {
- // Hack until we tie "t" to lang state
+ // FIXME Hack until we tie "t" to lang state
// eslint-disable-next-line
const appState = useExcalidrawAppState();
const setAppState = useExcalidrawSetAppState();
@@ -154,7 +265,7 @@ export const LiveCollaboration = ({
onSelect: () => void;
isCollaborating: boolean;
}) => {
- // Hack until we tie "t" to lang state
+ // FIXME Hack until we tie "t" to lang state
// eslint-disable-next-line
const appState = useExcalidrawAppState();
return (
diff --git a/src/element/Hyperlink.tsx b/src/element/Hyperlink.tsx
index a2540383..43cbf0da 100644
--- a/src/element/Hyperlink.tsx
+++ b/src/element/Hyperlink.tsx
@@ -267,7 +267,7 @@ export const actionLink = register({
keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.key === KEYS.K,
contextItemLabel: (elements, appState) =>
getContextMenuLabel(elements, appState),
- contextItemPredicate: (elements, appState) => {
+ predicate: (elements, appState) => {
const selectedElements = getSelectedElements(elements, appState);
return selectedElements.length === 1;
},
diff --git a/src/tests/__snapshots__/contextmenu.test.tsx.snap b/src/tests/__snapshots__/contextmenu.test.tsx.snap
index ed03cd99..8633e88b 100644
--- a/src/tests/__snapshots__/contextmenu.test.tsx.snap
+++ b/src/tests/__snapshots__/contextmenu.test.tsx.snap
@@ -13,30 +13,30 @@ Object {
"items": Array [
Object {
"contextItemLabel": "labels.cut",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "cut",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copy",
- "contextItemPredicate": [Function],
"keyTest": undefined,
"name": "copy",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.paste",
- "contextItemPredicate": [Function],
"keyTest": undefined,
"name": "paste",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -44,28 +44,28 @@ Object {
"separator",
Object {
"contextItemLabel": "labels.copyAsPng",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "copyAsPng",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyAsSvg",
- "contextItemPredicate": [Function],
"name": "copyAsSvg",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyText",
- "contextItemPredicate": [Function],
"name": "copyText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -93,28 +93,28 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": "labels.group",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "group",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.unbindText",
- "contextItemPredicate": [Function],
"name": "unbindText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.bindText",
- "contextItemPredicate": [Function],
"name": "bindText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -122,10 +122,10 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": "labels.ungroup",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "ungroup",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -185,20 +185,20 @@ Object {
"separator",
Object {
"contextItemLabel": "labels.flipHorizontal",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "flipHorizontal",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.flipVertical",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "flipVertical",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -206,9 +206,9 @@ Object {
"separator",
Object {
"contextItemLabel": [Function],
- "contextItemPredicate": [Function],
"name": "toggleLinearEditor",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -216,10 +216,10 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": [Function],
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "hyperlink",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"action": "click",
"category": "hyperlink",
@@ -4401,30 +4401,30 @@ Object {
"items": Array [
Object {
"contextItemLabel": "labels.cut",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "cut",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copy",
- "contextItemPredicate": [Function],
"keyTest": undefined,
"name": "copy",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.paste",
- "contextItemPredicate": [Function],
"keyTest": undefined,
"name": "paste",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -4432,28 +4432,28 @@ Object {
"separator",
Object {
"contextItemLabel": "labels.copyAsPng",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "copyAsPng",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyAsSvg",
- "contextItemPredicate": [Function],
"name": "copyAsSvg",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyText",
- "contextItemPredicate": [Function],
"name": "copyText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -4481,28 +4481,28 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": "labels.group",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "group",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.unbindText",
- "contextItemPredicate": [Function],
"name": "unbindText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.bindText",
- "contextItemPredicate": [Function],
"name": "bindText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -4510,10 +4510,10 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": "labels.ungroup",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "ungroup",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -4573,20 +4573,20 @@ Object {
"separator",
Object {
"contextItemLabel": "labels.flipHorizontal",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "flipHorizontal",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.flipVertical",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "flipVertical",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -4594,9 +4594,9 @@ Object {
"separator",
Object {
"contextItemLabel": [Function],
- "contextItemPredicate": [Function],
"name": "toggleLinearEditor",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -4604,10 +4604,10 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": [Function],
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "hyperlink",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"action": "click",
"category": "hyperlink",
@@ -4942,30 +4942,30 @@ Object {
"items": Array [
Object {
"contextItemLabel": "labels.cut",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "cut",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copy",
- "contextItemPredicate": [Function],
"keyTest": undefined,
"name": "copy",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.paste",
- "contextItemPredicate": [Function],
"keyTest": undefined,
"name": "paste",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -4973,28 +4973,28 @@ Object {
"separator",
Object {
"contextItemLabel": "labels.copyAsPng",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "copyAsPng",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyAsSvg",
- "contextItemPredicate": [Function],
"name": "copyAsSvg",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyText",
- "contextItemPredicate": [Function],
"name": "copyText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5022,28 +5022,28 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": "labels.group",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "group",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.unbindText",
- "contextItemPredicate": [Function],
"name": "unbindText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.bindText",
- "contextItemPredicate": [Function],
"name": "bindText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5051,10 +5051,10 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": "labels.ungroup",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "ungroup",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5114,20 +5114,20 @@ Object {
"separator",
Object {
"contextItemLabel": "labels.flipHorizontal",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "flipHorizontal",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.flipVertical",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "flipVertical",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5135,9 +5135,9 @@ Object {
"separator",
Object {
"contextItemLabel": [Function],
- "contextItemPredicate": [Function],
"name": "toggleLinearEditor",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5145,10 +5145,10 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": [Function],
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "hyperlink",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"action": "click",
"category": "hyperlink",
@@ -5568,10 +5568,10 @@ Object {
"items": Array [
Object {
"contextItemLabel": "labels.paste",
- "contextItemPredicate": [Function],
"keyTest": undefined,
"name": "paste",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5579,28 +5579,28 @@ Object {
"separator",
Object {
"contextItemLabel": "labels.copyAsPng",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "copyAsPng",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyAsSvg",
- "contextItemPredicate": [Function],
"name": "copyAsSvg",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyText",
- "contextItemPredicate": [Function],
"name": "copyText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5619,10 +5619,10 @@ Object {
Object {
"checked": [Function],
"contextItemLabel": "labels.showGrid",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "gridMode",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "canvas",
"predicate": [Function],
@@ -5632,10 +5632,10 @@ Object {
Object {
"checked": [Function],
"contextItemLabel": "buttons.zenMode",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "zenMode",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "canvas",
"predicate": [Function],
@@ -5645,10 +5645,10 @@ Object {
Object {
"checked": [Function],
"contextItemLabel": "labels.viewMode",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "viewMode",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "canvas",
"predicate": [Function],
@@ -5782,30 +5782,30 @@ Object {
"items": Array [
Object {
"contextItemLabel": "labels.cut",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "cut",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copy",
- "contextItemPredicate": [Function],
"keyTest": undefined,
"name": "copy",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.paste",
- "contextItemPredicate": [Function],
"keyTest": undefined,
"name": "paste",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5813,28 +5813,28 @@ Object {
"separator",
Object {
"contextItemLabel": "labels.copyAsPng",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "copyAsPng",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyAsSvg",
- "contextItemPredicate": [Function],
"name": "copyAsSvg",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyText",
- "contextItemPredicate": [Function],
"name": "copyText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5862,28 +5862,28 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": "labels.group",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "group",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.unbindText",
- "contextItemPredicate": [Function],
"name": "unbindText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.bindText",
- "contextItemPredicate": [Function],
"name": "bindText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5891,10 +5891,10 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": "labels.ungroup",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "ungroup",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5954,20 +5954,20 @@ Object {
"separator",
Object {
"contextItemLabel": "labels.flipHorizontal",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "flipHorizontal",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.flipVertical",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "flipVertical",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5975,9 +5975,9 @@ Object {
"separator",
Object {
"contextItemLabel": [Function],
- "contextItemPredicate": [Function],
"name": "toggleLinearEditor",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -5985,10 +5985,10 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": [Function],
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "hyperlink",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"action": "click",
"category": "hyperlink",
@@ -6119,30 +6119,30 @@ Object {
"items": Array [
Object {
"contextItemLabel": "labels.cut",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "cut",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copy",
- "contextItemPredicate": [Function],
"keyTest": undefined,
"name": "copy",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.paste",
- "contextItemPredicate": [Function],
"keyTest": undefined,
"name": "paste",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -6150,28 +6150,28 @@ Object {
"separator",
Object {
"contextItemLabel": "labels.copyAsPng",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "copyAsPng",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyAsSvg",
- "contextItemPredicate": [Function],
"name": "copyAsSvg",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.copyText",
- "contextItemPredicate": [Function],
"name": "copyText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -6199,28 +6199,28 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": "labels.group",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "group",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.unbindText",
- "contextItemPredicate": [Function],
"name": "unbindText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.bindText",
- "contextItemPredicate": [Function],
"name": "bindText",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -6228,10 +6228,10 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": "labels.ungroup",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "ungroup",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -6291,20 +6291,20 @@ Object {
"separator",
Object {
"contextItemLabel": "labels.flipHorizontal",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "flipHorizontal",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
},
Object {
"contextItemLabel": "labels.flipVertical",
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "flipVertical",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -6312,9 +6312,9 @@ Object {
"separator",
Object {
"contextItemLabel": [Function],
- "contextItemPredicate": [Function],
"name": "toggleLinearEditor",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"category": "element",
},
@@ -6322,10 +6322,10 @@ Object {
Object {
"PanelComponent": [Function],
"contextItemLabel": [Function],
- "contextItemPredicate": [Function],
"keyTest": [Function],
"name": "hyperlink",
"perform": [Function],
+ "predicate": [Function],
"trackEvent": Object {
"action": "click",
"category": "hyperlink",
diff --git a/src/tests/packages/__snapshots__/excalidraw.test.tsx.snap b/src/tests/packages/__snapshots__/excalidraw.test.tsx.snap
index a581fbf3..09402981 100644
--- a/src/tests/packages/__snapshots__/excalidraw.test.tsx.snap
+++ b/src/tests/packages/__snapshots__/excalidraw.test.tsx.snap
@@ -1,5 +1,114 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[` should render main menu with host menu items if passed from host 1`] = `
+
+`;
+
exports[` Test UIOptions prop Test canvasActions should render menu with default items when "UIOPtions" is "undefined" 1`] = `
Test UIOptions prop Test canvasActions should render menu
`;
-
-exports[` should render main menu with host menu items if passed from host 1`] = `
-
-`;
diff --git a/src/tests/packages/excalidraw.test.tsx b/src/tests/packages/excalidraw.test.tsx
index 99e928c5..a0d49593 100644
--- a/src/tests/packages/excalidraw.test.tsx
+++ b/src/tests/packages/excalidraw.test.tsx
@@ -3,6 +3,7 @@ import { Excalidraw, Footer, MainMenu } from "../../packages/excalidraw/index";
import { queryByText, queryByTestId } from "@testing-library/react";
import { GRID_SIZE, THEME } from "../../constants";
import { t } from "../../i18n";
+import { useMemo } from "react";
const { h } = window;
@@ -13,6 +14,7 @@ describe(" ", () => {
toggleMenu(document.querySelector(".excalidraw")!);
}
});
+
describe("Test zenModeEnabled prop", () => {
it('should show exit zen mode button when zen mode is set and zen mode option in context menu when zenModeEnabled is "undefined"', async () => {
const { container } = await render( );
@@ -121,34 +123,6 @@ describe(" ", () => {
});
});
- it("should render main menu with host menu items if passed from host", async () => {
- const { container } = await render(
-
-
- window.alert("Clicked")}>
- Click me
-
-
- Excalidraw blog
-
-
- window.alert("custom menu item")}
- >
- {" "}
- custom menu item
-
-
-
-
- ,
- );
- //open menu
- toggleMenu(container);
- expect(queryByTestId(container, "dropdown-menu")).toMatchSnapshot();
- });
-
describe("Test UIOptions prop", () => {
describe("Test canvasActions", () => {
it('should render menu with default items when "UIOPtions" is "undefined"', async () => {
@@ -306,7 +280,7 @@ describe(" ", () => {
//open menu
toggleMenu(container);
const darkModeToggle = queryByTestId(container, "toggle-dark-mode");
- expect(darkModeToggle).toBeFalsy();
+ expect(darkModeToggle).toBe(null);
});
});
@@ -336,6 +310,7 @@ describe(" ", () => {
expect(textInput?.nodeName).toBe("SPAN");
});
});
+
describe("Test autoFocus prop", () => {
it("should not focus when autoFocus is false", async () => {
const { container } = await render( );
@@ -353,4 +328,64 @@ describe(" ", () => {
).toBe(true);
});
});
+
+ describe(" ", () => {
+ it("should render main menu with host menu items if passed from host", async () => {
+ const { container } = await render(
+
+
+ window.alert("Clicked")}>
+ Click me
+
+
+ Excalidraw blog
+
+
+ window.alert("custom menu item")}
+ >
+ {" "}
+ custom menu item
+
+
+
+
+ ,
+ );
+ //open menu
+ toggleMenu(container);
+ expect(queryByTestId(container, "dropdown-menu")).toMatchSnapshot();
+ });
+
+ it("should update themeToggle text even if MainMenu memoized", async () => {
+ const CustomExcalidraw = () => {
+ const customMenu = useMemo(() => {
+ return (
+
+
+
+ );
+ }, []);
+
+ return {customMenu} ;
+ };
+
+ const { container } = await render( );
+ //open menu
+ toggleMenu(container);
+
+ expect(h.state.theme).toBe(THEME.LIGHT);
+
+ expect(
+ queryByTestId(container, "toggle-dark-mode")?.textContent,
+ ).toContain(t("buttons.darkMode"));
+
+ fireEvent.click(queryByTestId(container, "toggle-dark-mode")!);
+
+ expect(
+ queryByTestId(container, "toggle-dark-mode")?.textContent,
+ ).toContain(t("buttons.lightMode"));
+ });
+ });
});