{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"kbd","type":"registry:ui","title":"Kbd","description":"A key or a shortcut as on a keyboard: ⌘ K on a Mac, Ctrl K elsewhere, read out as words.","dependencies":[],"registryDependencies":["https://dashral.com/r/utils.json"],"files":[{"path":"registry/dashral/kbd.tsx","type":"registry:file","target":"components/dashral/kbd.tsx","content":"\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\n\ntype KbdSize = \"sm\" | \"default\"\n\n/** How a named key shows and is read out, on an Apple keyboard and elsewhere. */\nconst named: Record<string, { mac: string; other: string; macName: string; otherName: string }> = {\n  mod: { mac: \"⌘\", other: \"Ctrl\", macName: \"Command\", otherName: \"Control\" },\n  cmd: { mac: \"⌘\", other: \"⌘\", macName: \"Command\", otherName: \"Command\" },\n  ctrl: { mac: \"⌃\", other: \"Ctrl\", macName: \"Control\", otherName: \"Control\" },\n  alt: { mac: \"⌥\", other: \"Alt\", macName: \"Option\", otherName: \"Alt\" },\n  shift: { mac: \"⇧\", other: \"Shift\", macName: \"Shift\", otherName: \"Shift\" },\n  enter: { mac: \"↵\", other: \"Enter\", macName: \"Return\", otherName: \"Enter\" },\n  esc: { mac: \"Esc\", other: \"Esc\", macName: \"Escape\", otherName: \"Escape\" },\n  tab: { mac: \"⇥\", other: \"Tab\", macName: \"Tab\", otherName: \"Tab\" },\n  backspace: { mac: \"⌫\", other: \"⌫\", macName: \"Delete\", otherName: \"Backspace\" },\n  space: { mac: \"Space\", other: \"Space\", macName: \"Space\", otherName: \"Space\" },\n  up: { mac: \"↑\", other: \"↑\", macName: \"Up arrow\", otherName: \"Up arrow\" },\n  down: { mac: \"↓\", other: \"↓\", macName: \"Down arrow\", otherName: \"Down arrow\" },\n  left: { mac: \"←\", other: \"←\", macName: \"Left arrow\", otherName: \"Left arrow\" },\n  right: { mac: \"→\", other: \"→\", macName: \"Right arrow\", otherName: \"Right arrow\" },\n}\n\nconst noSubscribe = () => () => {}\n/** Whether this is an Apple device; on the server (and for the first paint) it guesses yes, as most of the kit's readers are. */\nfunction useAppleKeyboard() {\n  return React.useSyncExternalStore(\n    noSubscribe,\n    () => /Mac|iPhone|iPad|iPod/.test(navigator.platform || navigator.userAgent),\n    () => true\n  )\n}\n\n/** A key as it shows and as it's read out. */\nfunction describeKey(key: string, apple: boolean) {\n  const entry = named[key.toLowerCase()]\n  if (!entry) return { label: key.length === 1 ? key.toUpperCase() : key, name: key.length === 1 ? key.toUpperCase() : key }\n  return { label: apple ? entry.mac : entry.other, name: apple ? entry.macName : entry.otherName }\n}\n\n/** The classes for one key cap. */\nconst kbdKeyClass = (size: KbdSize) =>\n  cn(\n    \"inline-flex min-w-5 items-center justify-center rounded border border-b-2 bg-muted px-1 font-sans font-medium text-muted-foreground\",\n    size === \"sm\" ? \"h-5 text-[11px]\" : \"h-6 min-w-6 px-1.5 text-xs\"\n  )\n\ntype KbdProps = Omit<React.ComponentProps<\"kbd\">, \"children\"> & {\n  /**\n   * The keys of a shortcut, e.g. [\"mod\", \"K\"]. \"mod\" is ⌘ on a Mac and Ctrl elsewhere; \"shift\", \"alt\", \"ctrl\", \"enter\",\n   * \"esc\", \"tab\", \"backspace\", \"space\" and the arrows (\"up\"…) show as their symbols and are read out by name.\n   */\n  keys?: string[]\n  /** A single key, as text, when keys isn't given. */\n  children?: React.ReactNode\n  size?: KbdSize\n}\n\n/**\n * A key, or a shortcut of several, as on a keyboard: <Kbd keys={[\"mod\", \"K\"]} /> shows ⌘ K on a Mac and Ctrl K\n * elsewhere, and screen readers hear \"Command K\". Inside a button or a menu it says what the keys do the same as.\n */\nfunction Kbd({ keys, children, size = \"default\", className, ...props }: KbdProps) {\n  const apple = useAppleKeyboard()\n  if (!keys) {\n    return (\n      <kbd data-slot=\"kbd\" className={cn(kbdKeyClass(size), className)} {...props}>\n        {children}\n      </kbd>\n    )\n  }\n  const described = keys.map((key) => describeKey(key, apple))\n  return (\n    // Nested kbd for a combination, as HTML has it; read out as words (\"Command K\"), not symbols.\n    <kbd data-slot=\"kbd\" aria-label={described.map((key) => key.name).join(\" \")} className={cn(\"inline-flex items-center gap-1\", className)} {...props}>\n      {described.map((key, i) => (\n        <kbd key={i} aria-hidden className={kbdKeyClass(size)}>\n          {key.label}\n        </kbd>\n      ))}\n    </kbd>\n  )\n}\n\n// Building blocks for a Kbd of your own (the motion edition uses them).\nexport { Kbd, describeKey, useAppleKeyboard, kbdKeyClass, type KbdProps, type KbdSize }\n"}]}