From 1086bf58a10cf12e76c30cc77090e9faf1206b72 Mon Sep 17 00:00:00 2001 From: Eric NGUYEN Date: Tue, 4 Oct 2022 17:22:28 +0200 Subject: [PATCH] Add Undo/Redo to contextmenu + add separator between categories --- src/Components/Editor/Editor.tsx | 35 +++++++++++++++- src/Components/Menu/Menu.tsx | 68 ++++++++++++++++++++++++-------- 2 files changed, 84 insertions(+), 19 deletions(-) diff --git a/src/Components/Editor/Editor.tsx b/src/Components/Editor/Editor.tsx index 77d0277..1ae9d4c 100644 --- a/src/Components/Editor/Editor.tsx +++ b/src/Components/Editor/Editor.tsx @@ -27,8 +27,37 @@ function InitActions( configuration: IConfiguration, history: IHistoryState[], historyCurrentStep: number, - setNewHistory: (newHistory: IHistoryState[]) => void + setNewHistory: (newHistory: IHistoryState[]) => void, + setHistoryCurrentStep: Dispatch> ): void { + menuActions.set( + '', + [ + { + text: 'Undo', + title: 'Undo last action', + shortcut: 'Ctrl+Z', + action: () => { + if (historyCurrentStep <= 0) { + return; + } + setHistoryCurrentStep(historyCurrentStep - 1); + } + }, + { + text: 'Redo', + title: 'Redo last action', + shortcut: 'Ctrl+Y', + action: () => { + if (historyCurrentStep >= history.length - 1) { + return; + } + setHistoryCurrentStep(historyCurrentStep + 1); + } + } + ] + ); + menuActions.set( 'elements-sidebar-row', [{ @@ -46,6 +75,7 @@ function InitActions( } }] ); + menuActions.set( 'symbols-sidebar-row', [{ @@ -237,7 +267,8 @@ export function Editor(props: IEditorProps): JSX.Element { props.configuration, history, historyCurrentStep, - setNewHistory + setNewHistory, + setHistoryCurrentStep ); // Render diff --git a/src/Components/Menu/Menu.tsx b/src/Components/Menu/Menu.tsx index a5d2b06..841041e 100644 --- a/src/Components/Menu/Menu.tsx +++ b/src/Components/Menu/Menu.tsx @@ -91,23 +91,9 @@ export function Menu(props: IMenuProps): JSX.Element { if (target !== undefined) { let count = 0; - for (const className of target.classList) { - count++; - const actions = props.actions.get(className); - if (actions === undefined) { - continue; - } - - actions.forEach((action, index) => { - children.push( action.action(target)} />); - }); - }; + count = AddClassSpecificActions(target, count, props, children); + // Add universal actions + AddUniversalActions(props, children, count, target); } const visible = isOpen && children.length > 0 ? 'visible opacity-1' : 'invisible opacity-0'; @@ -127,3 +113,51 @@ export function Menu(props: IMenuProps): JSX.Element { ); } + +function AddClassSpecificActions( + target: HTMLElement, + count: number, + props: IMenuProps, + children: JSX.Element[] +): number { + for (const className of target.classList) { + count++; + const actions = props.actions.get(className); + + // Only select action where classname matches + if (actions === undefined) { + continue; + } + + actions.forEach((action, index) => { + children.push( action.action(target)} />); + }); + children.push(
); + }; + return count; +} + +function AddUniversalActions(props: IMenuProps, children: JSX.Element[], count: number, target: HTMLElement): number { + const actions = props.actions.get(''); + + if (actions !== undefined) { + count++; + actions.forEach((action, index) => { + children.push( action.action(target)} />); + }); + } + + return count; +}