UNPKG

2.96 kBJavaScriptView Raw
1import global from 'global'; // The shortcut is our JSON-ifiable representation of a shortcut combination
2
3const {
4 navigator
5} = global;
6export const isMacLike = () => navigator && navigator.platform ? !!navigator.platform.match(/(Mac|iPhone|iPod|iPad)/i) : false;
7export const controlOrMetaSymbol = () => isMacLike() ? '⌘' : 'ctrl';
8export const controlOrMetaKey = () => isMacLike() ? 'meta' : 'control';
9export const optionOrAltSymbol = () => isMacLike() ? '⌥' : 'alt';
10export const isShortcutTaken = (arr1, arr2) => JSON.stringify(arr1) === JSON.stringify(arr2); // Map a keyboard event to a keyboard shortcut
11// NOTE: if we change the fields on the event that we need, we'll need to update the serialization in core/preview/start.js
12
13export const eventToShortcut = e => {
14 // Meta key only doesn't map to a shortcut
15 if (['Meta', 'Alt', 'Control', 'Shift'].includes(e.key)) {
16 return null;
17 }
18
19 const keys = [];
20
21 if (e.altKey) {
22 keys.push('alt');
23 }
24
25 if (e.ctrlKey) {
26 keys.push('control');
27 }
28
29 if (e.metaKey) {
30 keys.push('meta');
31 }
32
33 if (e.shiftKey) {
34 keys.push('shift');
35 }
36
37 if (e.key && e.key.length === 1 && e.key !== ' ') {
38 keys.push(e.key.toUpperCase());
39 }
40
41 if (e.key === ' ') {
42 keys.push('space');
43 }
44
45 if (e.key === 'Escape') {
46 keys.push('escape');
47 }
48
49 if (e.key === 'ArrowRight') {
50 keys.push('ArrowRight');
51 }
52
53 if (e.key === 'ArrowDown') {
54 keys.push('ArrowDown');
55 }
56
57 if (e.key === 'ArrowUp') {
58 keys.push('ArrowUp');
59 }
60
61 if (e.key === 'ArrowLeft') {
62 keys.push('ArrowLeft');
63 }
64
65 return keys.length > 0 ? keys : null;
66};
67export const shortcutMatchesShortcut = (inputShortcut, shortcut) => {
68 if (!inputShortcut || !shortcut) return false;
69 if (inputShortcut.join('') === 'shift/') inputShortcut.shift(); // shift is optional for `/`
70
71 if (inputShortcut.length !== shortcut.length) return false;
72 return !inputShortcut.find((key, i) => key !== shortcut[i]);
73}; // Should this keyboard event trigger this keyboard shortcut?
74
75export const eventMatchesShortcut = (e, shortcut) => {
76 return shortcutMatchesShortcut(eventToShortcut(e), shortcut);
77};
78export const keyToSymbol = key => {
79 if (key === 'alt') {
80 return optionOrAltSymbol();
81 }
82
83 if (key === 'control') {
84 return '⌃';
85 }
86
87 if (key === 'meta') {
88 return '⌘';
89 }
90
91 if (key === 'shift') {
92 return '⇧​';
93 }
94
95 if (key === 'Enter' || key === 'Backspace' || key === 'Esc') {
96 return '';
97 }
98
99 if (key === 'escape') {
100 return '';
101 }
102
103 if (key === ' ') {
104 return 'SPACE';
105 }
106
107 if (key === 'ArrowUp') {
108 return '↑';
109 }
110
111 if (key === 'ArrowDown') {
112 return '↓';
113 }
114
115 if (key === 'ArrowLeft') {
116 return '←';
117 }
118
119 if (key === 'ArrowRight') {
120 return '→';
121 }
122
123 return key.toUpperCase();
124}; // Display the shortcut as a human readable string
125
126export const shortcutToHumanString = shortcut => {
127 return shortcut.map(keyToSymbol).join(' ');
128};
\No newline at end of file