excalidraw/packages/excalidraw/actions/types.ts

200 lines
4.5 KiB
TypeScript
Raw Normal View History

import React from "react";
import { ExcalidrawElement } from "../element/types";
import {
AppClassProperties,
AppState,
ExcalidrawProps,
BinaryFiles,
UIAppState,
} from "../types";
import { MarkOptional } from "../utility-types";
export type ActionSource =
| "ui"
| "keyboard"
| "contextMenu"
| "api"
| "commandPalette";
2022-03-28 12:46:40 +00:00
2020-07-07 11:53:44 +00:00
/** 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;
2020-07-07 11:53:44 +00:00
commitToHistory: boolean;
syncHistory?: boolean;
replaceFiles?: boolean;
2020-07-07 11:53:44 +00:00
}
| false;
type ActionFn = (
elements: readonly ExcalidrawElement[],
appState: Readonly<AppState>,
2020-01-24 10:04:54 +00:00
formData: any,
app: AppClassProperties,
2020-10-19 08:53:37 +00:00
) => ActionResult | Promise<ActionResult>;
2020-10-19 08:53:37 +00:00
export type UpdaterFn = (res: ActionResult) => void;
export type ActionFilterFn = (action: Action) => void;
export type ActionName =
| "copy"
| "cut"
| "paste"
| "copyAsPng"
| "copyAsSvg"
2022-04-05 21:11:00 +00:00
| "copyText"
| "sendBackward"
| "bringForward"
| "sendToBack"
| "bringToFront"
| "copyStyles"
| "selectAll"
| "pasteStyles"
| "gridMode"
| "zenMode"
| "objectsSnapMode"
| "stats"
| "changeStrokeColor"
| "changeBackgroundColor"
| "changeFillStyle"
| "changeStrokeWidth"
| "changeStrokeShape"
| "changeSloppiness"
2020-05-14 15:04:33 +00:00
| "changeStrokeStyle"
| "changeArrowhead"
| "changeOpacity"
| "changeFontSize"
| "toggleCanvasMenu"
| "toggleEditMenu"
| "undo"
| "redo"
| "finalize"
| "changeProjectName"
| "changeExportBackground"
| "changeExportEmbedScene"
| "changeExportScale"
| "saveToActiveFile"
| "saveFileToDisk"
| "loadScene"
| "duplicateSelection"
| "deleteSelectedElements"
| "changeViewBackgroundColor"
| "clearCanvas"
| "zoomIn"
| "zoomOut"
| "resetZoom"
| "zoomToFit"
| "zoomToFitSelection"
| "zoomToFitSelectionInViewport"
2020-04-05 21:47:13 +00:00
| "changeFontFamily"
| "changeTextAlign"
| "changeVerticalAlign"
2020-04-07 10:42:10 +00:00
| "toggleFullScreen"
| "toggleShortcuts"
| "group"
| "ungroup"
| "goToCollaborator"
| "addToLibrary"
| "changeRoundness"
| "alignTop"
| "alignBottom"
| "alignLeft"
| "alignRight"
| "alignVerticallyCentered"
2020-11-23 18:16:23 +00:00
| "alignHorizontallyCentered"
| "distributeHorizontally"
| "distributeVertically"
| "flipHorizontal"
| "flipVertical"
| "viewMode"
| "exportWithDarkMode"
| "toggleTheme"
| "increaseFontSize"
| "decreaseFontSize"
feat: Support hyperlinks 🔥 (#4620) * feat: Support hypelinks * dont show edit when link not present * auto submit on blur * Add link button in sidebar and do it react way * add key to hyperlink to remount when element selection changes * autofocus input * remove click handler and use pointerup/down to show /hide popup * add keydown and support enter/escape to submit * show extrrnal link icon when element has link * use icons and open link in new tab * dnt submit unless link updated * renamed ffiles * remove unnecessary changes * update snap * hide link popup once user starts interacting with element and show again only if clicked outside and clicked on element again * render link icon outside the element * fix hit testing * rewrite implementation to render hyperlinks outside elements and hide when element selected * remove * remove * tweak icon position and size * rotate link icon when element rotated, handle zooming and render exactly where ne resize handle is rendered * no need to create a new reference anymore for element when link added/updated * rotate the link image as well when rotating element * calculate hitbox of link icon and show pointer when hovering over link icon * open link when clicked on link icon * show tooltip when hovering over link icon * show link action only when single element selected * support other protocols * add shortcut cmd/ctrl+k to edit/update link * don't hide popup after submit * renderes decreased woo * Add context mneu label to add/edit link * fix tests * remove tick and show trash when in edit mode * show edit view when element contains link * fix snap * horizontally center the hyperlink container with respect to elemnt * fix padding * remove checkcircle * show popup on hover of selected element and dismiss when outside hitbox * check if element has link before setting popup state * move logic of auto hide to hyperlink and dnt hide when editing * hide popover when drag/resize/rotate * unmount during autohide * autohide after 500ms * fix regression * prevent cmd/ctrl+k when inside link editor * submit when input not updated * allow custom urls * fix centering of popup when zoomed * fix hitbox during zoom * fix * tweak link normalization * touch hyperlink tooltip DOM only if needed * consider 0 if no offsetY * reduce hitbox of link icon and make sure link icon doesn't show on top of higher z-index elements * show link tooltip only if element has higher z-index * dnt show hyperlink popup when selection changes from element with link to element with no link and also hide popover when element type changes from selection to something else * lint: EOL * fix link icon tooltip positioning * open the link only when last pointer down and last pointer up hit the link hitbox * render tooltip after 300ms delay * ensure link popup and editor input have same height * wip: cache the link icon canvas * fix the image quality after caching using device pixel ratio yay * some cleanup * remove unused selectedElementIds from renderConfig * Update src/renderer/renderElement.ts * fix `opener` vulnerability * tweak styling * decrease padding * open local links in the same tab * fix caching * code style refactor * remove unnecessary save & restore * show link shortcut in help dialog * submit on cmd/ctrl+k * merge state props * Add title for link * update editview if prop changes * tweak link action logic * make `Hyperlink` compo editor state fully controlled * dont show popup when context menu open * show in contextMenu only for single selection & change pos * set button `selected` state * set contextMenuOpen on pointerdown * set contextMenyOpen to false when action triggered * don't render link icons on export * fix tests * fix buttons wrap * move focus states to input top-level rule * fix elements sharing `Hyperlink` state * fix hitbox for link icon in case of rect * Early return if hitting link icon Co-authored-by: dwelle <luzar.david@gmail.com>
2022-02-03 15:04:59 +00:00
| "unbindText"
| "hyperlink"
| "bindText"
| "unlockAllElements"
| "toggleElementLock"
| "toggleLinearEditor"
| "toggleEraserTool"
| "toggleHandTool"
| "selectAllElementsInFrame"
| "removeAllElementsFromFrame"
| "updateFrameRendering"
| "setFrameAsActiveTool"
| "setEmbeddableAsActiveTool"
| "createContainerFromText"
| "wrapTextInContainer"
| "commandPalette";
export type PanelComponentProps = {
elements: readonly ExcalidrawElement[];
appState: AppState;
updateData: <T = any>(formData?: T) => void;
appProps: ExcalidrawProps;
data?: Record<string, any>;
app: AppClassProperties;
};
export interface Action {
name: ActionName;
label:
| string
| ((
elements: readonly ExcalidrawElement[],
appState: Readonly<AppState>,
app: AppClassProperties,
) => string);
keywords?: string[];
icon?:
| React.ReactNode
| ((
appState: UIAppState,
elements: readonly ExcalidrawElement[],
) => React.ReactNode);
PanelComponent?: React.FC<PanelComponentProps>;
perform: ActionFn;
keyPriority?: number;
keyTest?: (
event: React.KeyboardEvent | KeyboardEvent,
appState: AppState,
elements: readonly ExcalidrawElement[],
app: AppClassProperties,
) => boolean;
predicate?: (
elements: readonly ExcalidrawElement[],
appState: AppState,
appProps: ExcalidrawProps,
app: AppClassProperties,
) => boolean;
checked?: (appState: Readonly<AppState>) => boolean;
2022-03-28 12:46:40 +00:00
trackEvent:
| false
| {
category:
| "toolbar"
| "element"
| "canvas"
| "export"
| "history"
| "menu"
| "collab"
| "hyperlink";
action?: string;
predicate?: (
appState: Readonly<AppState>,
elements: readonly ExcalidrawElement[],
value: any,
) => boolean;
};
/** if set to `true`, allow action to be performed in viewMode.
* Defaults to `false` */
viewMode?: boolean;
}