useKeyActions
azemmur/hooks-use-key-actionsFreeHook
A hook for handling keyboard actions with customizable key bindings and modifiers.
Install it
npx shadcn@latest add https://azemmur.raouf.codes/r/hooks-use-key-actions.jsonSource
1// Copyright (c) 2026 raouf.codes - Azemmur23'use client';45import { useCallback } from 'react';67/**8 * Modifier keys that can be required for a key action.9 */10export type Modifiers = {11 ctrl?: boolean;12 alt?: boolean;13 shift?: boolean;14 meta?: boolean;15};1617/**18 * Configuration for a single key action.19 */20export type KeyAction = {21 keys: string[];22 action: (e: React.KeyboardEvent<HTMLElement>) => void;23 modifiers?: Modifiers;24 clickOnMatch?: boolean;25};2627/**28 * Check if the pressed modifier keys match the expected modifiers.29 */30export function modifiersMatch(31 event: React.KeyboardEvent<HTMLElement>,32 modifiers?: Modifiers,33): boolean {34 if (!modifiers) return true;3536 return (37 (modifiers.ctrl === undefined || modifiers.ctrl === event.ctrlKey) &&38 (modifiers.alt === undefined || modifiers.alt === event.altKey) &&39 (modifiers.shift === undefined || modifiers.shift === event.shiftKey) &&40 (modifiers.meta === undefined || modifiers.meta === event.metaKey)41 );42}4344/**45 * Hook for handling keyboard actions with customizable key bindings and modifiers.46 *47 * @example48 * ```tsx49 * const handleKeyDown = useKeyActions([50 * {51 * keys: ['Escape'],52 * action: () => close(),53 * },54 * {55 * keys: ['s'],56 * modifiers: { meta: true },57 * action: () => save(),58 * },59 * ]);60 *61 * return <input onKeyDown={handleKeyDown} />;62 * ```63 *64 * @param keyActions - Array of key action configurations65 * @param activeRef - Optional ref to scope key handling to a container66 * @param enabled - Whether the hook is active (default: true)67 * @returns Event handler function for onKeyDown68 */69export function useKeyActions(70 keyActions: KeyAction[],71 activeRef?: React.RefObject<HTMLElement | null>,72 enabled: boolean = true,73) {74 return useCallback(75 (e: React.KeyboardEvent<HTMLElement>) => {76 if (!enabled) return;7778 if (79 activeRef?.current &&80 !activeRef.current.contains(document.activeElement)81 ) {82 return;83 }8485 for (const { keys, action, modifiers, clickOnMatch } of keyActions) {86 if (keys.includes(e.key) && modifiersMatch(e, modifiers)) {87 e.preventDefault();88 action(e);8990 if (clickOnMatch && e.target instanceof HTMLElement) {91 e.target.click();92 }9394 break;95 }96 }97 },98 [keyActions, activeRef, enabled],99 );100}
Files it writes
More from Azemmur
All 27 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| useFocusTraphooks-use-focus-trap | Azemmur | Hooks | Free | no deps | |
| useIsMobilehooks-use-is-mobile | Azemmur | Hooks | Free | no deps | |
| useMergeRefshooks-use-merged-refs | Azemmur | Hooks | Free | no deps | |
| usePinchZoomhooks-use-pinch-zoom | Azemmur | Hooks | Free | no deps |
