From ccdc0eb82879841cada17f0591cf5bbbe21bb9f8 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 17 Aug 2025 17:07:50 +0200 Subject: [PATCH] made return value not nullable, fixed sequence of keys in events, removed AI text from readme --- README.md | 27 +++++++++++++++++---------- package.json | 2 +- src/createKeyHandler.ts | 12 ++++++++---- src/index.ts | 1 + src/test/createKeyHandler.test.ts | 27 ++++++++++++--------------- src/types.ts | 1 + 6 files changed, 40 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 1cdb95d..c100a40 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # hyperf-keybinds -Quickly handle keyboard shortcuts and sequences in your app. - +Handle keybind sequences in your app. +You can have branches of sequences, the only restriction being that one sequence cannot be a strict subset of another. ## Install ```bash @@ -11,23 +11,30 @@ npm install hyperf-keybinds ## Quick Start ```ts -import { createKeyHandler, KeybindEventTypes, ModifierKey } from 'hyperf-keybinds'; +import { createKeyHandler, ModifierKey, KeybindEvent} from 'hyperf-keybinds'; -// Define a command +// Define commands const commands = [ { command: [{ key: 'KeyS', modifiers: [ModifierKey.Control] }], callback: () => console.log('Ctrl+S!') }, { command: [{ key: 'KeyA', modifiers: []}, { key: 'KeyS', modifiers: []}], callback: () => console.log('a - s!')} ]; -// Create handler and emitter -const { handler, emitter } = createKeyHandler(commands); +// Create handler +const {handler, emitter, success} = createKeyHandler(commands, 5000); -// Attach to window -window.addEventListener('keydown', handler); +// Success is false if you provided invalid sequences. +if (success) +{ + window.addEventListener('keydown', handler); + + // Listen to events + emitter.on((event : KeybindEvent) => console.log(event.type, event)); +} -// Listen to events -emitter.on(e => console.log(e.type)); ``` Now Ctrl+S triggers your callback and emits events. Pressing a then s triggers a separate callback. +Timeout (default 5000) can be observed by just pressing key A. + +Key codes can be looked up here: https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_code_values diff --git a/package.json b/package.json index a26898a..20b17e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hyperf-keybinds", - "version": "0.1.1", + "version": "0.1.2", "description": "", "main": "dist/index.js", diff --git a/src/createKeyHandler.ts b/src/createKeyHandler.ts index f148631..630cbe6 100644 --- a/src/createKeyHandler.ts +++ b/src/createKeyHandler.ts @@ -2,10 +2,14 @@ import { KeybindEmitter } from "./keybindEmitter"; import { KeyTree } from "./keyTree"; import { KeybindEventTypes, ModifierKey, type CommandMap, type KeyCommand, type KeyHandlerReturn, type Modifiers } from "./types"; -export function createKeyHandler(commandMaps : CommandMap[], timeout : number = 5000): KeyHandlerReturn | null { +export function createKeyHandler(commandMaps : CommandMap[], timeout : number = 5000): KeyHandlerReturn { const emitter = new KeybindEmitter(); const tree = KeyTree.buildTree(commandMaps); - if (tree === null) return null; + if (tree === null) return { + handler: () => {}, + emitter: emitter, + success: false + }; const sequenceProgress : KeyCommand[] = []; var currentTreeNode : KeyTree | null = null; @@ -20,7 +24,7 @@ export function createKeyHandler(commandMaps : CommandMap[], timeout : number = const tryResetFields = () => { currentTreeNode = null; - sequenceProgress.length = 0; + sequenceProgress.splice(0); tryResetTimeout(); }; @@ -68,7 +72,7 @@ export function createKeyHandler(commandMaps : CommandMap[], timeout : number = } } }; - return {handler, emitter}; + return {handler, emitter, success: true}; } function eventToKeyCommand(event: KeyboardEvent): KeyCommand{ diff --git a/src/index.ts b/src/index.ts index 977d0bd..d446320 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ export { createKeyHandler } from './createKeyHandler'; +export * from './types'; \ No newline at end of file diff --git a/src/test/createKeyHandler.test.ts b/src/test/createKeyHandler.test.ts index a55e920..b87f014 100644 --- a/src/test/createKeyHandler.test.ts +++ b/src/test/createKeyHandler.test.ts @@ -9,21 +9,20 @@ describe("createKeyHandler", () => { const command = makeCommand("KeyA"); const callback = vi.fn(); - const keyHandlerReturn = createKeyHandler([ + + const {handler, emitter, success} = createKeyHandler([ { command: [command], callback: callback } ]); - expect(keyHandlerReturn).not.toBe(null); + expect(success).toBe(true); - const handler = keyHandlerReturn?.handler; - const emitter = keyHandlerReturn?.emitter; const listener = vi.fn(); - emitter?.on(listener); + emitter.on(listener); const event = { code: command.key, shiftKey: false, ctrlKey: false, altKey: false, metaKey: false } as KeyboardEvent; - handler?.(event); + handler(event); expect(listener).toHaveBeenCalledTimes(2); @@ -56,12 +55,11 @@ describe("createKeyHandler", () => { const command2 = makeCommand("KeyB"); const callback = vi.fn(); - const keyHandlerReturn = createKeyHandler([ + const {handler, emitter, success} = createKeyHandler([ { command: [command1, command2], callback } ], delay); - const handler = keyHandlerReturn?.handler; - const emitter = keyHandlerReturn?.emitter; + expect(success).toBe(true); const listener = vi.fn(); emitter?.on(listener); @@ -93,12 +91,12 @@ describe("createKeyHandler", () => { const command = makeCommand("KeyA"); const callback = vi.fn(); - const keyHandlerReturn = createKeyHandler([ + const {handler, emitter, success} = createKeyHandler([ { command: [command], callback } ]); - const handler = keyHandlerReturn?.handler; - const emitter = keyHandlerReturn?.emitter; + expect(success).toBe(true); + const listener = vi.fn(); emitter?.on(listener); @@ -124,12 +122,11 @@ describe("createKeyHandler", () => { const command1 = makeCommand("KeyA"); const command2 = makeCommand("KeyB"); const callback = vi.fn(); - const keyHandlerReturn = createKeyHandler([ + const {handler, emitter, success} = createKeyHandler([ { command: [command1, command2], callback } ]); - const handler = keyHandlerReturn?.handler; - const emitter = keyHandlerReturn?.emitter; + expect(success).toBe(true); const listener = vi.fn(); emitter?.on(listener); diff --git a/src/types.ts b/src/types.ts index 162afce..0394b30 100644 --- a/src/types.ts +++ b/src/types.ts @@ -38,4 +38,5 @@ export type KeyEventHandler = (event: KeyboardEvent) => void; export interface KeyHandlerReturn { handler: KeyEventHandler; emitter: KeybindEmitter; + success: boolean; } \ No newline at end of file