{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-keyboard-event",
  "title": "useKeyboardEvent",
  "description": "A hook to handle keyboard events",
  "files": [
    {
      "path": "registry/hooks/use-keyboard-event.ts",
      "content": "'use client'\n\nimport * as React from 'react'\n\nexport type KeyboardEventFilter = string | ((event: KeyboardEvent) => boolean)\n\nexport function useKeyboardEvent(\n  predicate: KeyboardEventFilter,\n  callback: (event: KeyboardEvent) => void,\n  options: {\n    event?: 'keydown' | 'keypress' | 'keyup'\n    target?: HTMLElement | React.RefObject<HTMLElement | null>\n    deps?: React.DependencyList\n  } = {},\n): void {\n  const { event = 'keydown', target = window } = options\n  const callbackEvent = React.useEffectEvent(callback)\n  const getPredicateEvent = React.useEffectEvent((ev: KeyboardEvent) => {\n    return typeof predicate === 'string'\n      ? ev.key === predicate\n      : predicate(ev)\n  })\n\n  React.useEffect(() => {\n    const abortController = new AbortController()\n\n    const t = 'current' in target ? target.current : target\n\n    if (!t) {\n      return\n    }\n\n    t.addEventListener(event, (e) => {\n      const event = e as KeyboardEvent\n      const matches = getPredicateEvent(event)\n\n      if (matches) {\n        callbackEvent(event)\n      }\n    }, {\n      signal: abortController.signal,\n    })\n\n    return () => {\n      abortController.abort()\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [event, target, ...(options.deps || [])])\n}\n",
      "type": "registry:hook",
      "target": "hookas/use-keyboard-event.ts"
    }
  ],
  "type": "registry:hook"
}