mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
refactor: separate elements logic into a standalone package (#9285)
Some checks failed
Auto release excalidraw next / Auto-release-excalidraw-next (push) Failing after 2m36s
Build Docker image / build-docker (push) Failing after 6s
Cancel previous runs / cancel (push) Failing after 1s
Publish Docker / publish-docker (push) Failing after 31s
New Sentry production release / sentry (push) Failing after 2m3s
Some checks failed
Auto release excalidraw next / Auto-release-excalidraw-next (push) Failing after 2m36s
Build Docker image / build-docker (push) Failing after 6s
Cancel previous runs / cancel (push) Failing after 1s
Publish Docker / publish-docker (push) Failing after 31s
New Sentry production release / sentry (push) Failing after 2m3s
This commit is contained in:
parent
a18f059188
commit
432a46ef9e
372 changed files with 3466 additions and 2466 deletions
151
packages/common/src/keys.ts
Normal file
151
packages/common/src/keys.ts
Normal file
|
@ -0,0 +1,151 @@
|
|||
import { isDarwin } from "./constants";
|
||||
|
||||
import type { ValueOf } from "./utility-types";
|
||||
|
||||
export const CODES = {
|
||||
EQUAL: "Equal",
|
||||
MINUS: "Minus",
|
||||
NUM_ADD: "NumpadAdd",
|
||||
NUM_SUBTRACT: "NumpadSubtract",
|
||||
NUM_ZERO: "Numpad0",
|
||||
BRACKET_RIGHT: "BracketRight",
|
||||
BRACKET_LEFT: "BracketLeft",
|
||||
ONE: "Digit1",
|
||||
TWO: "Digit2",
|
||||
THREE: "Digit3",
|
||||
NINE: "Digit9",
|
||||
QUOTE: "Quote",
|
||||
ZERO: "Digit0",
|
||||
SLASH: "Slash",
|
||||
C: "KeyC",
|
||||
D: "KeyD",
|
||||
H: "KeyH",
|
||||
V: "KeyV",
|
||||
Z: "KeyZ",
|
||||
Y: "KeyY",
|
||||
R: "KeyR",
|
||||
S: "KeyS",
|
||||
} as const;
|
||||
|
||||
export const KEYS = {
|
||||
ARROW_DOWN: "ArrowDown",
|
||||
ARROW_LEFT: "ArrowLeft",
|
||||
ARROW_RIGHT: "ArrowRight",
|
||||
ARROW_UP: "ArrowUp",
|
||||
PAGE_UP: "PageUp",
|
||||
PAGE_DOWN: "PageDown",
|
||||
BACKSPACE: "Backspace",
|
||||
ALT: "Alt",
|
||||
CTRL_OR_CMD: isDarwin ? "metaKey" : "ctrlKey",
|
||||
DELETE: "Delete",
|
||||
ENTER: "Enter",
|
||||
ESCAPE: "Escape",
|
||||
QUESTION_MARK: "?",
|
||||
SPACE: " ",
|
||||
TAB: "Tab",
|
||||
CHEVRON_LEFT: "<",
|
||||
CHEVRON_RIGHT: ">",
|
||||
PERIOD: ".",
|
||||
COMMA: ",",
|
||||
SUBTRACT: "-",
|
||||
SLASH: "/",
|
||||
|
||||
A: "a",
|
||||
C: "c",
|
||||
D: "d",
|
||||
E: "e",
|
||||
F: "f",
|
||||
G: "g",
|
||||
H: "h",
|
||||
I: "i",
|
||||
L: "l",
|
||||
O: "o",
|
||||
P: "p",
|
||||
Q: "q",
|
||||
R: "r",
|
||||
S: "s",
|
||||
T: "t",
|
||||
V: "v",
|
||||
X: "x",
|
||||
Y: "y",
|
||||
Z: "z",
|
||||
K: "k",
|
||||
W: "w",
|
||||
|
||||
0: "0",
|
||||
1: "1",
|
||||
2: "2",
|
||||
3: "3",
|
||||
4: "4",
|
||||
5: "5",
|
||||
6: "6",
|
||||
7: "7",
|
||||
8: "8",
|
||||
9: "9",
|
||||
} as const;
|
||||
|
||||
export type Key = keyof typeof KEYS;
|
||||
|
||||
// defines key code mapping for matching codes as fallback to respective keys on non-latin keyboard layouts
|
||||
export const KeyCodeMap = new Map<ValueOf<typeof KEYS>, ValueOf<typeof CODES>>([
|
||||
[KEYS.Z, CODES.Z],
|
||||
[KEYS.Y, CODES.Y],
|
||||
]);
|
||||
|
||||
export const isLatinChar = (key: string) => /^[a-z]$/.test(key.toLowerCase());
|
||||
|
||||
/**
|
||||
* Used to match key events for any keyboard layout, especially on Windows and Linux,
|
||||
* where non-latin character with modified (CMD) is not substituted with latin-based alternative.
|
||||
*
|
||||
* Uses `event.key` when it's latin, otherwise fallbacks to `event.code` (if mapping exists).
|
||||
*
|
||||
* Example of pressing "z" on different layouts, with the chosen key or code highlighted in []:
|
||||
*
|
||||
* Layout | Code | Key | Comment
|
||||
* --------------------- | ----- | --- | -------
|
||||
* U.S. | KeyZ | [z] |
|
||||
* Czech | KeyY | [z] |
|
||||
* Turkish | KeyN | [z] |
|
||||
* French | KeyW | [z] |
|
||||
* Macedonian | [KeyZ] | з | z with cmd; з is Cyrillic equivalent of z
|
||||
* Russian | [KeyZ] | я | z with cmd
|
||||
* Serbian | [KeyZ] | ѕ | z with cmd
|
||||
* Greek | [KeyZ] | ζ | z with cmd; also ζ is Greek equivalent of z
|
||||
* Hebrew | [KeyZ] | ז | z with cmd; also ז is Hebrew equivalent of z
|
||||
* Pinyin - Simplified | KeyZ | [z] | due to IME
|
||||
* Cangije - Traditional | [KeyZ] | 重 | z with cmd
|
||||
* Japanese | [KeyZ] | つ | z with cmd
|
||||
* 2-Set Korean | [KeyZ] | ㅋ | z with cmd
|
||||
*
|
||||
* More details in https://github.com/excalidraw/excalidraw/pull/5944
|
||||
*/
|
||||
export const matchKey = (
|
||||
event: KeyboardEvent | React.KeyboardEvent<Element>,
|
||||
key: ValueOf<typeof KEYS>,
|
||||
): boolean => {
|
||||
// for latin layouts use key
|
||||
if (key === event.key.toLowerCase()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// non-latin layouts fallback to code
|
||||
const code = KeyCodeMap.get(key);
|
||||
return Boolean(code && !isLatinChar(event.key) && event.code === code);
|
||||
};
|
||||
|
||||
export const isArrowKey = (key: string) =>
|
||||
key === KEYS.ARROW_LEFT ||
|
||||
key === KEYS.ARROW_RIGHT ||
|
||||
key === KEYS.ARROW_DOWN ||
|
||||
key === KEYS.ARROW_UP;
|
||||
|
||||
export const shouldResizeFromCenter = (event: MouseEvent | KeyboardEvent) =>
|
||||
event.altKey;
|
||||
|
||||
export const shouldMaintainAspectRatio = (event: MouseEvent | KeyboardEvent) =>
|
||||
event.shiftKey;
|
||||
|
||||
export const shouldRotateWithDiscreteAngle = (
|
||||
event: MouseEvent | KeyboardEvent | React.PointerEvent<HTMLCanvasElement>,
|
||||
) => event.shiftKey;
|
Loading…
Add table
Add a link
Reference in a new issue