# Kbd Shortcut

> Labelled keyboard-shortcut hint (“Send ⌘↵”) that can also bind the shortcut and light its keys while pressed.

- **Slug:** `kbd-shortcut` · **Category:** input · **Status:** beta
- **Import:** `import { KbdShortcut } from "@kura-ui/react/kbd-shortcut";`
- **Docs:** https://kuro.abstergo.fyi/components/kbd-shortcut
- **Registry item:** https://kuro.abstergo.fyi/r/kbd-shortcut.json
- **Tags:** keyboard, shortcut, hotkey, hint, kbd, composer, accelerator

## Install

```bash
# shadcn registry (copies source into your project)
npx shadcn@latest add https://kuro.abstergo.fyi/r/kbd-shortcut.json
# Kura CLI (same, plus dependency resolution and --json output)
npx @kura-ui/cli add kbd-shortcut
# npm package
npm install @kura-ui/react
```

## When to use

- Hints under or inside a prompt composer: “⌘↵ to send”, “Esc to stop”.
- Advertise and bind a global shortcut in one element (e.g. ⌘K for search, ⌘J to toggle a panel).
- Empty states and onboarding that teach shortcuts.

## When not to use

- Showing a single key or combo without a label or binding — use kbd.
- A shortcut inside a tooltip — pass `shortcut` to tooltip or icon-button instead.
- Binding a shortcut with no visible hint — call the useHotkey hook directly.

## Props

| Prop | Type | Default | Required | Description |
| --- | --- | --- | --- | --- |
| `keys` | `readonly KeyName[]` | — | yes | The combo, e.g. ["mod", "enter"]. `mod` renders ⌘ on Apple platforms and Ctrl elsewhere. |
| `label` | `React.ReactNode` | — | no | Short action label shown before the keys, e.g. "Send". |
| `onTrigger` | `(event: KeyboardEvent) => void` | — | no | Bind the combo on `document` and call this when pressed. Omit for a display-only hint. |
| `enabled` | `boolean` | `true` | no | Enable/disable the binding without hiding the hint (renders dimmed when false). |
| `allowInInputs` | `boolean` | — | no | Fire while typing in inputs. Defaults to true only when the combo contains a modifier. |
| `variant` | `"raised" \| "ghost"` | `"raised"` | no | Keycap style. Use ghost inside buttons and dense toolbars. |
| `size` | `"sm" \| "md"` | `"sm"` | no | Keycap size. |

Native attributes of the root element, `className` and `ref` are passed through.

## Anatomy

- **KbdShortcut** (`data-slot="kbd-shortcut"`) — Wrapper; exposes `data-pressed` and `data-bound`.
- **Label** (`data-slot="kbd-shortcut-label"`) — Optional action label.
- **Kbd** (`data-slot="kbd"`) — The combo, rendered with the kbd primitive.

## Accessibility

- Renders a semantic <kbd> combo with visually hidden spoken text (e.g. “Command Enter”); individual glyphs are aria-hidden.
- The binding is global (document keydown); without a modifier it is ignored while the user types in inputs.
- It is a hint, not a control: the action must also be reachable by a focusable button.
- Reduced motion: The 1px key press travel is removed; colour change remains.

| Keys | Action |
| --- | --- |
| The configured combo | Calls onTrigger and shows the keys pressed |

## Notes for agents

- Use `mod` (not `meta`/`ctrl`) for the primary modifier so it is correct on every platform.
- Only one mounted KbdShortcut should bind a given combo; render the others display-only (no onTrigger).
- Key names follow KeyboardEvent.key plus aliases: mod, cmd, ctrl, alt/option, shift, enter, esc, up/down/left/right, space.

## Examples

### Display-only hint (minimal)

```tsx
import { KbdShortcut } from "@kura-ui/react/kbd-shortcut";

export function KbdShortcutMinimal() {
  return <KbdShortcut keys={["mod", "enter"]} label="Send" />;
}
```

### Bound shortcut (full)

Press the combo: the keys light up and a counter increments.

```tsx
"use client";

import * as React from "react";
import { KbdShortcut } from "@kura-ui/react/kbd-shortcut";

export function KbdShortcutFull() {
  const [count, setCount] = React.useState(0);
  return (
    <div className="flex flex-col items-center gap-3">
      <KbdShortcut
        keys={["mod", "j"]}
        label="Toggle panel"
        size="md"
        variant="raised"
        allowInInputs
        enabled
        onTrigger={() => setCount((c) => c + 1)}
      />
      <p className="text-kura-fg-muted text-xs tabular-nums" aria-live="polite">
        Triggered {count} {count === 1 ? "time" : "times"}
      </p>
    </div>
  );
}
```

### Composer footer hints (composition)

A row of hints as used under a prompt composer.

```tsx
import { KbdShortcut } from "@kura-ui/react/kbd-shortcut";

export function KbdShortcutComposerHints() {
  return (
    <div className="flex w-full max-w-md items-center justify-between rounded-kura-lg bg-kura-surface px-3 py-2 shadow-kura-sm">
      <div className="flex items-center gap-3">
        <KbdShortcut keys={["/"]} label="Commands" variant="ghost" />
        <KbdShortcut keys={["@"]} label="Context" variant="ghost" />
      </div>
      <KbdShortcut keys={["mod", "enter"]} label="Send" />
    </div>
  );
}
```

## Dependencies

- npm: none
- Kura registry items: `kura-theme`, `kbd`, `kura-keys`, `use-hotkey`, `utils`
- Related: `kbd`, `tooltip`, `icon-button`, `composer`, `command-palette`
