Feature: Action System (#298)

* Add Action System

- Add keyboard test
- Add context menu label
- Add PanelComponent

* Show context menu items based on actions

* Add render action feature

- Replace bringForward etc buttons with action manager render functions

* Move all property changes and canvas into actions

* Remove unnecessary functions and add forgotten force update when elements array change

* Extract export operations into actions

* Add elements and app state as arguments to `keyTest` function

* Add key priorities

- Sort actions by key priority when handling key presses

* Extract copy/paste styles

* Add Context Menu Item order

- Sort context menu items based on menu item order parameter

* Remove unnecessary functions from App component
This commit is contained in:
Gasim Gasimzada
2020-01-12 02:22:03 +04:00
committed by Christopher Chedeau
parent c253c0b635
commit f465121f9b
15 changed files with 967 additions and 430 deletions

57
src/actions/types.ts Normal file
View File

@ -0,0 +1,57 @@
import React from "react";
import { ExcalidrawElement } from "../element/types";
import { AppState } from "../types";
export type ActionResult = {
elements?: ExcalidrawElement[];
appState?: AppState;
};
type ActionFn = (
elements: readonly ExcalidrawElement[],
appState: AppState,
formData: any
) => ActionResult;
export type UpdaterFn = (res: ActionResult) => void;
export interface Action {
name: string;
PanelComponent?: React.FC<{
elements: readonly ExcalidrawElement[];
appState: AppState;
updateData: (formData: any) => void;
}>;
perform: ActionFn;
keyPriority?: number;
keyTest?: (
event: KeyboardEvent,
elements?: readonly ExcalidrawElement[],
appState?: AppState
) => boolean;
contextItemLabel?: string;
contextMenuOrder?: number;
}
export interface ActionsManagerInterface {
actions: {
[keyProp: string]: Action;
};
registerAction: (action: Action) => void;
handleKeyDown: (
event: KeyboardEvent,
elements: readonly ExcalidrawElement[],
appState: AppState
) => ActionResult | {};
getContextMenuItems: (
elements: readonly ExcalidrawElement[],
appState: AppState,
updater: UpdaterFn
) => { label: string; action: () => void }[];
renderAction: (
name: string,
elements: ExcalidrawElement[],
appState: AppState,
updater: UpdaterFn
) => React.ReactElement | null;
}