import React from "react"; import { ExcalidrawElement } from "../element/types"; import { AppClassProperties, AppState, ExcalidrawProps, BinaryFiles, } from "../types"; import { ToolButtonSize } from "../components/ToolButton"; /** if false, the action should be prevented */ export type ActionResult = | { elements?: readonly ExcalidrawElement[] | null; appState?: MarkOptional< AppState, "offsetTop" | "offsetLeft" | "width" | "height" > | null; files?: BinaryFiles | null; commitToHistory: boolean; syncHistory?: boolean; replaceFiles?: boolean; } | false; type ActionFn = ( elements: readonly ExcalidrawElement[], appState: Readonly, formData: any, app: AppClassProperties, ) => ActionResult | Promise; export type UpdaterFn = (res: ActionResult) => void; export type ActionFilterFn = (action: Action) => void; export type ActionName = | "copy" | "cut" | "paste" | "copyAsPng" | "copyAsSvg" | "sendBackward" | "bringForward" | "sendToBack" | "bringToFront" | "copyStyles" | "selectAll" | "pasteStyles" | "gridMode" | "zenMode" | "stats" | "changeStrokeColor" | "changeBackgroundColor" | "changeFillStyle" | "changeStrokeWidth" | "changeStrokeShape" | "changeSloppiness" | "changeStrokeStyle" | "changeArrowhead" | "changeOpacity" | "changeFontSize" | "toggleCanvasMenu" | "toggleEditMenu" | "undo" | "redo" | "finalize" | "changeProjectName" | "changeExportBackground" | "changeExportEmbedScene" | "changeExportScale" | "saveToActiveFile" | "saveFileToDisk" | "loadScene" | "duplicateSelection" | "deleteSelectedElements" | "changeViewBackgroundColor" | "clearCanvas" | "zoomIn" | "zoomOut" | "resetZoom" | "zoomToFit" | "zoomToSelection" | "changeFontFamily" | "changeTextAlign" | "changeVerticalAlign" | "toggleFullScreen" | "toggleShortcuts" | "group" | "ungroup" | "goToCollaborator" | "addToLibrary" | "changeSharpness" | "alignTop" | "alignBottom" | "alignLeft" | "alignRight" | "alignVerticallyCentered" | "alignHorizontallyCentered" | "distributeHorizontally" | "distributeVertically" | "flipHorizontal" | "flipVertical" | "viewMode" | "exportWithDarkMode" | "toggleTheme" | "increaseFontSize" | "decreaseFontSize" | "unbindText" | "hyperlink"; export type PanelComponentProps = { elements: readonly ExcalidrawElement[]; appState: AppState; updateData: (formData?: any) => void; appProps: ExcalidrawProps; data?: Partial<{ id: string; size: ToolButtonSize }>; }; export interface Action { name: ActionName; PanelComponent?: React.FC; perform: ActionFn; keyPriority?: number; keyTest?: ( event: React.KeyboardEvent | KeyboardEvent, appState: AppState, elements: readonly ExcalidrawElement[], ) => boolean; contextItemLabel?: | string | (( elements: readonly ExcalidrawElement[], appState: Readonly, ) => string); contextItemPredicate?: ( elements: readonly ExcalidrawElement[], appState: AppState, ) => boolean; checked?: (appState: Readonly) => boolean; trackEvent?: | boolean | ((action: Action, type: "ui" | "keyboard" | "api", value: any) => void); } export interface ActionsManagerInterface { actions: Record; registerAction: (action: Action) => void; handleKeyDown: (event: React.KeyboardEvent | KeyboardEvent) => boolean; renderAction: (name: ActionName) => React.ReactElement | null; executeAction: (action: Action) => void; }