File size: 1,412 Bytes
4d70170 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
import { defineComponent } from 'vue'
export const LEFT = 'ArrowLeft'
export const UP = 'ArrowUp'
export const RIGHT = 'ArrowRight'
export const DOWN = 'ArrowDown'
export const ENTER = 'Enter'
export const DEL = 'Delete'
export const BACKSPACE = 'Backspace'
const activeInstances = []
function processEvent(event, type) {
if (
event.target.tagName === 'INPUT'
|| event.target.tagName === 'TEXTAREA'
) {
return
}
const modifiers: string[] = []
if (event.ctrlKey || event.metaKey) {
modifiers.push('ctrl')
}
if (event.shiftKey) {
modifiers.push('shift')
}
if (event.altKey) {
modifiers.push('alt')
}
const info = {
key: event.key,
code: event.code,
modifiers: modifiers.join('+'),
}
let result = true
activeInstances.forEach((opt) => {
if (opt[type]) {
const r = opt[type].call(opt.vm, info)
if (r === false) {
result = false
}
}
})
if (!result) {
event.preventDefault()
}
}
document.addEventListener('keydown', (event) => {
processEvent(event, 'onKeyDown')
})
export default function (options) {
return defineComponent({
mounted() {
activeInstances.push({
vm: this,
...options,
})
},
unmounted() {
const i = activeInstances.findIndex(
o => o.vm === this,
)
if (i >= 0) {
activeInstances.splice(i, 1)
}
},
})
}
|