Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix Windows keyboard shorcuts #20

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Live at: [designer.grommet.io](https://designer.grommet.io)

### Command shortcuts

* **command-e** or **windows-E**: toggles preview vs. edit modes
* **commend-delete**: deletes the currently selected component and all of its children
* **command-e** or **control-e**: toggles preview vs. edit modes
* **command-delete** or **control-delete**: deletes the currently selected component and all of its children

### Linking

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"grommet": "https://github.com/grommet/grommet/tarball/stable",
"grommet": "^2.7.1",
"grommet-icons": "^4.2.0",
"grommet-theme-aruba": "^0.1.2",
"grommet-theme-dxc": "^0.1.2",
"grommet-theme-hp": "^0.1.2",
"grommet-theme-hpe": "^0.4.2",
"keycode": "^2.2.0",
"lz-string": "^1.4.4",
"react": "^16.8.6",
"react-dom": "^16.8.6",
Expand Down
9 changes: 4 additions & 5 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
bucketUrl, bucketKey, getParent, resetState, upgradeDesign, bare, rich,
} from './designs';
import ScreenDetails from './ScreenDetails';
import isHotkey from './isHotkey';

const themes = { aruba, dark, dxc, grommet, hp, hpe };

Expand Down Expand Up @@ -131,11 +132,9 @@ class App extends Component {

onKeyDown = (event) => {
const { preview } = this.state;
if (event.metaKey) {
if (event.keyCode === 69) { // e
event.preventDefault();
this.setState({ preview: !preview });
}
if (isHotkey(event, "Meta+e", false)) {
event.preventDefault();
this.setState({ preview: !preview });
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/Properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Property from './Property';
import {
duplicateComponent, getDisplayName, getLinkOptions, getParent,
} from './designs';
import isHotkey from './isHotkey';

export default class Properties extends Component {

Expand Down Expand Up @@ -76,11 +77,9 @@ export default class Properties extends Component {

onKeyDown = (event) => {
const { onDelete } = this.props;
if (event.metaKey) {
if (event.keyCode === 8) { // delete
event.preventDefault();
onDelete();
}
if (isHotkey(event, "Meta+Delete")) {
event.preventDefault();
onDelete();
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/ScreenDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
} from 'grommet';
import { Duplicate, Trash } from 'grommet-icons';
import { addScreen } from './designs';
import isHotkey from './isHotkey';

export default class ScreenDetails extends Component {

Expand Down Expand Up @@ -60,11 +61,9 @@ export default class ScreenDetails extends Component {

onKeyDown = (event) => {
const { onDelete } = this.props;
if (event.metaKey) {
if (event.keyCode === 8) { // delete
event.preventDefault();
onDelete();
}
if (isHotkey(event, "Meta+Delete")) {
event.preventDefault();
onDelete();
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/Tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Add, Configure, FormDown, FormUp, Save, Share, Trash } from 'grommet-ic
import { types, Adder } from './Types';
import DesignSettings from './DesignSettings';
import { addScreen, getParent, getScreen } from './designs';
import isHotkey from './isHotkey';

const treeName = component =>
(component.name || component.text
Expand Down Expand Up @@ -105,11 +106,9 @@ class Tree extends Component {
}

onKeyDown = (event) => {
if (event.metaKey) {
// if (event.keyCode === 65) { // a
if (isHotkey(event, "Meta+a")) {
// event.preventDefault();
// this.setState({ adding: true });
// }
}
}

Expand Down
85 changes: 85 additions & 0 deletions src/isHotkey.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import Keycode from 'keycode';



/**
* Checks modifier key name and converts `Meta` to `Meta` on Mac and `Control` elsewhere.
*
* Logs an error and returns an empty string if the modifier key is unknown.
*
* `Meta`, `Control`, `Alt`, `Shift` are supported.
*
* @param {string} keyName - key name like `Shift` or `Meta`
* @param {string} [platform] - (optional) defaults to `navigator.platform`
* @return {string} Native modifier key name that can be used for event filtering
*/
export function translateModifierKey(keyName, platform = navigator.platform) {
const supportedModifierKeys = [`Meta`, `Control`, `Alt`, `Shift`];
if (!supportedModifierKeys.includes(keyName)) {
console.error(`Unsupported modifier key: ${keyName}`);
return ''
}
if (keyName === "Meta") {
return /Mac|iPod|iPhone|iPad/.test(platform) ? 'Meta' : 'Control';
}
return keyName;
}
/**
* Extracts an list of native key names from a shortcut.
* @param {string} shortcut keyboard shourtcut such as `Alt+Shift+e` (case-sensitive, no spaces allowed)
* @param {boolean} [exclude] (optional) inverse logic: return only keys that are not modifiers instead
* @returns {[string]} array of modifier keys to be pressed together
*/
export function filterModifiers(shortcut, exclude = false) {
const modifiers = [`Alt`, `AltGraph`, `Shift`, `CapsLock`, `Control`, `Meta`, `NumLock`, `OS`, `ScrollLock`]
const lowModifiers = modifiers.map(m => m.toLowerCase())
const keys = shortcut
.split('+').map(k => k.toLowerCase())
.map(k => ((k || '+').trim()) || ' ') // treat things like "Control +" and "Control+" as `Control` and `+` together
if (exclude) {
return keys.filter(k => !lowModifiers.includes(k));
}
else {
return modifiers.filter(m => keys.includes(m.toLowerCase()));
}
}


/**
* Check if a modifier key is pressed
* Checks for if no `modifier` argument is provided
*
* @param {KeyboardEvent} event - onKeyDown event
* @param {string} shortcut - Keyboard shortcut like `Meta+e` or `Shift+x`, case-sensitive
* @param {boolean} [ignoreFields] - (optional) disable the shortcut inside editable fields like `Textarea` or `Input`, defaults to false
* @return {boolean} `true` if modifier key is pressed, else `false`
*/
export function isHotkey(event, shortcut, ignoreFields = false) {
const needKeys = filterModifiers(shortcut, true);
if (needKeys.length !== 1) {
console.error(`Invalid shortcut "${shortcut}": multiple normal keys not allowed`);
return false;
}
const needKey = needKeys[0];
if (!Keycode.isEventKey(event, needKey)) {
return false;
}

const target = event.target || event.srcElement;
const tagName = target.tagName;
const isField = target.isContentEditable ||
((tagName === 'INPUT' || tagName === 'TEXTAREA') && !target.readOnly);
if (isField && ignoreFields) {
return false;
}

const modifiersPressed = filterModifiers(shortcut);
const allModifiersPressed = modifiersPressed.every(m => event.getModifierState(translateModifierKey(m)));
if (!allModifiersPressed) {
return false;
}

return true
}

export default isHotkey;
10 changes: 8 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4383,9 +4383,10 @@ grommet-theme-hpe@^0.4.2:
resolved "https://registry.yarnpkg.com/grommet-theme-hpe/-/grommet-theme-hpe-0.4.2.tgz#f2c4d02341056a34d32f1fbc4f843b523912dce5"
integrity sha512-3GlnYNBM2DM90hgzrSedm40BsxIJaN6eDr5Ezeyqpp4SvwQnXpaEzlWkXiokTsgDlMhtNI/WoxWG9l/l9+y9oQ==

"grommet@https://github.com/grommet/grommet/tarball/stable":
grommet@^2.7.1:
version "2.7.1"
resolved "https://github.com/grommet/grommet/tarball/stable#82c951206776f2fe68b22c2d54f9c543c79815f4"
resolved "https://registry.yarnpkg.com/grommet/-/grommet-2.7.1.tgz#f05ad25f55c1b846515bab0967e156966b055d00"
integrity sha512-1QkupZUg8JeKYP4VR6CC5dPcOnkyzdnZtbk9W+mO27lzGQEfvQS+7HrN9DRzQIGf1gsWmGaXCKmmHm2S9xeJig==
dependencies:
css "^2.2.3"
grommet-icons "^4.2.0"
Expand Down Expand Up @@ -5842,6 +5843,11 @@ jsx-ast-utils@^2.0.1:
dependencies:
array-includes "^3.0.3"

keycode@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04"
integrity sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=

killable@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
Expand Down