From 918133ca5f9df5063c0a94d0e71cc913446f701f Mon Sep 17 00:00:00 2001 From: Adam Procter <adamprocter@researchnot.es> Date: Fri, 30 Apr 2021 17:36:19 +0100 Subject: [PATCH] added simple shortcut mixin --- src/components/ToolBar.vue | 12 +++++ src/mixins/shortcuts.js | 89 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 src/mixins/shortcuts.js diff --git a/src/components/ToolBar.vue b/src/components/ToolBar.vue index ad0bdc7..e13daa3 100644 --- a/src/components/ToolBar.vue +++ b/src/components/ToolBar.vue @@ -10,6 +10,7 @@ <script> // @ is an alias to /src import UploadMedia from '@/components/UploadMedia.vue' +import shortcuts from '@/mixins/shortcuts' export default { name: 'ToolBar', @@ -20,6 +21,17 @@ export default { return {} }, + mixins: [ + shortcuts('n', function () { + // n key pressed + this.addNode() + }), + shortcuts('ArrowRight', function () { + // Arrow right key was pressed + console.log('->') + }), + ], + methods: { addNode() { this.$store.dispatch('addNode') diff --git a/src/mixins/shortcuts.js b/src/mixins/shortcuts.js new file mode 100644 index 0000000..94f478b --- /dev/null +++ b/src/mixins/shortcuts.js @@ -0,0 +1,89 @@ +// Original code from here +// https://gist.github.com/loilo/2a1834dc20d842f63bd048ffbcf3dc19#file-shortcut-mjs + +// Modifier keys +export const CTRL = 0b000001 +export const ALT = 0b000010 +export const SHIFT = 0b000100 +export const META = 0b001000 + +// The Windows key +export const WIN = 0b010000 + +// The CMD key +export const CMD = 0b100000 + +// Check for macOS +const isMac = navigator.appVersion.includes('Macintosh') + +// Determine the primary modifier key +export const PRIMARY = isMac ? CMD : CTRL + +/** + * Create a mixin for simple keyboard shortcuts + * + * @param {string|string[]} matcher The key name(s) to react to + * @param {number} modifierKeys A bitmask of modifier keys + * @returns {object} + */ +export default function shortcut(matcher, ...args) { + // If only one remaining argument, treat it as callback + if (args.length === 1) { + return shortcut(matcher, 0b0000, args[0]) + } + + // The key the listener function will be stored at + const LISTENER = Symbol('keydown listener') + + let [modifierKeys, callback] = args + + // Check modifier keys for WIN or CMD + let excludedByOS = false + if (modifierKeys & (WIN | CMD)) { + // Add META to modifier keys if OS matches + if (modifierKeys & (isMac ? CMD : WIN)) { + modifierKeys = modifierKeys | META + } else { + excludedByOS = true + } + } + + // Normalize matcher towards a function + if (typeof matcher === 'string') { + matcher = [matcher] + } + if (Array.isArray(matcher)) { + const lowerKeys = matcher.map((key) => key.toLowerCase()) + matcher = (event) => lowerKeys.includes(event.key.toLowerCase()) + } + + return { + mounted() { + this[LISTENER] = (event) => { + if ( + // Check for exclusion by OS + !excludedByOS && + // No explicitely focused element + document.activeElement === document.body && + // Control key matches requirement + event.ctrlKey === Boolean(modifierKeys & CTRL) && + // Alt key matches requirement + event.altKey === Boolean(modifierKeys & ALT) && + // Shift key matches requirement + event.shiftKey === Boolean(modifierKeys & SHIFT) && + // Meta key matches requirement + event.metaKey === Boolean(modifierKeys & META) && + // Key name is the requested one + matcher(event) + ) { + callback.call(this, event) + } + } + + document.addEventListener('keydown', this[LISTENER]) + }, + unmounted() { + document.removeEventListener('keydown', this[LISTENER]) + }, + } +} -- GitLab