{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "keyboard-shortcuts-help",
  "type": "registry:component",
  "title": "Keyboard Shortcuts Help",
  "description": "Displays available keyboard shortcuts to the user.",
  "dependencies": [
    "@vllnt/ui@^0.2.1"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/keyboard-shortcuts-help/keyboard-shortcuts-help.tsx",
      "content": "\"use client\";\n\nimport { memo, useEffect, useRef } from \"react\";\n\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"@vllnt/ui\";\n\nexport type KeyboardShortcut = {\n  description: string;\n  keys: readonly string[];\n};\n\nexport type KeyboardShortcutsHelpProps = {\n  className?: string;\n  closeIcon?: ReactNode;\n  footer?: ReactNode;\n  isOpen: boolean;\n  onClose: () => void;\n  shortcuts: readonly KeyboardShortcut[];\n  title?: string;\n};\n\n// eslint-disable-next-line max-lines-per-function -- Modal with keyboard handling and focus trap\nfunction KeyboardShortcutsHelpImpl({\n  className,\n  closeIcon,\n  footer,\n  isOpen,\n  onClose,\n  shortcuts,\n  title = \"Keyboard Shortcuts\",\n}: KeyboardShortcutsHelpProps): React.ReactNode {\n  const closeButtonRef = useRef<HTMLButtonElement>(null);\n\n  // Focus trap and close on Escape\n  useEffect(() => {\n    if (!isOpen) return;\n\n    closeButtonRef.current?.focus();\n\n    const handleKeyDown = (event: KeyboardEvent): void => {\n      if (event.key === \"Escape\") {\n        event.preventDefault();\n        onClose();\n      }\n    };\n\n    window.addEventListener(\"keydown\", handleKeyDown);\n    return () => {\n      window.removeEventListener(\"keydown\", handleKeyDown);\n    };\n  }, [isOpen, onClose]);\n\n  // Prevent body scroll when open\n  useEffect(() => {\n    document.body.style.overflow = isOpen ? \"hidden\" : \"\";\n    return () => {\n      document.body.style.overflow = \"\";\n    };\n  }, [isOpen]);\n\n  if (!isOpen) return null;\n\n  return (\n    <div\n      aria-labelledby=\"shortcuts-title\"\n      aria-modal=\"true\"\n      className=\"fixed inset-0 z-50 flex items-center justify-center\"\n      role=\"dialog\"\n    >\n      {/* Backdrop */}\n      <div\n        aria-hidden=\"true\"\n        className=\"absolute inset-0 bg-black/50 backdrop-blur-sm\"\n        onClick={onClose}\n      />\n\n      {/* Modal */}\n      <div\n        className={cn(\n          \"relative z-10 w-full max-w-sm rounded-lg bg-background p-6 shadow-xl mx-4\",\n          className,\n        )}\n      >\n        {/* Header */}\n        <div className=\"flex items-center justify-between mb-4\">\n          <h2 className=\"text-lg font-semibold\" id=\"shortcuts-title\">\n            {title}\n          </h2>\n          <button\n            aria-label=\"Close shortcuts help\"\n            className=\"flex size-8 items-center justify-center rounded-md hover:bg-muted\"\n            onClick={onClose}\n            ref={closeButtonRef}\n            type=\"button\"\n          >\n            {closeIcon ?? (\n              <svg\n                className=\"size-5\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                viewBox=\"0 0 24 24\"\n              >\n                <path\n                  d=\"M6 18L18 6M6 6l12 12\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                />\n              </svg>\n            )}\n          </button>\n        </div>\n\n        {/* Shortcuts List */}\n        <div className=\"space-y-3\">\n          {shortcuts.map((shortcut) => (\n            <div\n              className=\"flex items-center justify-between text-sm\"\n              key={shortcut.description}\n            >\n              <span className=\"text-muted-foreground\">\n                {shortcut.description}\n              </span>\n              <div className=\"flex gap-1\">\n                {shortcut.keys.map((key) => (\n                  <kbd\n                    className=\"inline-flex h-6 min-w-[24px] items-center justify-center rounded border border-border bg-muted px-1.5 font-mono text-xs\"\n                    key={key}\n                  >\n                    {key}\n                  </kbd>\n                ))}\n              </div>\n            </div>\n          ))}\n        </div>\n\n        {/* Footer */}\n        {footer ? (\n          <div className=\"mt-4 text-xs text-muted-foreground text-center\">\n            {footer}\n          </div>\n        ) : null}\n      </div>\n    </div>\n  );\n}\n\nexport const KeyboardShortcutsHelp = memo(KeyboardShortcutsHelpImpl);\nKeyboardShortcutsHelp.displayName = \"KeyboardShortcutsHelp\";\n",
      "type": "registry:component"
    }
  ],
  "version": "0.2.1",
  "stability": "stable"
}
