diff --git a/src/pods/toolbar/components/export-button/export-button.tsx b/src/pods/toolbar/components/export-button/export-button.tsx index 7e5b7f61..c611e698 100644 --- a/src/pods/toolbar/components/export-button/export-button.tsx +++ b/src/pods/toolbar/components/export-button/export-button.tsx @@ -8,6 +8,7 @@ import { } from './export-button.utils'; import { ToolbarButton } from '../toolbar-button'; import Konva from 'konva'; +import { SHORTCUTS } from '../../shortcut/shortcut.const'; export const ExportButton = () => { const { stageRef, shapes, fileName, getActivePageName } = useCanvasContext(); @@ -65,6 +66,7 @@ export const ExportButton = () => { disabled={shapes.length === 0} icon={} label="Export" + shortcutOptions={SHORTCUTS.export} /> ); }; diff --git a/src/pods/toolbar/components/new-button/new-button.tsx b/src/pods/toolbar/components/new-button/new-button.tsx index 54501807..478c1eb4 100644 --- a/src/pods/toolbar/components/new-button/new-button.tsx +++ b/src/pods/toolbar/components/new-button/new-button.tsx @@ -2,6 +2,7 @@ import { NewIcon } from '@/common/components/icons/new-button.components'; import classes from '@/pods/toolbar/toolbar.pod.module.css'; import { useCanvasContext } from '@/core/providers'; import { ToolbarButton } from '../toolbar-button'; +import { SHORTCUTS } from '../../shortcut/shortcut.const'; export const NewButton = () => { const { createNewFullDocument: clearCanvas } = useCanvasContext(); @@ -16,6 +17,7 @@ export const NewButton = () => { className={classes.button} icon={} label="New" + shortcutOptions={SHORTCUTS.new} /> ); }; diff --git a/src/pods/toolbar/components/open-button/open-button.tsx b/src/pods/toolbar/components/open-button/open-button.tsx index 61fa3834..a980602c 100644 --- a/src/pods/toolbar/components/open-button/open-button.tsx +++ b/src/pods/toolbar/components/open-button/open-button.tsx @@ -2,6 +2,7 @@ import { OpenIcon } from '@/common/components/icons/open-icon.component'; import { ToolbarButton } from '../toolbar-button'; import classes from '@/pods/toolbar/toolbar.pod.module.css'; import { useLocalDisk } from '@/core/local-disk'; +import { SHORTCUTS } from '../../shortcut/shortcut.const'; export const OpenButton = () => { const { handleLoad } = useLocalDisk(); @@ -12,6 +13,7 @@ export const OpenButton = () => { className={classes.button} icon={} label="Open" + shortcutOptions={SHORTCUTS.open} /> ); }; diff --git a/src/pods/toolbar/components/save-button/save-button.tsx b/src/pods/toolbar/components/save-button/save-button.tsx index 61294a91..ede0787c 100644 --- a/src/pods/toolbar/components/save-button/save-button.tsx +++ b/src/pods/toolbar/components/save-button/save-button.tsx @@ -2,6 +2,7 @@ import { SaveIcon } from '@/common/components/icons/save-icon.component'; import classes from '@/pods/toolbar/toolbar.pod.module.css'; import { ToolbarButton } from '../toolbar-button'; import { useLocalDisk } from '@/core/local-disk'; +import { SHORTCUTS } from '../../shortcut/shortcut.const'; export const SaveButton: React.FC = () => { const { handleSave } = useLocalDisk(); @@ -12,6 +13,7 @@ export const SaveButton: React.FC = () => { className={classes.button} icon={} label="Save" + shortcutOptions={SHORTCUTS.save} /> ); }; diff --git a/src/pods/toolbar/components/settings-button/settings-button.tsx b/src/pods/toolbar/components/settings-button/settings-button.tsx index 81825a93..dca0de5c 100644 --- a/src/pods/toolbar/components/settings-button/settings-button.tsx +++ b/src/pods/toolbar/components/settings-button/settings-button.tsx @@ -3,6 +3,7 @@ import { useModalDialogContext } from '@/core/providers/model-dialog-providers/m import { SettingsPod } from '@/pods'; import { ToolbarButton } from '@/pods/toolbar/components/toolbar-button/toolbar-button'; import classes from '@/pods/toolbar/toolbar.pod.module.css'; +import { SHORTCUTS } from '../../shortcut/shortcut.const'; export const SettingsButton = () => { const { openModal } = useModalDialogContext(); @@ -17,6 +18,7 @@ export const SettingsButton = () => { className={classes.button} icon={} label="Settings" + shortcutOptions={SHORTCUTS.settings} /> ); }; diff --git a/src/pods/toolbar/components/toolbar-button/toolbar-button.tsx b/src/pods/toolbar/components/toolbar-button/toolbar-button.tsx index 0f984a10..130383f5 100644 --- a/src/pods/toolbar/components/toolbar-button/toolbar-button.tsx +++ b/src/pods/toolbar/components/toolbar-button/toolbar-button.tsx @@ -29,6 +29,7 @@ export const ToolbarButton: React.FC = props => { ...shortcutOptions, targetKey: shortcutOptions?.targetKey || [], callback: onClick, + isDeleteShortcut: shortcutOptions?.isDeleteShortcut, }); return ( diff --git a/src/pods/toolbar/components/zoom-in-button/zoom-in-button.tsx b/src/pods/toolbar/components/zoom-in-button/zoom-in-button.tsx index 62eb96d1..856d7b42 100644 --- a/src/pods/toolbar/components/zoom-in-button/zoom-in-button.tsx +++ b/src/pods/toolbar/components/zoom-in-button/zoom-in-button.tsx @@ -2,6 +2,7 @@ import classes from '@/pods/toolbar/toolbar.pod.module.css'; import { ZoomInIcon } from '@/common/components/icons/zoom-in.component'; import { useCanvasContext } from '@/core/providers'; import { ToolbarButton } from '../toolbar-button'; +import { SHORTCUTS } from '../../shortcut/shortcut.const'; export const ZoomInButton = () => { const { scale, setScale } = useCanvasContext(); @@ -19,6 +20,7 @@ export const ZoomInButton = () => { disabled={isDisabled} icon={} label="Zoom In" + shortcutOptions={SHORTCUTS.zoomin} /> ); }; diff --git a/src/pods/toolbar/components/zoom-out-component/zoom-out-button.tsx b/src/pods/toolbar/components/zoom-out-component/zoom-out-button.tsx index 7047806f..abd4cc8e 100644 --- a/src/pods/toolbar/components/zoom-out-component/zoom-out-button.tsx +++ b/src/pods/toolbar/components/zoom-out-component/zoom-out-button.tsx @@ -2,6 +2,7 @@ import { ZoomOutIcon } from '@/common/components/icons/zoom-out.component'; import classes from '@/pods/toolbar/toolbar.pod.module.css'; import { useCanvasContext } from '@/core/providers'; import { ToolbarButton } from '../toolbar-button'; +import { SHORTCUTS } from '../../shortcut/shortcut.const'; export const ZoomOutButton = () => { const { scale, setScale } = useCanvasContext(); @@ -19,6 +20,7 @@ export const ZoomOutButton = () => { disabled={isDisabled} icon={} label="Zoom Out" + shortcutOptions={SHORTCUTS.zoomout} /> ); }; diff --git a/src/pods/toolbar/shortcut/shortcut.const.ts b/src/pods/toolbar/shortcut/shortcut.const.ts index 0d901ad7..a01d410f 100644 --- a/src/pods/toolbar/shortcut/shortcut.const.ts +++ b/src/pods/toolbar/shortcut/shortcut.const.ts @@ -9,7 +9,8 @@ export const SHORTCUTS: Shortcut = { description: 'Delete', id: 'delete-button-shortcut', targetKey: ['backspace', 'delete'], - targetKeyLabel: 'Backspace', + targetKeyLabel: 'Backspace / Delete', + isDeleteShortcut: true, }, copy: { description: 'Copy', @@ -35,4 +36,46 @@ export const SHORTCUTS: Shortcut = { targetKey: ['Ctrl+y', 'Meta+y'], targetKeyLabel: 'Ctrl + Y', }, + new: { + description: 'New', + id: 'new-button-shortcut', + targetKey: ['Alt+n', 'Meta+n'], + targetKeyLabel: 'Alt + N', + }, + open: { + description: 'Open', + id: 'open-button-shortcut', + targetKey: ['Ctrl+o', 'Meta+o'], + targetKeyLabel: 'Ctrl + O', + }, + save: { + description: 'Save', + id: 'save-button-shortcut', + targetKey: ['Ctrl+s', 'Meta+s'], + targetKeyLabel: 'Ctrl + S', + }, + export: { + description: 'Export', + id: 'export-button-shortcut', + targetKey: ['Ctrl+e', 'Meta+e'], + targetKeyLabel: 'Ctrl + E', + }, + zoomin: { + description: 'Zoom in', + id: 'zoomin-button-shortcut', + targetKey: ['Alt++', 'Meta++'], + targetKeyLabel: 'Alt + "+"', + }, + zoomout: { + description: 'Zoom out', + id: 'zoomout-button-shortcut', + targetKey: ['Alt+-', 'Meta+-'], + targetKeyLabel: 'Alt + "-"', + }, + settings: { + description: 'Settings', + id: 'settings-button-shortcut', + targetKey: ['Ctrl+,', 'Meta+,'], + targetKeyLabel: 'Ctrl + ","', + }, }; diff --git a/src/pods/toolbar/shortcut/shortcut.hook.tsx b/src/pods/toolbar/shortcut/shortcut.hook.tsx index aa0698fa..b1ee7198 100644 --- a/src/pods/toolbar/shortcut/shortcut.hook.tsx +++ b/src/pods/toolbar/shortcut/shortcut.hook.tsx @@ -1,33 +1,46 @@ +import { useEffect } from 'react'; import { isMacOS } from '@/common/helpers/platform.helpers'; import { useCanvasContext } from '@/core/providers'; -import { useEffect } from 'react'; export interface ShortcutHookProps { targetKey: string[]; callback: () => void; + isDeleteShortcut?: boolean; } -export const useShortcut = ({ targetKey, callback }: ShortcutHookProps) => { +export const useShortcut = ({ + targetKey, + callback, + isDeleteShortcut, +}: ShortcutHookProps) => { const { isInlineEditing } = useCanvasContext(); - const handleKeyPress = (event: KeyboardEvent) => { - if (isInlineEditing) { - return; - } - // TODO: later on this needs discussio about shortcut keys - // Right now enable CTRL+C, CTRL+V for windows, linux and mac - //const isAltKeyPressed = event.getModifierState('Alt'); - //const isCtrlKeyPressed = event.getModifierState('Control'); - const isCtrlOrCmdPressed = event.ctrlKey || event.metaKey; - const ctrlKey = isMacOS() ? 'Meta' : 'Ctrl'; + const handleKeyPress = (event: KeyboardEvent) => { + if (isInlineEditing) return; const pressedKey = event.key.toLowerCase(); - if ( - targetKey.includes(pressedKey) || - (isCtrlOrCmdPressed && targetKey.includes(`${ctrlKey}+${pressedKey}`)) - ) { - event.preventDefault(); - callback(); + if (isDeleteShortcut) { + if (pressedKey === 'backspace' || pressedKey === 'delete') { + event.preventDefault(); + callback(); + } + } else { + const isCtrlOrCmdPressed = event.ctrlKey || event.metaKey; + const isAltPressed = event.altKey; + const ctrlKey = isMacOS() ? 'Meta' : 'Ctrl'; + + const pressedCombination = [ + isCtrlOrCmdPressed ? ctrlKey : '', + isAltPressed ? 'Alt' : '', + pressedKey, + ] + .filter(Boolean) + .join('+'); + + if (targetKey.includes(pressedCombination)) { + event.preventDefault(); + callback(); + } } }; @@ -38,5 +51,5 @@ export const useShortcut = ({ targetKey, callback }: ShortcutHookProps) => { return () => { window.removeEventListener('keydown', onKeyDown); }; - }, [targetKey, callback]); + }, [targetKey, callback, isDeleteShortcut]); }; diff --git a/src/pods/toolbar/shortcut/shortcut.model.ts b/src/pods/toolbar/shortcut/shortcut.model.ts index 13bff58b..0bb1c115 100644 --- a/src/pods/toolbar/shortcut/shortcut.model.ts +++ b/src/pods/toolbar/shortcut/shortcut.model.ts @@ -3,4 +3,5 @@ export interface ShortcutOptions { targetKey: string[]; targetKeyLabel: string; description: string; + isDeleteShortcut?: boolean; }