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 |
x7 x12 x12 x36 x1 x1 x35 x40 x59 x59 x59 x59 x59 x26 x7 x7 x19 x59 x3 x2 x2 x1 x59 x10 x6 x6 x4 x59 x20 x11 x11 x59 x59 x14 x35 x12 x12 |
/**
* Keyboard expression matcher.
*
* Multiple keys can be combined into a single combination using a plus sign (`+`).
* Multiple combinations can be combined into a single expression using a comma (`,`).
* Spaces are always trimmed.
*
* The following aliases are supported:
* - `alt` when `Alt` is pressed
* - `ctrl` when `Control` is pressed
* - `shift` when `Shift` is pressed
* - `meta` when `Meta` is pressed
* - `space` for `Space` key
* - `key` for any key except `Alt`, `Control`, `Shift` and `Meta`
*
* If the event is not a {@link https://developer.mozilla.org/docs/Web/API/KeyboardEvent | KeyboardEvent}, the function will return `false`.
*
* {@link https://developer.mozilla.org/docs/Web/API/UI_Events/Keyboard_event_key_values | Reference}
*
* ```ts
* import { Window } from "@mizu/internal/vdom"
* const { KeyboardEvent } = new Window()
*
* const check = keyboard("a,ctrl+b")
* console.assert(check(new KeyboardEvent("keydown", {key: "a"})))
* console.assert(check(new KeyboardEvent("keydown", {key: "b", ctrlKey: true})))
* console.assert(!check(new KeyboardEvent("keydown", {key: "c"})))
* ```
*
* @author Simon Lecoq (lowlighter)
* @license MIT
*/
export function keyboard(keys: string): (event: KeyboardEvent) => boolean {
const combinations = keys.split(",").map((combination) => combination.split("+").map((key) => key.trim().toLowerCase()))
return function (event: KeyboardEvent) {
if (!/^key(?:down|press|up)$/.test(event.type)) {
return false
}
return combinations.some((combination) => {
for (const key of combination) {
switch (key) {
case "alt":
case "ctrl":
case "shift":
case "meta":
if (!event[`${key}Key`]) {
return false
}
break
case "space":
if (event.key !== " ") {
return false
}
break
case "key":
if (/^(?:alt|ctrl|shift|meta)$/i.test(event.key)) {
return false
}
break
default:
if (event.key.toLowerCase() !== key) {
return false
}
}
}
return true
})
}
}
|