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 x19 x19 x55 x56 x56 x90 x130 x189 x189 x189 x189 x189 x215 x222 x222 x234 x189 x192 x194 x194 x193 x189 x199 x214 x214 x212 x189 x209 x220 x220 x189 x189 x144 x90 x19 x19 |
/**
* 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) {
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
})
}
}
|