<!-- Generated by scripts/gen-docs.mts from the JSDoc in registry/. Do not edit; run `pnpm run docs`. -->

# Kbd

A keyboard shortcut, in the reader's platform's notation: `keys={["mod", "k"]}` shows ⌘K on a Mac, iPhone or iPad and Ctrl+K elsewhere. Symbols carry their spoken name for screen readers. It sizes itself to the surrounding text, so it fits in a Menu item, a Tooltip or a sentence.

```tsx
import { Kbd } from "@/components/ouro/kbd/kbd";
```

## Example

```tsx
<Kbd keys={["mod", "k"]} />
<Text>Press <Kbd keys={["shift", "enter"]} /> for a new line.</Text>
```

## Usage

The server can't know the platform, so server HTML shows the key names (Ctrl+K) and Apple devices switch to the glyphs after hydration.

## Use instead when

- Use plain `Text` instead for a key named in prose that isn't a shortcut to press.

## Props

Type: `KbdProps`.

| Prop | Type | Description |
| --- | --- | --- |
| `className` | `string` | Layout only: margins (`ms-2`). Appearance classes warn in development; Kbd sizes itself to the surrounding text. |
| `keys` (required) | `readonly string[] \| (string & { 'Use an array: keys={["mod", "k"]}': never })` | The keys to press together, by name: `["mod", "k"]`. `mod` is ⌘ on Apple platforms and Ctrl elsewhere, the portable choice for an app shortcut. Modifier names: `mod`, `cmd` (`meta`: ⌘ on Apple, Win on Windows, Ctrl on Linux and ChromeOS), `ctrl`, `alt` (`option`), `shift`. Modifiers show in the platform's order (⌃⌥⇧⌘ on Apple, Win+Ctrl+Alt+Shift elsewhere), then the other keys as given. Other names: `enter`, `escape`, `tab`, `backspace`, `delete`, `space`, `up`, `down`, `left`, `right`. Any other string shows as written, a single letter in capitals. |
| `ref` | `Ref<HTMLElement>` | Reaches the rendered element. |

## Native attributes

Also accepts the attributes in React's `HTMLAttributes` (`id`, `aria-*`, event handlers), passed to the rendered element, except those named on this page.

## Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

- `children`: Not a prop. Kbd takes `keys`, so each platform gets the right glyphs: `<Kbd keys={["mod", "k"]} />`.
- `shortcut`: Not a prop. Ouro UI uses `keys`, an array: `<Kbd keys={["mod", "k"]} />`.

## `className` is for layout only

Pass margins, width and grid placement (`mt-4`, `w-full`, `col-span-2`). Your classes always win over Ouro UI's: Kbd merges `className` last with `cn` (tailwind-merge), so a class that conflicts with its own replaces it.[^layout-classes]

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (`hover:`, `sm:`) and any `!` are removed, it starts with `bg-`, `text-`, `border-`, `rounded-`, `shadow-`, `font-`, `ring-`, `from-`, `via-`, `to-`, `fill-` or `stroke-`, or is `border`, `rounded`, `shadow` or `ring`, or has a `dark:` variant. Text wrapping, overflow and table layout classes (`text-wrap`, `text-ellipsis`, `border-collapse`) are layout and do not warn.

Alignment classes (`text-center`) warn too: set alignment on a parent element.

[^layout-classes]: test:registry/ouro/components/ouro/kbd/kbd.test.tsx::Kbd > forwards a ref and lets app layout classes win verify:testExists(registry/ouro/components/ouro/kbd/kbd.test.tsx::Kbd > forwards a ref and lets app layout classes win)
