Update send/bring shortcuts and show them properly per operating… (#784)

* Show proper shortcuts

* sort

* Add shortcuts to bring/send

* fix hotkeys matching greedily

* Space

* align zindex shortcuts with figma

* switch to event.code & change Darwin shortcuts

Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
Lipis 2020-03-09 15:06:35 +02:00 committed by GitHub
parent f9edb1b4ac
commit 9de3716324
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 65 additions and 29 deletions

View File

@ -6,6 +6,7 @@ import { ToolButton } from "../components/ToolButton";
import { t } from "../i18n"; import { t } from "../i18n";
import { getNormalizedZoom } from "../scene"; import { getNormalizedZoom } from "../scene";
import { KEYS } from "../keys"; import { KEYS } from "../keys";
import { getShortcutKey } from "../utils";
import useIsMobile from "../is-mobile"; import useIsMobile from "../is-mobile";
import { register } from "./register"; import { register } from "./register";
@ -83,7 +84,7 @@ export const actionZoomIn = register({
<ToolButton <ToolButton
type="button" type="button"
icon={zoomIn} icon={zoomIn}
title={t("buttons.zoomIn")} title={`${t("buttons.zoomIn")} ${getShortcutKey("CtrlOrCmd++")}`}
aria-label={t("buttons.zoomIn")} aria-label={t("buttons.zoomIn")}
onClick={() => { onClick={() => {
updateData(null); updateData(null);
@ -92,7 +93,7 @@ export const actionZoomIn = register({
), ),
keyTest: event => keyTest: event =>
(event.code === KEY_CODES.EQUAL || event.code === KEY_CODES.NUM_ADD) && (event.code === KEY_CODES.EQUAL || event.code === KEY_CODES.NUM_ADD) &&
(event[KEYS.META] || event.shiftKey), (event[KEYS.CTRL_OR_CMD] || event.shiftKey),
}); });
export const actionZoomOut = register({ export const actionZoomOut = register({
@ -109,7 +110,7 @@ export const actionZoomOut = register({
<ToolButton <ToolButton
type="button" type="button"
icon={zoomOut} icon={zoomOut}
title={t("buttons.zoomOut")} title={`${t("buttons.zoomOut")} ${getShortcutKey("CtrlOrCmd+-")}`}
aria-label={t("buttons.zoomOut")} aria-label={t("buttons.zoomOut")}
onClick={() => { onClick={() => {
updateData(null); updateData(null);
@ -118,7 +119,7 @@ export const actionZoomOut = register({
), ),
keyTest: event => keyTest: event =>
(event.code === KEY_CODES.MINUS || event.code === KEY_CODES.NUM_SUBTRACT) && (event.code === KEY_CODES.MINUS || event.code === KEY_CODES.NUM_SUBTRACT) &&
(event[KEYS.META] || event.shiftKey), (event[KEYS.CTRL_OR_CMD] || event.shiftKey),
}); });
export const actionResetZoom = register({ export const actionResetZoom = register({
@ -144,5 +145,5 @@ export const actionResetZoom = register({
), ),
keyTest: event => keyTest: event =>
(event.code === KEY_CODES.ZERO || event.code === KEY_CODES.NUM_ZERO) && (event.code === KEY_CODES.ZERO || event.code === KEY_CODES.NUM_ZERO) &&
(event[KEYS.META] || event.shiftKey), (event[KEYS.CTRL_OR_CMD] || event.shiftKey),
}); });

View File

@ -31,7 +31,7 @@ const writeData = (
}; };
const testUndo = (shift: boolean) => (event: KeyboardEvent) => const testUndo = (shift: boolean) => (event: KeyboardEvent) =>
event[KEYS.META] && /z/i.test(event.key) && event.shiftKey === shift; event[KEYS.CTRL_OR_CMD] && /z/i.test(event.key) && event.shiftKey === shift;
type ActionCreator = (history: SceneHistory) => Action; type ActionCreator = (history: SceneHistory) => Action;

View File

@ -14,5 +14,5 @@ export const actionSelectAll = register({
}; };
}, },
contextItemLabel: "labels.selectAll", contextItemLabel: "labels.selectAll",
keyTest: event => event[KEYS.META] && event.key === "a", keyTest: event => event[KEYS.CTRL_OR_CMD] && event.key === "a",
}); });

View File

@ -19,7 +19,8 @@ export const actionCopyStyles = register({
return {}; return {};
}, },
contextItemLabel: "labels.copyStyles", contextItemLabel: "labels.copyStyles",
keyTest: event => event[KEYS.META] && event.shiftKey && event.key === "C", keyTest: event =>
event[KEYS.CTRL_OR_CMD] && event.shiftKey && event.key === "C",
contextMenuOrder: 0, contextMenuOrder: 0,
}); });
@ -54,6 +55,7 @@ export const actionPasteStyles = register({
}, },
commitToHistory: () => true, commitToHistory: () => true,
contextItemLabel: "labels.pasteStyles", contextItemLabel: "labels.pasteStyles",
keyTest: event => event[KEYS.META] && event.shiftKey && event.key === "V", keyTest: event =>
event[KEYS.CTRL_OR_CMD] && event.shiftKey && event.key === "V",
contextMenuOrder: 1, contextMenuOrder: 1,
}); });

View File

@ -6,8 +6,9 @@ import {
moveAllRight, moveAllRight,
} from "../zindex"; } from "../zindex";
import { getSelectedIndices } from "../scene"; import { getSelectedIndices } from "../scene";
import { KEYS } from "../keys"; import { KEYS, isDarwin } from "../keys";
import { t } from "../i18n"; import { t } from "../i18n";
import { getShortcutKey } from "../utils";
import { register } from "./register"; import { register } from "./register";
import { import {
sendBackward, sendBackward,
@ -30,13 +31,14 @@ export const actionSendBackward = register({
contextItemLabel: "labels.sendBackward", contextItemLabel: "labels.sendBackward",
keyPriority: 40, keyPriority: 40,
commitToHistory: () => true, commitToHistory: () => true,
keyTest: event => event[KEYS.META] && event.altKey && event.key === "B", keyTest: event =>
event[KEYS.CTRL_OR_CMD] && !event.shiftKey && event.code === "BracketLeft",
PanelComponent: ({ updateData }) => ( PanelComponent: ({ updateData }) => (
<button <button
type="button" type="button"
className="zIndexButton" className="zIndexButton"
onClick={() => updateData(null)} onClick={() => updateData(null)}
title={t("labels.sendBackward")} title={`${t("labels.sendBackward")} ${getShortcutKey("CtrlOrCmd+[")}`}
> >
{sendBackward} {sendBackward}
</button> </button>
@ -57,13 +59,14 @@ export const actionBringForward = register({
contextItemLabel: "labels.bringForward", contextItemLabel: "labels.bringForward",
keyPriority: 40, keyPriority: 40,
commitToHistory: () => true, commitToHistory: () => true,
keyTest: event => event[KEYS.META] && event.altKey && event.key === "F", keyTest: event =>
event[KEYS.CTRL_OR_CMD] && !event.shiftKey && event.code === "BracketRight",
PanelComponent: ({ updateData }) => ( PanelComponent: ({ updateData }) => (
<button <button
type="button" type="button"
className="zIndexButton" className="zIndexButton"
onClick={() => updateData(null)} onClick={() => updateData(null)}
title={t("labels.bringForward")} title={`${t("labels.bringForward")} ${getShortcutKey("CtrlOrCmd+]")}`}
> >
{bringForward} {bringForward}
</button> </button>
@ -83,13 +86,23 @@ export const actionSendToBack = register({
}, },
contextItemLabel: "labels.sendToBack", contextItemLabel: "labels.sendToBack",
commitToHistory: () => true, commitToHistory: () => true,
keyTest: event => event[KEYS.META] && event.shiftKey && event.key === "B", keyTest: event => {
return isDarwin
? event[KEYS.CTRL_OR_CMD] && event.altKey && event.code === "BracketLeft"
: event[KEYS.CTRL_OR_CMD] &&
event.shiftKey &&
event.code === "BracketLeft";
},
PanelComponent: ({ updateData }) => ( PanelComponent: ({ updateData }) => (
<button <button
type="button" type="button"
className="zIndexButton" className="zIndexButton"
onClick={() => updateData(null)} onClick={() => updateData(null)}
title={t("labels.sendToBack")} title={`${t("labels.sendToBack")} ${
isDarwin
? getShortcutKey("CtrlOrCmd+Alt+[")
: getShortcutKey("CtrlOrCmd+Shift+[")
}`}
> >
{sendToBack} {sendToBack}
</button> </button>
@ -109,13 +122,23 @@ export const actionBringToFront = register({
}, },
commitToHistory: () => true, commitToHistory: () => true,
contextItemLabel: "labels.bringToFront", contextItemLabel: "labels.bringToFront",
keyTest: event => event[KEYS.META] && event.shiftKey && event.key === "F", keyTest: event => {
return isDarwin
? event[KEYS.CTRL_OR_CMD] && event.altKey && event.code === "BracketRight"
: event[KEYS.CTRL_OR_CMD] &&
event.shiftKey &&
event.code === "BracketRight";
},
PanelComponent: ({ updateData }) => ( PanelComponent: ({ updateData }) => (
<button <button
type="button" type="button"
className="zIndexButton" className="zIndexButton"
onClick={event => updateData(null)} onClick={event => updateData(null)}
title={t("labels.bringToFront")} title={`${t("labels.bringToFront")} ${
isDarwin
? getShortcutKey("CtrlOrCmd+Alt+]")
: getShortcutKey("CtrlOrCmd+Shift+]")
}`}
> >
{bringToFront} {bringToFront}
</button> </button>

View File

@ -5,7 +5,7 @@ import { hasBackground, hasStroke, hasText } from "../scene";
import { t } from "../i18n"; import { t } from "../i18n";
import { SHAPES } from "../shapes"; import { SHAPES } from "../shapes";
import { ToolButton } from "./ToolButton"; import { ToolButton } from "./ToolButton";
import { capitalizeString } from "../utils"; import { capitalizeString, getShortcutKey } from "../utils";
import { CURSOR_TYPE } from "../constants"; import { CURSOR_TYPE } from "../constants";
import Stack from "./Stack"; import Stack from "./Stack";
@ -78,6 +78,9 @@ export function ShapesSwitcher({
<> <>
{SHAPES.map(({ value, icon }, index) => { {SHAPES.map(({ value, icon }, index) => {
const label = t(`toolBar.${value}`); const label = t(`toolBar.${value}`);
const shortcut = getShortcutKey(
`${capitalizeString(value)[0]}, ${index + 1}`,
);
return ( return (
<ToolButton <ToolButton
key={value} key={value}
@ -85,9 +88,7 @@ export function ShapesSwitcher({
icon={icon} icon={icon}
checked={elementType === value} checked={elementType === value}
name="editor-current-shape" name="editor-current-shape"
title={`${capitalizeString(label)}${ title={`${capitalizeString(label)} ${shortcut}`}
capitalizeString(value)[0]
}, ${index + 1}`}
keyBindingLabel={`${index + 1}`} keyBindingLabel={`${index + 1}`}
aria-label={capitalizeString(label)} aria-label={capitalizeString(label)}
aria-keyshortcuts={`${label[0]} ${index + 1}`} aria-keyshortcuts={`${label[0]} ${index + 1}`}

View File

@ -1769,7 +1769,7 @@ export class App extends React.Component<any, AppState> {
event.preventDefault(); event.preventDefault();
const { deltaX, deltaY } = event; const { deltaX, deltaY } = event;
if (event.metaKey || event.ctrlKey) { if (event[KEYS.CTRL_OR_CMD]) {
const sign = Math.sign(deltaY); const sign = Math.sign(deltaY);
const MAX_STEP = 10; const MAX_STEP = 10;
let delta = Math.abs(deltaY); let delta = Math.abs(deltaY);

View File

@ -1,3 +1,5 @@
export const isDarwin = /Mac|iPod|iPhone|iPad/.test(window.navigator.platform);
export const KEYS = { export const KEYS = {
ARROW_LEFT: "ArrowLeft", ARROW_LEFT: "ArrowLeft",
ARROW_RIGHT: "ArrowRight", ARROW_RIGHT: "ArrowRight",
@ -7,14 +9,10 @@ export const KEYS = {
ESCAPE: "Escape", ESCAPE: "Escape",
DELETE: "Delete", DELETE: "Delete",
BACKSPACE: "Backspace", BACKSPACE: "Backspace",
get META() { CTRL_OR_CMD: isDarwin ? "metaKey" : "ctrlKey",
return /Mac|iPod|iPhone|iPad/.test(window.navigator.platform)
? "metaKey"
: "ctrlKey";
},
TAB: "Tab", TAB: "Tab",
SPACE: " ", SPACE: " ",
}; } as const;
export function isArrowKey(keyCode: string) { export function isArrowKey(keyCode: string) {
return ( return (

View File

@ -134,6 +134,17 @@ export function resetCursor() {
document.documentElement.style.cursor = ""; document.documentElement.style.cursor = "";
} }
export const getShortcutKey = (shortcut: string): string => {
const isMac = /Mac|iPod|iPhone|iPad/.test(window.navigator.platform);
if (isMac) {
return `${shortcut
.replace("CtrlOrCmd+", "⌘")
.replace("Alt+", "⌥")
.replace("Ctrl+", "⌃")
.replace("Shift+", "⇧")}`;
}
return `${shortcut.replace("CtrlOrCmd", "Ctrl")}`;
};
export function viewportCoordsToSceneCoords( export function viewportCoordsToSceneCoords(
{ clientX, clientY }: { clientX: number; clientY: number }, { clientX, clientY }: { clientX: number; clientY: number },
{ {