{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "kbd",
  "title": "Keyboard Shortcuts",
  "description": "Display keyboard shortcuts with proper key symbols.",
  "dependencies": [
    "react-hotkeys-hook"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/spell-ui/kbd.tsx",
      "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { useEffect, useState } from \"react\";\nimport { useHotkeys } from \"react-hotkeys-hook\";\n\ntype KeyItem = string | { display: string; key: string };\n\ninterface KbdProps {\n  keys: KeyItem[];\n  className?: string;\n  active?: boolean;\n  listenToKeyboard?: boolean;\n}\n\nconst keySymbolMap = {\n  command: \"⌘\",\n  cmd: \"⌘\",\n  control: \"⌃\",\n  ctrl: \"⌃\",\n  alt: \"⌥\",\n  option: \"⌥\",\n  space: \"␣\",\n  arrowleft: \"←\",\n  left: \"←\",\n  arrowdown: \"↓\",\n  down: \"↓\",\n  arrowup: \"↑\",\n  up: \"↑\",\n  arrowright: \"→\",\n  right: \"→\",\n} as const;\n\nconst keyHotkeyMap: Record<string, string> = {\n  command: \"meta\",\n  cmd: \"meta\",\n  control: \"ctrl\",\n  ctrl: \"ctrl\",\n  alt: \"alt\",\n  option: \"alt\",\n  shift: \"shift\",\n  enter: \"enter\",\n  return: \"enter\",\n  space: \"space\",\n  arrowleft: \"left\",\n  left: \"left\",\n  arrowdown: \"down\",\n  down: \"down\",\n  arrowup: \"up\",\n  up: \"up\",\n  arrowright: \"right\",\n  right: \"right\",\n};\n\nexport function Kbd({ keys = [], className, active, listenToKeyboard = false }: KbdProps) {\n  const [isPressed, setIsPressed] = useState(false);\n\n  const getKeyDisplay = (item: KeyItem): string => {\n    const key = typeof item === \"string\" ? item : item.display;\n    const lowerKey = key.toLowerCase();\n    return keySymbolMap[lowerKey as keyof typeof keySymbolMap] || key.toUpperCase();\n  };\n\n  const getHotkeyString = (): string => {\n    return keys\n      .map((item) => {\n        const key = typeof item === \"string\" ? item : item.key;\n        const lowerKey = key.toLowerCase();\n        return keyHotkeyMap[lowerKey] || lowerKey;\n      })\n      .join(\"+\");\n  };\n\n  useHotkeys(\n    getHotkeyString(),\n    () => setIsPressed(true),\n    {\n      enabled: listenToKeyboard,\n      keydown: true,\n      keyup: false,\n      preventDefault: false,\n    },\n    [keys, listenToKeyboard]\n  );\n\n  useEffect(() => {\n    if (!listenToKeyboard) return;\n\n    const handleKeyUp = () => {\n      setIsPressed(false);\n    };\n\n    const handleBlur = () => {\n      setIsPressed(false);\n    };\n\n    window.addEventListener(\"keyup\", handleKeyUp);\n    window.addEventListener(\"blur\", handleBlur);\n\n    return () => {\n      window.removeEventListener(\"keyup\", handleKeyUp);\n      window.removeEventListener(\"blur\", handleBlur);\n    };\n  }, [listenToKeyboard]);\n\n  const isActive = active || isPressed;\n\n  return (\n    <kbd\n      className={cn(\n        \"box-border align-text-top whitespace-nowrap select-none cursor-default tracking-tight rounded-[0.35em] min-w-[1.75em] shrink-0 justify-center items-center pb-[0.05em] px-[0.5em] text-[0.75em] font-normal leading-[1.7em] inline-flex relative -top-[0.03em] transition-all duration-100\",\n        isActive\n          ? \"bg-background text-foreground translate-y-[0.05em] shadow-[inset_0_0.05em_rgba(255,255,255,0.95),inset_0_0.05em_0.2em_rgba(0,0,0,0.1),0_0_0_0.05em_rgba(0,0,0,0.134)] dark:shadow-[inset_0_0.05em_0.2em_rgba(0,0,0,0.3),0_0_0_0.05em_rgba(255,255,255,0.134)]\"\n          : \"bg-background text-foreground shadow-[inset_0_-0.05em_0.5em_rgba(0,0,0,0.034),inset_0_0.05em_rgba(255,255,255,0.95),inset_0_0.25em_0.5em_rgba(0,0,0,0.034),inset_0_-0.05em_rgba(0,0,0,0.172),0_0_0_0.05em_rgba(0,0,0,0.134),0_0.08em_0.17em_rgba(0,0,0,0.231)] dark:shadow-[inset_0_-0.05em_0.5em_rgba(255,255,255,0.034),inset_0_0.05em_rgba(255,255,255,0.1),inset_0_0.25em_0.5em_rgba(255,255,255,0.034),inset_0_-0.05em_rgba(255,255,255,0.172),0_0_0_0.05em_rgba(255,255,255,0.134),0_0.08em_0.17em_rgba(255,255,255,0.231)]\",\n        className\n      )}\n    >\n      {keys.map((item, index) => (\n        <span key={index} className={index > 0 ? \"ml-0.5\" : \"\"}>\n          {getKeyDisplay(item)}\n        </span>\n      ))}\n    </kbd>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}