@types/keymaster
Version:
TypeScript definitions for keymaster
194 lines (179 loc) • 5.99 kB
TypeScript
export as namespace key;
export = Keymaster;
declare const Keymaster: Keymaster;
interface Keymaster {
/**
* Defines a shortcut.
*
* Keymaster understands the following modifiers:
* `⇧`, `shift`, `option`, `⌥`, `alt`, `ctrl`, `control`, `command`, and `⌘`.
*
* The following special keys can be used for shortcuts:
* `backspace`, `tab`, `clear`, `enter`, `return`, `esc`, `escape`, `space`,
* `up`, `down`, `left`, `right`, `home`, `end`, `pageup`, `pagedown`, `del`, `delete`
* and `f1` through `f19`.
*
* @example
* import key = require('keymaster');
*
* // define short of 'a'
* key('a', () => alert('you pressed a!'));
*
* // returning false stops the event and prevents default browser events
* key('ctrl+r', () => {
* alert('stopped reload!');
* return false;
* });
*
* // multiple shortcuts that do the same thing
* key('⌘+r, ctrl+r', () => {});
*
* // define shortcuts with a scope
* key('o, enter', 'issues', () => {});
* key('o, enter', 'files', () => {});
*/
(key: string, callback: Keymaster.KeyHandler): void;
(key: string, scope: string, callback: Keymaster.KeyHandler): void;
/**
* At any point in time (even in code other than key shortcut handlers),
* you can query the `key` object for the state of any keys. This
* allows easy implementation of things like shift+click handlers. For example,
* `key.shift` is `true` if the shift key is currently pressed.
*
* @example
* if (key.shift) {
* alert('shift is pressed, OMGZ!');
* }
*/
shift: boolean;
"⇧": boolean;
alt: boolean;
option: boolean;
"⌥": boolean;
ctrl: boolean;
control: boolean;
"⌃": boolean;
command: boolean;
"⌘": boolean;
/**
* Set the scope if you want to reuse the same shortcut for separate
* areas in your single page app.
*
* @example
* // set the scope (only 'all' and 'issues' shortcuts will be honored)
* key.setScope('issues'); // default scope is 'all'
*/
setScope(scopeName?: string): void;
/**
* @returns The current scope.
*/
getScope(): string;
/**
* Remove all events that are set in a scope.
*
* @example
* key.deleteScope('issues');
*/
deleteScope(scopeName: string): void;
/**
* By default, when an `INPUT`, `SELECT` or `TEXTAREA` element is focused,
* Keymaster doesn't process any shortcuts.
*
* You can change this by overwriting `key.filter` with a new function.
* This function is called before Keymaster processes shortcuts.
*
* If your function returns false, then the no shortcuts will be processed.
*
* Here's the default implementation for reference:
*
* ```ts
* function filter(event: KeyboardEvent) {
* const tagName = event.target!.tagName;
* return !(tagName === "INPUT" || tagName === "SELECT" || tagName === "TEXTAREA");
* }
* ```
*
* If you only want _some_ shortcuts to work while in an input element, you
* can change the scope in the `key.filter` function. Below is an example
* implementation, setting the scope to either `'input'` or `'other'`.
* Don't forget to return `true` so the any shortcuts get processed.
*
* However a more robust way to handle this is to use proper
* focus and blur event handlers on your input element, and change scopes there as you see fit.
*
* @example
* key.filter = (event) => {
* const tagName = event.target!.tagName;
* key.setScope(/^(INPUT|TEXTAREA|SELECT)$/.test(tagName) ? 'input' : 'other');
* return true;
* }
*/
filter(event: Keymaster.FilterEvent): boolean;
/**
* At any point in time (even in code other than key shortcut handlers),
* you can query the `key` object for the state of any key. This
* is very helpful for game development using a game loop. For example,
* `key.isPressed(77)` is `true` if the M key is currently pressed.
*
* @example
* if (key.isPressed('M')) {
* alert('M key is pressed, can ya believe it!?');
* }
* if (key.isPressed(77)) {
* alert('M key is pressed, can ya believe it!?');
* }
*/
isPressed(keyCode: number | string): boolean;
/**
* @returns The key codes currently pressed.
*/
getPressedKeyCodes(): number[];
/**
* Removes the `key` function from global scope and restore whatever
* `key` was defined to before Keymaster was loaded.
*
* @returns The Keymaster `key` function.
*
* @example
* const keymaster = key.noConflict();
* keymaster('a', () => {});
*
* key()
* // --> TypeError: 'undefined' is not a function
*/
noConflict(): Keymaster;
/**
* Shortcuts can be unbound with this method.
*
* @example
* // unbind 'a' handler
* key.unbind('a');
*
* // unbind a key only for a single scope
* // when no scope is specified it defaults to the current scope (key.getScope())
* key.unbind('o, enter', 'issues');
* key.unbind('o, enter', 'files');
*/
unbind(key: string, scopeName?: string): void;
}
declare namespace Keymaster {
interface Handler {
key: string;
method: KeyHandler;
mods: number[];
/**
* The scope (or `all`).
*/
scope: string;
/**
* The shortcut used, e.g. `ctrl+r`.
*/
shortcut: string;
}
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
type KeyHandler = (keyboardEvent: KeyboardEvent, handler: Handler) => boolean | void;
type FilterEvent = EventTarget & {
target: HTMLElement | null;
srcElement: HTMLElement | null;
};
}