UNPKG

@keybindy/react

Version:

Keybindy for React: Simple, scoped keyboard shortcuts that require little setup. designed to smoothly blend in with your React applications, allowing for robust keybinding functionality without the overhead.

164 lines (161 loc) 5.19 kB
import React from 'react'; import ShortcutManager from '@keybindy/core'; let sharedInstance = null; const getSharedInstance = (options) => { if (typeof window === 'undefined') { return null; } if (!sharedInstance) { sharedInstance = new ShortcutManager(options); } return sharedInstance; }; /** * React hook to manage keyboard shortcuts using a shared instance of `ShortcutManager`. * This hook is safe for server-side rendering (SSR) and will only initialize the manager on the client. * * @param {Object} config - Configuration object. * @param {boolean} [config.logs=false] - Whether to enable debug logs in the console. * @param {(info: Shortcut) => void} [config.onShortcutFired] - Callback for when a shortcut is fired. * * @returns {Object} Object containing shortcut management methods and the manager instance (null on server). */ const useKeybindy = ({ logs = false, onShortcutFired, } = {}) => { const [manager, setManager] = React.useState(null); React.useEffect(() => { if (!manager) { const instance = getSharedInstance({ onShortcutFired, silent: !logs }); setManager(instance); } }, []); const log = (...args) => { if (logs) console.log('[Keybindy]', ...args); }; const warn = (...args) => { if (logs) console.warn('[Keybindy]', ...args); }; const register = React.useCallback((keys, handler, options) => { if (!manager) return; if (keys.length === 0) { warn('No keys provided to register'); return; } const id = options?.data?.id; log('Registered:', id ?? keys); manager.register(keys, handler, options); }, [manager]); const unregister = React.useCallback((keys, scope) => { if (!manager) return; if (keys.length === 0) { warn('No keys provided to unregister'); return; } manager.unregister(keys, scope); log('Unregistered:', keys); }, [manager]); const enable = React.useCallback((keys, scope) => { if (!manager) return; if (keys.length === 0) { warn('No keys provided to enable'); return; } manager.enable(keys, scope); log('Enabled:', keys); }, [manager]); const disable = React.useCallback((keys, scope) => { if (!manager) return; if (keys.length === 0) { warn('No keys provided to disable'); return; } manager.disable(keys, scope); log('Disabled:', keys); }, [manager]); const toggle = React.useCallback((keys, scope) => { if (!manager) return; if (keys.length === 0) { warn('No keys provided to toggle'); return; } manager.toggle(keys, scope); log('Toggled:', keys); }, [manager]); const getCheatSheet = React.useCallback((scope) => { return manager?.getCheatSheet(scope); }, [manager]); const getActiveScope = React.useCallback(() => { return manager?.getActiveScope(); }, [manager]); const disableAll = React.useCallback((scope) => { manager?.disableAll(scope); log(`Disabled all shortcuts${scope ? ` in scope "${scope}"` : ''}`); }, [manager]); const enableAll = React.useCallback((scope) => { manager?.enableAll(scope); log(`Enabled all shortcuts${scope ? ` in scope "${scope}"` : ''}`); }, [manager]); const setScope = React.useCallback((scope) => { manager?.setActiveScope(scope); log('Scope set to:', scope); }, [manager]); const resetScope = React.useCallback(() => { manager?.resetScope(); log('Reset scope'); }, [manager]); const getScopes = React.useCallback(() => { return manager?.getScopes(); }, [manager]); const isScopeActive = React.useCallback((scope) => { return manager?.isScopeActive(scope); }, [manager]); const onTyping = React.useCallback((callback) => { manager?.onTyping(callback); }, [manager]); const popScope = React.useCallback(() => { manager?.popScope(); log('Popped scope, active scope is:', manager?.getActiveScope()); }, [manager]); const pushScope = React.useCallback((scope) => { manager?.pushScope(scope); log('Pushed scope:', scope); }, [manager]); const getScopeInfo = React.useCallback((scope) => { return manager?.getScopesInfo(scope); }, [manager]); const destroy = () => { manager?.destroy(); }; const clear = () => { manager?.clear(); }; return { register, unregister, enable, disable, toggle, setScope, getCheatSheet, destroy, getScopeInfo, getActiveScope, popScope, pushScope, resetScope, getScopes, isScopeActive, onTyping, enableAll, clear, disableAll, manager, }; }; export { useKeybindy };