@clinth/ui-commands
v1.0.2
Published
A general-purpose library for managing UI commands, keyboard shortcuts, and input handling.
Readme
@clinth/ui-commands
A general-purpose library for managing UI commands, keyboard shortcuts, and input handling.
Installation
npm install @clinth/ui-commandsQuick Start
import {
CommandRegistry,
KeyboardManager,
loadKeyBindings,
InputManager,
createInputManager,
type KeyBindingConfig,
} from '@clinth/ui-commands';
// 1. Create a command registry
interface AppState {
isPlaying: boolean;
}
const registry = new CommandRegistry<AppState>({
onInvoke: (id, args) => console.log(`Command invoked: ${id}`, args),
onCommandNotFound: (id) => console.warn(`Unknown command: ${id}`),
});
// 2. Register commands
registry.register({
id: 'play-stop',
label: 'Play/Stop',
description: 'Toggle playback',
execute: () => console.log('Toggling playback'),
});
registry.register({
id: 'zoom-in',
label: 'Zoom In',
description: 'Increase zoom level',
enabledWhen: (state) => !state.isPlaying, // Only when not playing
execute: () => console.log('Zooming in'),
});
// 3. Create keyboard manager and load bindings
type AppMode = 'detail' | 'coarse';
const keyboard = new KeyboardManager<AppMode>();
const bindings: KeyBindingConfig<AppMode>[] = [
{ key: ' ', mode: 'all', command: 'play-stop', description: 'Play/Stop' },
{ key: '=', mode: 'detail', command: 'zoom-in', description: 'Zoom in' },
{ key: 'q', mode: 'detail', command: 'zoom-in', description: 'Zoom in' },
];
loadKeyBindings(keyboard, bindings);
// 4. Create input manager and initialize
const input = createInputManager(registry, keyboard);
input.setModeGetter(() => 'coarse');
input.init(); // Attaches to document.bodyCore Concepts
CommandRegistry
Manages registration and invocation of commands.
const registry = new CommandRegistry({
onInvoke: (id, args) => { /* called on successful command */ },
onInvokeError: (id, error) => { /* called when command throws */ },
onCommandNotFound: (id) => { /* called when command not found */ },
});
registry.register({
id: 'my-command',
label: 'My Command',
description: 'Does something',
execute: (args) => { /* ... */ },
});
registry.invoke('my-command', { foo: 'bar' });KeyboardManager
Handles keyboard event binding and matching.
const keyboard = new KeyboardManager<AppMode>();
keyboard.bind({
key: 'a',
modifiers: new Set(['ctrl']),
mode: 'detail',
commandId: 'my-command',
});
// Get all current bindings
const bindings = keyboard.getBindings();InputManager
Coordinates between command registry and keyboard, plus handles button bindings.
const input = createInputManager(registry, keyboard);
// Bind a button element to a command
const button = document.getElementById('my-button');
input.bindButton(button, 'my-command');
// Or bind keys directly
input.bindKey('Enter', [], 'my-command', 'detail');
// Set the current app mode
input.setModeGetter(() => currentMode);Generic Mode Type
The library uses generics to support custom mode types:
type AdminMode = 'users' | 'settings' | 'reports';
const keyboard = new KeyboardManager<AdminMode>();
const input = createInputManager(registry, keyboard);API Reference
CommandRegistry
register(command)- Register a commandunregister(id)- Unregister a commandinvoke(id, args?)- Invoke a command, returns booleanget(id)- Get command by IDgetAll()- Get all registered commandsgetEnabled(state)- Get commands enabled for given statehas(id)- Check if command exists
KeyboardManager
bind(binding)- Add a key bindingunbind(key, modifiers)- Remove a key bindingsetActive(active)- Enable/disable keyboard handlingsetModeGetter(getter)- Set function that returns current modegetBindings()- Get all bindings
InputManager
init()- Initialize and attach to DOMdestroy()- CleanupbindKey(key, modifiers, commandId, mode?)- Bind a keybindButton(element, commandId)- Bind a button clickunbindButton(element)- Remove button bindingsetActive(active)- Enable/disable input handling
