UNPKG

kbind

Version:

Library for working with keybinds

294 lines (293 loc) 13.4 kB
import { default as AnyOrderArray } from './types/AnyOrderArray'; import { default as Handler } from './types/Handler'; import { modifierKeys, primaryKeys } from './data'; import { default as Key } from './enums/Key'; import { default as EnumValuesToValues } from './types/EnumValuesToValues'; import { default as EnumValueToValue } from './types/EnumValueToValue'; /** * KeyBinder class provides functionality to manage keyboard event listeners, * layers, and modifier keys. It allows registering and unregistering listeners * and layers, handling key events, and validating events based on custom * validators. */ declare class KeyBinder { private static state; /** * An array of event validator functions used to determine the validity of keyboard events. * * It's necessary in case you don't want to trigger some listeners under certain conditions, * e.g. `Ctrl+A` in a text field. * * @type {KeyBinder.EventValidator[]} */ static eventValidators: KeyBinder.EventValidator[]; /** * Checks if either the left or right Control key is currently pressed. * * @returns {boolean} `true` if either ControlLeft or ControlRight key is pressed, * otherwise `false`. */ static get isControlPressed(): boolean; /** * Checks if either the left or right Shift key is currently pressed. * * @returns {boolean} `true` if either ShiftLeft or ShiftRight key is pressed, * otherwise `false` */ static get isShiftPressed(): boolean; /** * Checks if either the left or right Alt key is currently pressed. * * @returns {boolean} `true` if either AltLeft or AltRight key is pressed, * otherwise `false`. */ static get isAltPressed(): boolean; /** * Gets the sorted list of layer ids based on their priority. * * NOTE: heavy operation, use it wisely. * * @returns {string[]} An array of layer IDs sorted in descending order of their priority. */ static get layerIds(): string[]; /** * Gets the sorted list of listener ids based on their priority. * * NOTE: heavy operation, use it wisely. * * @returns {string[]} An array of listener IDs sorted in descending order of their priority. */ static get listenerIds(): string[]; /** * Gets the highest priority of the layer in the stack. * * NOTE: heavy operation, use it wisely. * * @returns {number | undefined} The highest priority of the layer in the stack. */ static get highestLayerPriority(): number | undefined; /** * Mounts the KeyBinder event listeners to the window object. * This method attaches the following event listeners: * - 'blur': Calls the `blurHandler` method when the window loses focus. * - 'keydown': Calls the `keyDownHandler` method when a key is pressed down. * - 'keyup': Calls the `keyUpHandler` method when a key is released. */ static mount(): void; /** * Unmounts the KeyBinder by removing event listeners for 'blur', 'keydown', and 'keyup' events. * This method should be called to clean up event listeners when the KeyBinder is no longer * needed. */ static unmount(): void; /** * Handles the blur event by resetting the state of modifier keys. * This method is called when the window loses focus. */ static blurHandler(): void; /** * Handles the key down event by processing the key code and updating the state of modifier * keys. * * @param event - The keyboard event triggered by a key press. */ static keyDownHandler(event: KeyboardEvent): void; /** * Handles the key up event for modifier keys. * * @param event - The keyboard event triggered on key up. */ static keyUpHandler(event: KeyboardEvent): void; /** * Checks if the given key code is a modifier key. * * @param key - The key code to check. * @returns `true` if the key is a modifier key, otherwise `false`. */ static isModifierKeyCode(key: string): key is KeyBinder.ModifierKey; /** * Checks if the given key code is a primary key. * * @param key - The key code to check. * @returns `true` if the key is a primary key, otherwise `false`. */ static isPrimaryKeyCode(key: string): key is KeyBinder.PrimaryKey; /** * Converts a given key code to its corresponding key name. * * @param key - The key code to convert. * @returns The key name corresponding to the key code, * or the key code itself if no key name is found. */ static normalizeKey(key: KeyBinder.KeyCode): "Alt" | "AltLeft" | "AltRight" | "ArrowDown" | "ArrowLeft" | "ArrowRight" | "ArrowUp" | "Backspace" | "CapsLock" | "ControlLeft" | "ControlRight" | "Delete" | "End" | "Enter" | "Escape" | "Home" | "Insert" | "IntlBackslash" | "IntlRo" | "IntlYen" | "F1" | "F2" | "F3" | "F4" | "F5" | "F6" | "F7" | "F8" | "F9" | "F10" | "F11" | "F12" | "F13" | "F14" | "F15" | "F16" | "F17" | "F18" | "F19" | "F20" | "F21" | "F22" | "F23" | "F24" | "PageUp" | "PageDown" | "Pause" | "ScrollLock" | "Shift" | "ShiftLeft" | "ShiftRight" | "Space" | "Tab" | "`" | "\\" | "[" | "]" | "," | "Ctrl" | "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "-" | "=" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "Numpad 0" | "Numpad 1" | "Numpad 2" | "Numpad 3" | "Numpad 4" | "Numpad 5" | "Numpad 6" | "Numpad 7" | "Numpad 8" | "Numpad 9" | "+" | "*" | "/" | "." | "\"" | ";"; /** * Converts a key binding to an array of key names. * * @param keyBind - The key binding to convert. * @returns An array of key names corresponding to the key binding. */ static normalizeKeyBind(keyBind: KeyBinder.KeyBind): ("Alt" | "AltLeft" | "AltRight" | "ArrowDown" | "ArrowLeft" | "ArrowRight" | "ArrowUp" | "Backspace" | "CapsLock" | "ControlLeft" | "ControlRight" | "Delete" | "End" | "Enter" | "Escape" | "Home" | "Insert" | "IntlBackslash" | "IntlRo" | "IntlYen" | "F1" | "F2" | "F3" | "F4" | "F5" | "F6" | "F7" | "F8" | "F9" | "F10" | "F11" | "F12" | "F13" | "F14" | "F15" | "F16" | "F17" | "F18" | "F19" | "F20" | "F21" | "F22" | "F23" | "F24" | "PageUp" | "PageDown" | "Pause" | "ScrollLock" | "Shift" | "ShiftLeft" | "ShiftRight" | "Space" | "Tab" | "`" | "\\" | "[" | "]" | "," | "Ctrl" | "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "-" | "=" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "Numpad 0" | "Numpad 1" | "Numpad 2" | "Numpad 3" | "Numpad 4" | "Numpad 5" | "Numpad 6" | "Numpad 7" | "Numpad 8" | "Numpad 9" | "+" | "*" | "/" | "." | "\"" | ";")[]; /** * Gets the highest priority of the listener in the stack. * * NOTE: heavy operation, use it wisely. * * @param layerId - The id of the layer to get the highest listener priority from. * @returns {number | undefined} The highest priority of the listener in the given layer stack. */ static getHighestListenerPriority(layerId: KeyBinder.State.Layer.Id): number | undefined; /** * Registers a listener with a specified id. * * @param id - The unique identifier for the listener. * @param listener - The listener metadata object containing the callback and other properties. */ static registerListener(id: KeyBinder.State.Listener.Id, listener: KeyBinder.State.Listener): void; /** * Removes a listener from the state by its unique id. * * @param id - The unique identifier for the listener. */ static unregisterListener(id: KeyBinder.State.Listener.Id): void; /** * Registers a layer with a specified id. * * @param id - The unique identifier for the layer. * @param layer - The layer metadata object containing the priority and propagation properties */ static registerLayer(id: KeyBinder.State.Layer.Id, layer: KeyBinder.State.Layer): void; /** * Removes a layer from the state by its unique id. * * @param id - The unique identifier for the layer. */ static unregisterLayer(id: KeyBinder.State.Layer.Id): void; private static isValidEvent; private static checkIfBindModifierKeysPressed; private static findListenerIdByPressedKey; private static emit; } declare namespace KeyBinder { /** * Represents a type that corresponds to one of the modifier keys. */ type ModifierKey = (typeof modifierKeys)[number]; /** * Represents a type that corresponds to one of the primary keys. * Primary keys are the keys that are not modifiers and can be used in key binding. */ type PrimaryKey = (typeof primaryKeys)[number]; /** * Represents a type that corresponds to the keys of the `Key` object. * This type is used to define all valid key codes that can be used. */ type KeyCode = keyof typeof Key; /** * Represents a type that corresponds to the key codes that can be used in key binding as * modifier keys. */ type ModifierKeys = [ Key.Control | Key.ControlLeft | Key.ControlRight, Key.Shift | Key.ShiftLeft | Key.ShiftRight, Key.Alt | Key.AltLeft | Key.AltRight ]; /** * A type representing a function that validates a keyboard event. * * @callback EventValidator * @param {KeyboardEvent} event - The keyboard event to validate. * @returns {boolean} - Returns `true` if the event is valid, otherwise `false`. */ type EventValidator = (event: KeyboardEvent) => boolean; /** * Represents a key binding that consists of a combination of modifier keys and a primary key. */ type KeyBind = [...KeyBind.Modifiers, KeyBind.PressKey]; namespace KeyBind { /** * Represents a type that corresponds to the modifier keys that can be used in key binding. */ type Modifiers = EnumValuesToValues<AnyOrderArray<ModifierKeys>>; /** * Represents a type that corresponds to the primary keys that can be used in key binding. */ type PressKey = EnumValueToValue<PrimaryKey>; } /** * Represents the state of the key binder. * * @interface State * @property {ModifierKey[]} modifierKeys - An array of modifier keys currently active. * @property {Record<State.Listener.Id, State.Listener>} listeners - A record of listeners * identified by their unique ids. * @property {Record<State.Layer.Id, State.Layer>} layers - A record of layers identified by * their unique ids. */ interface State { modifierKeys: ModifierKey[]; listeners: Record<State.Listener.Id, State.Listener>; layers: Record<State.Layer.Id, State.Layer>; } namespace State { /** * Represents a layer in the key binding system. * * @interface Layer * @property {number} priority - The priority of the layer. Higher numbers indicate higher * priority. * @property {boolean} propagate - Determines whether the key event should propagate to * lower priority layers. */ interface Layer { priority: number; propagate: boolean; } namespace Layer { /** * Represents a unique identifier of the layer as a string. */ type Id = string; } /** * Represents a listener in the key binding system. * * @interface Listener * * @property {Layer.Id} layerId - Optional identifier for the layer * (default value: `default`). * @property {number} priority - The priority of the listener. * @property {KeyBind | null} bind - Optional key binding associated with the listener * (e.g. `['Control', 'KeyB']`). * @property {Handler<KeyboardEvent>} handler - Optional handler function for the keyboard * event. The handler is called when the key binding is pressed. * @property {Listener.Options} options - Optional additional options for the listener. */ interface Listener { layerId?: Layer.Id; priority: number; bind?: KeyBind | null; handler?: Handler<KeyboardEvent>; options?: Listener.Options; } namespace Listener { /** * Represents a unique identifier of the listener as a string. */ type Id = string; /** * Options for configuring listener key binding behavior. * * @interface Options * @property {boolean} [preventDefault] - If `true`, the default action of the event * will be prevented. * @property {boolean} [stopPropagation] - If `true`, the event will not propagate * further. */ interface Options { preventDefault?: boolean; stopPropagation?: boolean; } } } } export default KeyBinder;