{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "mac-keyboard",
  "type": "registry:ui",
  "title": "Mac Keyboard",
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Component for mac-keyboard",
  "files": [
    {
      "path": "components/ui/mac-keyboard.tsx",
      "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n  ArrowLeft,\n  ArrowRight,\n  ArrowDown,\n  ArrowUp,\n  ChevronUp,\n  Command,\n  Globe,\n  LayoutGrid,\n  Lock,\n  Mic,\n  Moon,\n  Option,\n  Play,\n  Search,\n  SkipBack,\n  SkipForward,\n  Sun,\n  Volume1,\n  Volume2,\n  VolumeX,\n} from \"lucide-react\";\nimport * as React from \"react\";\n\n// Context to share active keys state\nconst KeyboardContext = React.createContext<{\n  activeKeys: Set<string>;\n}>({\n  activeKeys: new Set(),\n});\n\nexport interface MacKeyProps extends React.HTMLAttributes<HTMLDivElement> {\n  label?: React.ReactNode;\n  subLabel?: React.ReactNode;\n  icon?: React.ReactNode;\n  iconLabel?: string;\n  width?: number;\n  keyCode?: string | string[]; // Can be a single code or array of codes\n  noAspectRatio?: boolean; // Skip aspect-ratio on wrapper (for arrow half-height keys)\n}\n\ninterface MacKeyboardProps extends React.HTMLAttributes<HTMLDivElement> {\n  // Optional prop to provide a custom sound URL\n  soundSrc?: string;\n}\n\nexport function MacKeyboard({ className, soundSrc = \"/audio/key-press.wav\", ...props }: MacKeyboardProps) {\n  const [activeKeys, setActiveKeys] = React.useState<Set<string>>(new Set());\n  const audioCtxRef = React.useRef<AudioContext | null>(null);\n  const audioBufferRef = React.useRef<AudioBuffer | null>(null);\n\n  React.useEffect(() => {\n    if (!soundSrc) return;\n    // Use Web Audio API for low-latency, short key click sounds\n    const ctx = new (window.AudioContext || (window as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext)();\n    audioCtxRef.current = ctx;\n\n    fetch(soundSrc)\n      .then((res) => res.arrayBuffer())\n      .then((buf) => ctx.decodeAudioData(buf))\n      .then((decoded) => { audioBufferRef.current = decoded; })\n      .catch(() => {}); // Silently fail if audio can't load\n\n    return () => { ctx.close().catch(() => {}); };\n  }, [soundSrc]);\n\n  const playClick = React.useCallback(() => {\n    const ctx = audioCtxRef.current;\n    const buffer = audioBufferRef.current;\n    if (!ctx || !buffer) return;\n\n    const play = () => {\n      const source = ctx.createBufferSource();\n      source.buffer = buffer;\n\n      const gain = ctx.createGain();\n      gain.gain.value = 0.15; // Set volume very low (15%) so it's a subtle click\n\n      source.connect(gain);\n      gain.connect(ctx.destination);\n      source.start(0);\n    };\n\n    if (ctx.state === \"suspended\") {\n      ctx.resume().then(play).catch(() => {});\n    } else {\n      play();\n    }\n  }, []);\n\n  React.useEffect(() => {\n    const handleKeyDown = (e: KeyboardEvent) => {\n      if (e.repeat) return;\n\n      setActiveKeys((prev) => {\n        const newSet = new Set(prev);\n        newSet.add(e.code);\n        return newSet;\n      });\n\n      playClick();\n    };\n\n    const handleKeyUp = (e: KeyboardEvent) => {\n      setActiveKeys((prev) => {\n        const newSet = new Set(prev);\n        newSet.delete(e.code);\n        return newSet;\n      });\n    };\n\n    window.addEventListener(\"keydown\", handleKeyDown);\n    window.addEventListener(\"keyup\", handleKeyUp);\n    return () => {\n      window.removeEventListener(\"keydown\", handleKeyDown);\n      window.removeEventListener(\"keyup\", handleKeyUp);\n    };\n  }, [playClick]);\n\n  return (\n    <KeyboardContext.Provider value={{ activeKeys }}>\n      {props.children ? (\n        <div \n          className={cn(\n            \"inline-flex items-center gap-1.5 rounded-[1.5rem] bg-neutral-200 p-3 shadow-2xl dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-800\", \n            className\n          )} \n          {...props}\n        >\n          {props.children}\n        </div>\n      ) : (\n        <div\n          className={cn(\n            \"flex w-full min-w-[800px] max-w-5xl shrink-0 flex-col gap-2 rounded-[1.5rem] bg-neutral-200 p-3 shadow-2xl dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-800\",\n            className\n          )}\n          style={{ minWidth: \"800px\" }}\n          {...props}\n        >\n          {/* Row 1: Esc, F1-F12, Touch ID */}\n          <Row>\n            <MacKey width={1.5} keyCode=\"Escape\" className=\"text-[10px] items-start pl-3\">esc</MacKey>\n            <MacKey width={1} keyCode=\"F1\" icon={<Sun className=\"h-4 w-4\" />} iconLabel=\"F1\" />\n            <MacKey width={1} keyCode=\"F2\" icon={<Sun className=\"h-4 w-4\" />} iconLabel=\"F2\" />\n            <MacKey width={1} keyCode=\"F3\" icon={<LayoutGrid className=\"h-4 w-4\" />} iconLabel=\"F3\" />\n            <MacKey width={1} keyCode=\"F4\" icon={<Search className=\"h-4 w-4\" />} iconLabel=\"F4\" />\n            <MacKey width={1} keyCode=\"F5\" icon={<Mic className=\"h-4 w-4\" />} iconLabel=\"F5\" />\n            <MacKey width={1} keyCode=\"F6\" icon={<Moon className=\"h-4 w-4\" />} iconLabel=\"F6\" />\n            <MacKey width={1} keyCode=\"F7\" icon={<SkipBack className=\"h-4 w-4 fill-current\" />} iconLabel=\"F7\" />\n            <MacKey width={1} keyCode=\"F8\" icon={<Play className=\"h-4 w-4 fill-current\" />} iconLabel=\"F8\" />\n            <MacKey width={1} keyCode=\"F9\" icon={<SkipForward className=\"h-4 w-4 fill-current\" />} iconLabel=\"F9\" />\n            <MacKey width={1} keyCode=\"F10\" icon={<VolumeX className=\"h-4 w-4\" />} iconLabel=\"F10\" />\n            <MacKey width={1} keyCode=\"F11\" icon={<Volume1 className=\"h-4 w-4\" />} iconLabel=\"F11\" />\n            <MacKey width={1} keyCode=\"F12\" icon={<Volume2 className=\"h-4 w-4\" />} iconLabel=\"F12\" />\n            <MacKey width={1} icon={<Lock className=\"h-4 w-4\" />} />\n          </Row>\n\n      {/* Row 2: Numbers */}\n      <Row>\n        <MacKey width={1} label=\"`\" subLabel=\"~\" />\n        <MacKey width={1} label=\"1\" subLabel=\"!\" />\n        <MacKey width={1} label=\"2\" subLabel=\"@\" />\n        <MacKey width={1} label=\"3\" subLabel=\"#\" />\n        <MacKey width={1} label=\"4\" subLabel=\"$\" />\n        <MacKey width={1} label=\"5\" subLabel=\"%\" />\n        <MacKey width={1} label=\"6\" subLabel=\"^\" />\n        <MacKey width={1} label=\"7\" subLabel=\"&\" />\n        <MacKey width={1} label=\"8\" subLabel=\"*\" />\n        <MacKey width={1} label=\"9\" subLabel=\"(\" />\n        <MacKey width={1} label=\"0\" subLabel=\")\" />\n        <MacKey width={1} label=\"-\" subLabel=\"_\" />\n        <MacKey width={1} label=\"=\" subLabel=\"+\" />\n        <MacKey width={1.5} className=\"items-end pr-2 text-xs\" label=\"delete\" />\n      </Row>\n\n      {/* Row 3: Tab */}\n      <Row>\n        <MacKey width={1.5} className=\"items-start pl-3 text-xs\" label=\"tab\" />\n        <MacKey width={1} label=\"Q\" />\n        <MacKey width={1} label=\"W\" />\n        <MacKey width={1} label=\"E\" />\n        <MacKey width={1} label=\"R\" />\n        <MacKey width={1} label=\"T\" />\n        <MacKey width={1} label=\"Y\" />\n        <MacKey width={1} label=\"U\" />\n        <MacKey width={1} label=\"I\" />\n        <MacKey width={1} label=\"O\" />\n        <MacKey width={1} label=\"P\" />\n        <MacKey width={1} label=\"[\" subLabel=\"{\" />\n        <MacKey width={1} label=\"]\" subLabel=\"}\" />\n        <MacKey width={1} label=\"\\\" subLabel=\"|\" />\n      </Row>\n\n      {/* Row 4: Caps */}\n      <Row>\n        <MacKey width={1.75} className=\"items-start pl-3 text-xs relative group\" label=\"\">\n           <span className=\"z-10 mt-0.5\">caps lock</span>\n           <div className=\"absolute left-2 top-2 h-1.5 w-1.5 rounded-full bg-neutral-900/20 group-active:bg-green-500 transition-colors dark:bg-white/20\" />\n        </MacKey>\n        <MacKey width={1} label=\"A\" />\n        <MacKey width={1} label=\"S\" />\n        <MacKey width={1} label=\"D\" />\n        <MacKey width={1} label=\"F\" />\n        <MacKey width={1} label=\"G\" />\n        <MacKey width={1} label=\"H\" />\n        <MacKey width={1} label=\"J\" />\n        <MacKey width={1} label=\"K\" />\n        <MacKey width={1} label=\"L\" />\n        <MacKey width={1} label=\";\" subLabel=\":\" />\n        <MacKey width={1} label=\"'\" subLabel='\"' />\n        <MacKey width={1.75} className=\"items-end pr-2 text-xs\" label=\"return\" />\n      </Row>\n\n      {/* Row 5: Shift */}\n      <Row>\n        <MacKey width={2.25} keyCode=\"ShiftLeft\" className=\"items-start pl-3 text-xs\" label=\"shift\" />\n        <MacKey width={1} label=\"Z\" />\n        <MacKey width={1} label=\"X\" />\n        <MacKey width={1} label=\"C\" />\n        <MacKey width={1} label=\"V\" />\n        <MacKey width={1} label=\"B\" />\n        <MacKey width={1} label=\"N\" />\n        <MacKey width={1} label=\"M\" />\n        <MacKey width={1} label=\",\" subLabel=\"<\" />\n        <MacKey width={1} label=\".\" subLabel=\">\" />\n        <MacKey width={1} label=\"/\" subLabel=\"?\" />\n        <MacKey width={2.25} keyCode=\"ShiftRight\" className=\"items-end pr-2 text-xs\" label=\"shift\" />\n      </Row>\n\n      {/* Row 6: Bottom */}\n      <Row>\n        <MacKey\n          width={1}\n          className=\"items-end pr-1 pb-1\"\n          label={<span className=\"text-[10px] font-normal\">fn</span>}\n        >\n          <Globe className=\"absolute top-2 left-2 h-4 w-4\" />\n        </MacKey>\n        <MacKey\n          width={1}\n          keyCode=\"ControlLeft\"\n          className=\"items-end pr-1 pb-1\"\n          label={<span className=\"text-[10px] font-normal\">control</span>}\n        >\n          <ChevronUp className=\"absolute top-2 left-2 h-4 w-4\" />\n        </MacKey>\n        <MacKey\n          width={1.25}\n          keyCode=\"AltLeft\"\n          className=\"items-end pr-1 pb-1\"\n          label={<span className=\"text-[10px] font-normal\">option</span>}\n        >\n          <Option className=\"absolute top-2 left-2 h-4 w-4\" />\n        </MacKey>\n        <MacKey\n          width={1.5}\n          keyCode=\"MetaLeft\"\n          className=\"items-end pr-1 pb-1\"\n          label={<span className=\"text-[10px] font-bold\">command</span>}\n        >\n          <Command className=\"absolute top-2 left-2 h-4 w-4\" />\n        </MacKey>\n        {/* Spacebar */}\n        <MacKey width={4} keyCode=\"Space\" /> \n        <MacKey\n          width={1.5}\n          keyCode=\"MetaRight\"\n          className=\"items-end pl-1 pb-1\"\n          label={<span className=\"text-[10px] font-bold\">command</span>}\n        >\n           <Command className=\"absolute top-2 right-2 h-4 w-4\" />\n        </MacKey>\n        <MacKey\n          width={1.25}\n          keyCode=\"AltRight\"\n          className=\"items-end pl-1 pb-1\"\n          label={<span className=\"text-[10px] font-normal\">option</span>}\n        >\n           <Option className=\"absolute top-2 right-2 h-4 w-4\" />\n        </MacKey>\n        \n        {/* Arrow keys */}\n        <div style={{ flex: 3 }} className=\"grid h-full grid-cols-3 items-end gap-1.5 pl-0.5\">\n          <MacKey width={1} keyCode=\"ArrowLeft\" className=\"h-full\">\n            <ArrowLeft className=\"h-4 w-4\" />\n          </MacKey>\n          <div className=\"flex h-full min-h-0 flex-col gap-1.5\">\n            <MacKey\n              width={1}\n              noAspectRatio\n              keyCode=\"ArrowUp\"\n              style={{ flex: 1 }}\n              className=\"!min-h-0 items-center justify-center p-0 !rounded-[4px] shadow-[0_1px_0_1px_rgba(0,0,0,0.1)]\"\n            >\n              <ArrowUp className=\"h-3 w-3\" />\n            </MacKey>\n            <MacKey\n              width={1}\n              noAspectRatio\n              keyCode=\"ArrowDown\"\n              style={{ flex: 1 }}\n              className=\"!min-h-0 items-center justify-center p-0 !rounded-[4px] shadow-[0_1px_0_1px_rgba(0,0,0,0.1)]\"\n            >\n              <ArrowDown className=\"h-3 w-3\" />\n            </MacKey>\n          </div>\n          <MacKey width={1} keyCode=\"ArrowRight\" className=\"h-full\">\n            <ArrowRight className=\"h-4 w-4\" />\n          </MacKey>\n        </div>\n      </Row>\n        </div>\n      )}\n    </KeyboardContext.Provider>\n  );\n}\n\nfunction Row({ children }: { children: React.ReactNode }) {\n  return <div className=\"flex w-full gap-1.5\">{children}</div>;\n}\n\nexport function MacKey({\n  className,\n  label,\n  subLabel,\n  icon,\n  iconLabel,\n  width = 1,\n  children,\n  keyCode,\n  noAspectRatio,\n  ...props\n}: MacKeyProps) {\n  const { activeKeys } = React.useContext(KeyboardContext);\n\n  const isActive = React.useMemo(() => {\n    // 1. Check explicit keyCode prop\n    if (keyCode) {\n      if (Array.isArray(keyCode)) {\n        return keyCode.some((code) => activeKeys.has(code));\n      }\n      return activeKeys.has(keyCode);\n    }\n\n    // 2. Try to infer from label (simple cases)\n    if (typeof label === \"string\") {\n      const l = label.toLowerCase();\n      \n      // Numbers\n      if (/^[0-9]$/.test(l)) return activeKeys.has(`Digit${l}`);\n      \n      // Letters\n      if (/^[a-z]$/.test(l)) return activeKeys.has(`Key${l.toUpperCase()}`);\n\n      // Common symbols\n      const symbolMap: Record<string, string> = {\n        \"-\": \"Minus\",\n        \"=\": \"Equal\",\n        \"[\": \"BracketLeft\",\n        \"]\": \"BracketRight\",\n        \"\\\\\": \"Backslash\",\n        \";\": \"Semicolon\",\n        \"'\": \"Quote\",\n        \",\": \"Comma\",\n        \".\": \"Period\",\n        \"/\": \"Slash\",\n        \"`\": \"Backquote\",\n        \"delete\": \"Backspace\",\n        \"tab\": \"Tab\", \n        \"caps lock\": \"CapsLock\",\n        \"return\": \"Enter\",\n        \"space\": \"Space\"\n      };\n      \n      if (symbolMap[l]) return activeKeys.has(symbolMap[l]);\n    }\n    \n    return false;\n  }, [activeKeys, keyCode, label]);\n\n  // For width=1 keys, use aspect-ratio to define the row height.\n  // For wider keys, omit aspect-ratio so they stretch to the row height via align-items: stretch.\n  const applyAspectRatio = !noAspectRatio;\n  return (\n    <div\n      style={{\n        flex: width,\n        ...(applyAspectRatio ? { aspectRatio: `${width}/1` } : {}),\n      }}\n      className=\"min-w-0 self-stretch\"\n    >\n      <div\n        className={cn(\n          \"group relative flex h-full w-full min-w-0 select-none flex-col items-center justify-center overflow-hidden rounded-lg bg-white\",\n          // Light mode shadows\n          \"shadow-[inset_0_-2px_1px_rgba(0,0,0,0.05),inset_0_1px_1px_rgba(255,255,255,1),0_1px_1px_rgba(0,0,0,0.1)]\",\n          // Dark mode overrides\n          \"dark:bg-neutral-800 dark:shadow-[inset_0_-2px_1px_rgba(0,0,0,0.4),inset_0_1px_1px_rgba(255,255,255,0.05),0_1px_1px_rgba(0,0,0,0.5)]\",\n          // Active state styles - mimicking the active: pseudo-class but triggered by state\n          isActive && \"translate-y-[1px] shadow-none scale-[0.98]\",\n          \"active:translate-y-[1px] active:shadow-none transition-all duration-100 active:scale-[0.98]\",\n          className\n        )}\n        {...props}\n      >\n        {/* Icon only keys (F-keys) */}\n        {icon && !label && !subLabel && !children && (\n           <div className=\"flex flex-col items-center justify-between h-full py-2\">\n              <span className=\"text-[15px]\">{icon}</span>\n              {iconLabel && <span className=\"text-[7px] leading-none opacity-60 font-medium\">{iconLabel}</span>}\n           </div>\n        )}\n\n        {/* Number/Symbol keys */}\n        {subLabel && (\n          <div className=\"flex flex-col items-center justify-between h-full py-2\">\n             <span className=\"text-xs font-normal opacity-60\">{subLabel}</span>\n             <span className=\"text-sm font-medium\">{label}</span>\n          </div>\n        )}\n        \n        {/* Letter keys */}\n        {!subLabel && !icon && typeof label === \"string\" && label.length === 1 && (\n          <span className=\"text-lg font-medium\">{label}</span>\n        )}\n\n        {/* Modifier keys with text label */}\n        {!subLabel && !icon && (typeof label !== \"string\" || label.length > 1) && !children && (\n          <span className=\"font-medium text-xs\">{label}</span>\n        )}\n        \n        {children}\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}