{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "keyboard-shortcut",
  "title": "Keyboard Shortcut",
  "description": "A platform-aware key-combination hint with accessible labels and a reusable listener hook.",
  "files": [
    {
      "path": "registry/rivetui/components/keyboard-shortcut/keyboard-shortcut.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype KeyboardShortcutKeyName =\n  | \"mod\"\n  | \"command\"\n  | \"control\"\n  | \"option\"\n  | \"shift\"\n  | \"enter\"\n  | \"escape\"\n  | \"tab\"\n  | \"space\"\n  | \"backspace\"\n  | \"delete\"\n  | \"arrow-up\"\n  | \"arrow-down\"\n  | \"arrow-left\"\n  | \"arrow-right\";\n\ntype KeyboardShortcutKey = KeyboardShortcutKeyName | (string & Record<never, never>);\ntype KeyboardShortcutKeys = readonly [KeyboardShortcutKey, ...KeyboardShortcutKey[]];\ntype KeyboardShortcutPlatform = \"auto\" | \"mac\" | \"windows\" | \"linux\";\ntype ResolvedPlatform = Exclude<KeyboardShortcutPlatform, \"auto\"> | \"unknown\";\n\ntype KeyboardShortcutProps = Omit<React.ComponentProps<\"kbd\">, \"children\"> & {\n  keys: KeyboardShortcutKeys;\n  platform?: KeyboardShortcutPlatform;\n  size?: \"sm\" | \"md\";\n};\n\ntype UseKeyboardShortcutOptions = {\n  allowInEditable?: boolean;\n  allowRepeat?: boolean;\n  enabled?: boolean;\n  platform?: KeyboardShortcutPlatform;\n  preventDefault?: boolean;\n};\n\ntype KeyDefinition = {\n  label: string;\n  symbol: string;\n};\n\nconst keyDefinitions: Record<string, KeyDefinition> = {\n  shift: { label: \"Shift\", symbol: \"⇧\" },\n  enter: { label: \"Enter\", symbol: \"↵\" },\n  return: { label: \"Enter\", symbol: \"↵\" },\n  escape: { label: \"Escape\", symbol: \"Esc\" },\n  esc: { label: \"Escape\", symbol: \"Esc\" },\n  tab: { label: \"Tab\", symbol: \"⇥\" },\n  space: { label: \"Space\", symbol: \"Space\" },\n  backspace: { label: \"Backspace\", symbol: \"⌫\" },\n  delete: { label: \"Delete\", symbol: \"⌦\" },\n  \"arrow-up\": { label: \"Arrow up\", symbol: \"↑\" },\n  \"arrow-down\": { label: \"Arrow down\", symbol: \"↓\" },\n  \"arrow-left\": { label: \"Arrow left\", symbol: \"←\" },\n  \"arrow-right\": { label: \"Arrow right\", symbol: \"→\" },\n};\n\nconst modifierKeys = new Set([\n  \"mod\",\n  \"command\",\n  \"cmd\",\n  \"meta\",\n  \"control\",\n  \"ctrl\",\n  \"option\",\n  \"alt\",\n  \"shift\",\n]);\nconst primaryModifierKeys = new Set([\"mod\", \"command\", \"cmd\"]);\nconst controlKeys = new Set([\"control\", \"ctrl\"]);\nconst optionKeys = new Set([\"option\", \"alt\"]);\nconst eventKeyAliases: Record<string, string> = {\n  \" \": \"space\",\n  arrowdown: \"arrow-down\",\n  arrowleft: \"arrow-left\",\n  arrowright: \"arrow-right\",\n  arrowup: \"arrow-up\",\n  esc: \"escape\",\n  return: \"enter\",\n};\nconst keydownSubscribers = new Set<(event: KeyboardEvent) => void>();\n\nfunction subscribeToPlatform() {\n  return () => undefined;\n}\n\nfunction dispatchKeydown(event: KeyboardEvent) {\n  for (const subscriber of keydownSubscribers) {\n    subscriber(event);\n  }\n}\n\nfunction subscribeToKeydown(subscriber: (event: KeyboardEvent) => void) {\n  keydownSubscribers.add(subscriber);\n  if (keydownSubscribers.size === 1) {\n    window.addEventListener(\"keydown\", dispatchKeydown);\n  }\n\n  return () => {\n    keydownSubscribers.delete(subscriber);\n    if (keydownSubscribers.size === 0) {\n      window.removeEventListener(\"keydown\", dispatchKeydown);\n    }\n  };\n}\n\nfunction detectPlatform(): ResolvedPlatform {\n  if (typeof navigator === \"undefined\") {\n    return \"unknown\";\n  }\n\n  const navigatorWithHints = navigator as Navigator & {\n    userAgentData?: { platform?: string };\n  };\n  const platform = [\n    navigatorWithHints.userAgentData?.platform,\n    navigator.platform,\n    navigator.userAgent,\n  ]\n    .filter(Boolean)\n    .join(\" \")\n    .toLowerCase();\n\n  if (/mac|iphone|ipad|ipod/.test(platform)) {\n    return \"mac\";\n  }\n  if (platform.includes(\"win\")) {\n    return \"windows\";\n  }\n  if (/linux|android/.test(platform)) {\n    return \"linux\";\n  }\n  return \"unknown\";\n}\n\nfunction useResolvedPlatform(platform: KeyboardShortcutPlatform): ResolvedPlatform {\n  const detectedPlatform = React.useSyncExternalStore<ResolvedPlatform>(\n    subscribeToPlatform,\n    detectPlatform,\n    (): ResolvedPlatform => \"unknown\",\n  );\n\n  return platform === \"auto\" ? detectedPlatform : platform;\n}\n\nfunction getKeyDefinition(key: KeyboardShortcutKey, platform: ResolvedPlatform): KeyDefinition {\n  const normalizedKey = key.trim().toLowerCase();\n  const isMac = platform === \"mac\";\n\n  if (primaryModifierKeys.has(normalizedKey)) {\n    if (platform === \"unknown\") {\n      return { label: \"Modifier\", symbol: \"Mod\" };\n    }\n    return isMac ? { label: \"Command\", symbol: \"⌘\" } : { label: \"Control\", symbol: \"Ctrl\" };\n  }\n  if (normalizedKey === \"meta\") {\n    return isMac ? { label: \"Command\", symbol: \"⌘\" } : { label: \"Meta\", symbol: \"Meta\" };\n  }\n  if (controlKeys.has(normalizedKey)) {\n    return isMac ? { label: \"Control\", symbol: \"⌃\" } : { label: \"Control\", symbol: \"Ctrl\" };\n  }\n  if (optionKeys.has(normalizedKey)) {\n    return isMac ? { label: \"Option\", symbol: \"⌥\" } : { label: \"Alt\", symbol: \"Alt\" };\n  }\n  if (normalizedKey === \"shift\") {\n    return isMac ? { label: \"Shift\", symbol: \"⇧\" } : { label: \"Shift\", symbol: \"Shift\" };\n  }\n\n  return keyDefinitions[normalizedKey] ?? { label: key, symbol: key };\n}\n\nfunction getShortcutItems(keys: KeyboardShortcutKeys, platform: ResolvedPlatform) {\n  const occurrences = new Map<string, number>();\n\n  return keys.map((key) => {\n    const normalizedKey = key.trim().toLowerCase();\n    const definition = getKeyDefinition(key, platform);\n    const occurrence = (occurrences.get(normalizedKey) ?? 0) + 1;\n    occurrences.set(normalizedKey, occurrence);\n\n    return {\n      ...definition,\n      id: `${normalizedKey}-${occurrence}`,\n      isLiteralKey: !keyDefinitions[normalizedKey] && !modifierKeys.has(normalizedKey),\n      isMacModifier: platform === \"mac\" && modifierKeys.has(normalizedKey),\n    };\n  });\n}\n\nfunction normalizeEventKey(key: string) {\n  const normalizedKey = key.toLowerCase();\n  return eventKeyAliases[normalizedKey] ?? normalizedKey;\n}\n\nfunction matchesShortcut(\n  event: KeyboardEvent,\n  keys: readonly string[],\n  platform: ResolvedPlatform,\n) {\n  const normalizedKeys = keys.map((key) => key.trim().toLowerCase());\n  const primaryModifier = platform === \"mac\" ? \"meta\" : \"control\";\n  let requiresMeta = false;\n  let requiresControl = false;\n  let requiresAlt = false;\n  let requiresShift = false;\n\n  for (const key of normalizedKeys) {\n    if (primaryModifierKeys.has(key)) {\n      requiresMeta ||= primaryModifier === \"meta\";\n      requiresControl ||= primaryModifier === \"control\";\n    } else if (key === \"meta\") {\n      requiresMeta = true;\n    } else if (controlKeys.has(key)) {\n      requiresControl = true;\n    } else if (optionKeys.has(key)) {\n      requiresAlt = true;\n    } else if (key === \"shift\") {\n      requiresShift = true;\n    }\n  }\n\n  const triggerKeys = normalizedKeys.filter((key) => !modifierKeys.has(key));\n  if (triggerKeys.length !== 1 || normalizeEventKey(event.key) !== triggerKeys[0]) {\n    return false;\n  }\n\n  return (\n    event.metaKey === requiresMeta &&\n    event.ctrlKey === requiresControl &&\n    event.altKey === requiresAlt &&\n    event.shiftKey === requiresShift\n  );\n}\n\nfunction isEditableTarget(target: EventTarget | null) {\n  return (\n    target instanceof HTMLElement &&\n    (target.isContentEditable || [\"INPUT\", \"SELECT\", \"TEXTAREA\"].includes(target.tagName))\n  );\n}\n\nfunction useKeyboardShortcut(\n  keys: KeyboardShortcutKeys,\n  onTrigger: (event: KeyboardEvent) => void,\n  {\n    allowInEditable = false,\n    allowRepeat = false,\n    enabled = true,\n    platform = \"auto\",\n    preventDefault = true,\n  }: UseKeyboardShortcutOptions = {},\n) {\n  const resolvedPlatform = useResolvedPlatform(platform);\n  const onTriggerRef = React.useRef(onTrigger);\n  const shortcutSignature = keys.map((key) => key.trim().toLowerCase()).join(\"\\u001f\");\n\n  React.useEffect(() => {\n    onTriggerRef.current = onTrigger;\n  }, [onTrigger]);\n\n  React.useEffect(() => {\n    if (!enabled) {\n      return;\n    }\n\n    const shortcutKeys = shortcutSignature.split(\"\\u001f\");\n\n    function handleKeyDown(event: KeyboardEvent) {\n      if (\n        (!allowRepeat && event.repeat) ||\n        (!allowInEditable && isEditableTarget(event.target)) ||\n        !matchesShortcut(event, shortcutKeys, resolvedPlatform)\n      ) {\n        return;\n      }\n\n      if (preventDefault) {\n        event.preventDefault();\n      }\n      onTriggerRef.current(event);\n    }\n\n    return subscribeToKeydown(handleKeyDown);\n  }, [allowInEditable, allowRepeat, enabled, preventDefault, resolvedPlatform, shortcutSignature]);\n}\n\nfunction KeyboardShortcut({\n  keys,\n  platform = \"auto\",\n  size = \"md\",\n  className,\n  \"aria-label\": ariaLabel,\n  ...props\n}: KeyboardShortcutProps) {\n  const resolvedPlatform = useResolvedPlatform(platform);\n  const items = getShortcutItems(keys, resolvedPlatform);\n\n  return (\n    <kbd\n      data-slot=\"keyboard-shortcut\"\n      data-platform={resolvedPlatform}\n      data-size={size}\n      aria-label={ariaLabel ?? items.map((item) => item.label).join(\" plus \")}\n      className={cn(\n        \"inline-flex shrink-0 overflow-hidden border border-border bg-muted/30 align-middle text-muted-foreground\",\n        className,\n      )}\n      {...props}\n    >\n      {platform === \"auto\" ? (\n        <>\n          <span\n            data-platform-variant=\"non-mac\"\n            aria-hidden=\"true\"\n            className=\"contents [[data-rivet-platform=mac]_&]:hidden\"\n          >\n            <KeyboardShortcutKeys keys={keys} platform=\"windows\" size={size} />\n          </span>\n          <span\n            data-platform-variant=\"mac\"\n            aria-hidden=\"true\"\n            className=\"hidden [[data-rivet-platform=mac]_&]:contents\"\n          >\n            <KeyboardShortcutKeys keys={keys} platform=\"mac\" size={size} />\n          </span>\n        </>\n      ) : (\n        <KeyboardShortcutKeys keys={keys} platform={platform} size={size} />\n      )}\n    </kbd>\n  );\n}\n\nfunction KeyboardShortcutKeys({\n  keys,\n  platform,\n  size,\n}: {\n  keys: KeyboardShortcutKeys;\n  platform: Exclude<KeyboardShortcutPlatform, \"auto\">;\n  size: NonNullable<KeyboardShortcutProps[\"size\"]>;\n}) {\n  const items = getShortcutItems(keys, platform);\n\n  return items.map((item) => (\n    <span\n      key={item.id}\n      data-slot=\"keyboard-shortcut-key\"\n      aria-hidden=\"true\"\n      className={cn(\n        \"inline-flex items-center justify-center border-l border-border font-mono font-medium uppercase leading-none first:border-l-0\",\n        size === \"sm\" ? \"h-5 min-w-5 px-1 text-[0.625rem]\" : \"h-7 min-w-7 px-1.5 text-[0.6875rem]\",\n        (item.isMacModifier || item.isLiteralKey) &&\n          \"font-sans font-semibold normal-case antialiased [font-family:system-ui,sans-serif]\",\n        item.isMacModifier && (size === \"sm\" ? \"text-[0.8125rem]\" : \"text-[0.9375rem]\"),\n        item.isLiteralKey && (size === \"sm\" ? \"text-xs\" : \"text-[0.8125rem]\"),\n      )}\n    >\n      <span className=\"inline-flex translate-y-px\">{item.symbol}</span>\n    </span>\n  ));\n}\n\nexport type {\n  KeyboardShortcutKey,\n  KeyboardShortcutKeyName,\n  KeyboardShortcutKeys,\n  KeyboardShortcutPlatform,\n  KeyboardShortcutProps,\n  UseKeyboardShortcutOptions,\n};\nexport { KeyboardShortcut, useKeyboardShortcut };\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/rivetui/components/keyboard-shortcut/keyboard-shortcut-script.tsx",
      "content": "type KeyboardShortcutScriptProps = {\n  nonce?: string;\n};\n\nfunction KeyboardShortcutScript({ nonce }: KeyboardShortcutScriptProps) {\n  const script = `try{var n=navigator;var h=n.userAgentData&&n.userAgentData.platform;var s=[h,n.platform,n.userAgent].filter(Boolean).join(\" \").toLowerCase();var p=/mac|iphone|ipad|ipod/.test(s)?\"mac\":s.includes(\"win\")?\"windows\":/linux|android/.test(s)?\"linux\":\"unknown\";document.documentElement.dataset.rivetPlatform=p}catch(e){}`;\n\n  return (\n    <script\n      id=\"rivet-ui-platform\"\n      nonce={nonce}\n      // biome-ignore lint/security/noDangerouslySetInnerHtml: The script is static and contains no consumer-controlled values.\n      dangerouslySetInnerHTML={{ __html: script }}\n    />\n  );\n}\n\nexport type { KeyboardShortcutScriptProps };\nexport { KeyboardShortcutScript };\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}