mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: Support customising canvas actions 🎉 (#3364)
* feat: Support hiding save, save as, clear & export * Remove canvasActions from state & minor changes * Rename prop to UIOptions & pass default value * Make requested changes * better type checking so that optional check not needed at every point * remove optional checks * Add few tests * Add describe block for canvasActions & use snapshot tests * Add support for hiding canvas background picker * Take snapshot of canvasActions instead of the whole app * Add support for hiding dark mode toggle * Update README.md * Rename table heading * Update changelog * Make requested changes * Update test name * tweaks Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
This commit is contained in:
parent
c54a099010
commit
233576628c
12 changed files with 637 additions and 15 deletions
|
@ -33,6 +33,7 @@ export const actionChangeViewBackgroundColor = register({
|
|||
type="canvasBackground"
|
||||
color={appState.viewBackgroundColor}
|
||||
onChange={(color) => updateData(color)}
|
||||
data-testid="canvas-background-picker"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -72,6 +73,7 @@ export const actionClearCanvas = register({
|
|||
updateData(null);
|
||||
}
|
||||
}}
|
||||
data-testid="clear-canvas-button"
|
||||
/>
|
||||
),
|
||||
});
|
||||
|
|
|
@ -136,6 +136,7 @@ export const actionSaveScene = register({
|
|||
aria-label={t("buttons.save")}
|
||||
showAriaLabel={useIsMobile()}
|
||||
onClick={() => updateData(null)}
|
||||
data-testid="save-button"
|
||||
/>
|
||||
),
|
||||
});
|
||||
|
@ -167,6 +168,7 @@ export const actionSaveAsScene = register({
|
|||
showAriaLabel={useIsMobile()}
|
||||
hidden={!supported}
|
||||
onClick={() => updateData(null)}
|
||||
data-testid="save-as-button"
|
||||
/>
|
||||
),
|
||||
});
|
||||
|
@ -204,6 +206,7 @@ export const actionLoadScene = register({
|
|||
aria-label={t("buttons.load")}
|
||||
showAriaLabel={useIsMobile()}
|
||||
onClick={updateData}
|
||||
data-testid="load-button"
|
||||
/>
|
||||
),
|
||||
});
|
||||
|
|
|
@ -7,12 +7,12 @@ import {
|
|||
ActionResult,
|
||||
} from "./types";
|
||||
import { ExcalidrawElement } from "../element/types";
|
||||
import { AppState, ExcalidrawProps } from "../types";
|
||||
import { AppProps, AppState } from "../types";
|
||||
import { MODES } from "../constants";
|
||||
|
||||
// This is the <App> component, but for now we don't care about anything but its
|
||||
// `canvas` state.
|
||||
type App = { canvas: HTMLCanvasElement | null; props: ExcalidrawProps };
|
||||
type App = { canvas: HTMLCanvasElement | null; props: AppProps };
|
||||
|
||||
export class ActionManager implements ActionsManagerInterface {
|
||||
actions = {} as ActionsManagerInterface["actions"];
|
||||
|
@ -52,10 +52,14 @@ export class ActionManager implements ActionsManagerInterface {
|
|||
}
|
||||
|
||||
handleKeyDown(event: KeyboardEvent) {
|
||||
const canvasActions = this.app.props.UIOptions.canvasActions;
|
||||
const data = Object.values(this.actions)
|
||||
.sort((a, b) => (b.keyPriority || 0) - (a.keyPriority || 0))
|
||||
.filter(
|
||||
(action) =>
|
||||
(action.name in canvasActions
|
||||
? canvasActions[action.name as keyof typeof canvasActions]
|
||||
: true) &&
|
||||
action.keyTest &&
|
||||
action.keyTest(
|
||||
event,
|
||||
|
@ -102,7 +106,15 @@ export class ActionManager implements ActionsManagerInterface {
|
|||
// like the user list. We can use this key to extract more
|
||||
// data from app state. This is an alternative to generic prop hell!
|
||||
renderAction = (name: ActionName, id?: string) => {
|
||||
if (this.actions[name] && "PanelComponent" in this.actions[name]) {
|
||||
const canvasActions = this.app.props.UIOptions.canvasActions;
|
||||
|
||||
if (
|
||||
this.actions[name] &&
|
||||
"PanelComponent" in this.actions[name] &&
|
||||
(name in canvasActions
|
||||
? canvasActions[name as keyof typeof canvasActions]
|
||||
: true)
|
||||
) {
|
||||
const action = this.actions[name];
|
||||
const PanelComponent = action.PanelComponent!;
|
||||
const updateData = (formState?: any) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue