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")} - - ) : ( - + ); }; 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[` should render main menu with host menu items if passed from host 1`] = ` -