{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "kbd",
  "title": "Kbd",
  "description": "A kbd component.",
  "dependencies": [
    "class-variance-authority"
  ],
  "files": [
    {
      "path": "registry/default/kbd/kbd.tsx",
      "content": "import * as React from \"react\";\r\nimport { cva, type VariantProps } from \"class-variance-authority\";\r\n\r\nimport { cn } from \"@/lib/utils\";\r\n\r\nconst kbdVariants = cva(\r\n  // `bg-clip-padding` on `default` only: the translucent border needs the bg\r\n  // clipped to the padding box to composite correctly. Colored variants use\r\n  // opaque borders; ghost has no bg, so it would leave a 1px substrate halo.\r\n  \"inline-flex items-center justify-center rounded-sm border text-center font-medium tracking-tight shadow-[0_1px_2px_0_oklch(0_0_0/0.06)] transition-colors duration-150 font-mono\",\r\n  {\r\n    variants: {\r\n      size: {\r\n        sm: \"h-5 min-w-5 px-1.5 text-xs\",\r\n        md: \"h-6 min-w-6 px-2 text-xs\",\r\n        lg: \"h-7 min-w-7 px-2.5 text-sm\",\r\n      },\r\n      variant: {\r\n        default: \"bg-card bg-clip-padding text-foreground\",\r\n        primary: \"bg-primary text-primary-foreground border-primary\",\r\n        secondary: \"bg-secondary text-secondary-foreground border-secondary\",\r\n        outline: \"bg-transparent text-foreground shadow-none\",\r\n        ghost: \"border-transparent bg-muted text-muted-foreground shadow-none\",\r\n        danger: \"bg-destructive text-destructive-foreground border-destructive\",\r\n      },\r\n      pressed: {\r\n        true: \"translate-y-px bg-muted shadow-none\",\r\n        false: \"\",\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      size: \"md\",\r\n      variant: \"default\",\r\n      pressed: false,\r\n    },\r\n  },\r\n);\r\n\r\nconst platformKeys = {\r\n  mac: {\r\n    cmd: \"⌘\",\r\n    option: \"⌥\",\r\n    alt: \"⌥\",\r\n    ctrl: \"⌃\",\r\n    shift: \"⇧\",\r\n    enter: \"↵\",\r\n    delete: \"⌫\",\r\n    backspace: \"⌫\",\r\n    escape: \"⎋\",\r\n    tab: \"⇥\",\r\n    space: \"⎵\",\r\n    up: \"↑\",\r\n    down: \"↓\",\r\n    left: \"←\",\r\n    right: \"→\",\r\n  },\r\n  windows: {\r\n    cmd: \"Ctrl\",\r\n    option: \"Alt\",\r\n    alt: \"Alt\",\r\n    ctrl: \"Ctrl\",\r\n    shift: \"Shift\",\r\n    enter: \"Enter\",\r\n    delete: \"Del\",\r\n    backspace: \"Backspace\",\r\n    escape: \"Esc\",\r\n    tab: \"Tab\",\r\n    space: \"Space\",\r\n    up: \"↑\",\r\n    down: \"↓\",\r\n    left: \"←\",\r\n    right: \"→\",\r\n  },\r\n};\r\n\r\nfunction useClientPlatform(): \"mac\" | \"windows\" {\r\n  const [platform, setPlatform] = React.useState<\"mac\" | \"windows\">(\"mac\");\r\n\r\n  React.useEffect(() => {\r\n    if (typeof navigator === \"undefined\") return;\r\n    // `navigator.platform` is deprecated; prefer userAgentData.platform\r\n    // (Chromium) with userAgent string as the universal fallback.\r\n    const uaData = (\r\n      navigator as Navigator & { userAgentData?: { platform?: string } }\r\n    ).userAgentData;\r\n    const platformHint = uaData?.platform ?? navigator.userAgent;\r\n    setPlatform(/mac/i.test(platformHint) ? \"mac\" : \"windows\");\r\n  }, []);\r\n\r\n  return platform;\r\n}\r\n\r\nexport interface KbdProps\r\n  extends React.ComponentProps<\"kbd\">, VariantProps<typeof kbdVariants> {\r\n  keys?: string[];\r\n  separator?: string;\r\n  platform?: \"mac\" | \"windows\" | \"auto\";\r\n  disabled?: boolean;\r\n  \"aria-label\"?: string;\r\n}\r\n\r\nfunction Kbd({\r\n  className,\r\n  size,\r\n  variant,\r\n  pressed,\r\n  keys,\r\n  separator = \"+\",\r\n  platform = \"auto\",\r\n  disabled = false,\r\n  children,\r\n  \"aria-label\": ariaLabel,\r\n  ...props\r\n}: KbdProps) {\r\n  const clientPlatform = useClientPlatform();\r\n  const detectedPlatform = platform === \"auto\" ? clientPlatform : platform;\r\n  const keyMap = platformKeys[detectedPlatform];\r\n\r\n  const renderKey = (key: string) => {\r\n    const normalizedKey = key.toLowerCase();\r\n    return keyMap[normalizedKey as keyof typeof keyMap] || key;\r\n  };\r\n\r\n  const content = keys ? (\r\n    <span className=\"flex items-center gap-1\">\r\n      {keys.map((key, index) => (\r\n        <React.Fragment key={index}>\r\n          {index > 0 && (\r\n            <span className=\"text-muted-foreground text-xs font-normal\">\r\n              {separator}\r\n            </span>\r\n          )}\r\n          <span>{renderKey(key)}</span>\r\n        </React.Fragment>\r\n      ))}\r\n    </span>\r\n  ) : (\r\n    children\r\n  );\r\n\r\n  return (\r\n    <kbd\r\n      data-slot=\"kbd\"\r\n      className={cn(\r\n        kbdVariants({ size, variant, pressed }),\r\n        disabled && \"cursor-not-allowed opacity-60\",\r\n        className,\r\n      )}\r\n      aria-label={ariaLabel}\r\n      aria-disabled={disabled}\r\n      {...props}\r\n    >\r\n      {content}\r\n    </kbd>\r\n  );\r\n}\r\n\r\nexport { Kbd, kbdVariants };\r\n",
      "type": "registry:ui",
      "target": "components/ui/cubby-ui/kbd.tsx"
    }
  ],
  "type": "registry:ui"
}