caliper uidocs

Kbd

Free

Keys as small raised caps: one shortcut per kbd, ⌘ on a Mac and Ctrl elsewhere, with spoken names for symbols.

Installs components/ui/kbd.tsxDepends on none beyond ReactMotion none in component source
pnpm dlx shadcn@latest add https://caliperui.site/r/kbd.json

Keyboard shortcuts

Search everything
Command K
New issue
C
Go to inbox
GthenI
Send comment
Command Enter
Move selection
Option Up arrow
Close panel
Escape

Press / anywhere to search. In a button the caps follow its colour:

When to use #

Use it for

  • A shortcut list, a menu row or a tooltip that teaches a key.
  • Inline help such as “press / to search”.

Skip it when

  • The keys do nothing yet; only show shortcuts your app handles.

Installation #

terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/kbd.json

Adds its 2 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

This is the code behind the preview above. It is built from Kbd, toAriaKeyshortcuts and useKbdPlatform.

example.tsx
import { useState } from "react"
import { Button } from "@/components/ui/button"
import { Kbd, type KbdPlatform } from "@/components/ui/kbd"
import { SegmentedControl } from "@/components/ui/segmented-control"

const shortcuts = [
  { action: "Search everything", keys: "mod+k" },
  { action: "New issue", keys: "c" },
  { action: "Go to inbox", keys: ["g", "i"], then: true },
  { action: "Send comment", keys: "mod+enter" },
  { action: "Move selection", keys: ["alt", "up"] },
  { action: "Close panel", keys: "esc" },
];

export function KbdDemo() {
  const [platform, setPlatform] = useState<KbdPlatform>("mac");
  return (
    <div className="grid w-full max-w-md gap-4">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <h3 className="text-sm font-semibold">Keyboard shortcuts</h3>
        <SegmentedControl label="Show keys for" value={platform} onValueChange={(value) => setPlatform(value as KbdPlatform)} options={[{ value: "mac", label: "Mac" }, { value: "other", label: "Windows" }]} />
      </div>
      <dl className="grid divide-y divide-border">
        {shortcuts.map((row) => (
          <div key={row.action} className="flex items-center justify-between gap-4 py-2.5">
            <dt className="text-sm text-muted-foreground">{row.action}</dt>
            <dd className="flex items-center gap-1.5">
              {row.then ? (
                <>
                  <Kbd keys={row.keys[0]!} platform={platform} />
                  <span className="text-xs text-muted-foreground">then</span>
                  <Kbd keys={row.keys[1]!} platform={platform} />
                </>
              ) : (
                <Kbd keys={row.keys} platform={platform} />
              )}
            </dd>
          </div>
        ))}
      </dl>
      <p className="text-[13px] text-muted-foreground">
        Press <Kbd keys="/" size="sm" /> anywhere to search. In a button the caps follow its colour:
      </p>
      <div className="flex flex-wrap gap-2">
        <Button>Save <Kbd keys="mod+s" variant="inline" size="sm" platform={platform} /></Button>
        <Button variant="secondary">Snooze <Kbd keys="s" variant="inline" size="sm" /></Button>
      </div>
    </div>
  );
}

API reference #

Kbd

component

Also accepts the native props of its root element and a ref.

PropTypeDefaultDescription
keysstring | readonly string[]—One key or a combination: "mod+k", "shift+enter", ["alt", "↑"]. `mod` is ⌘ on a Mac and Ctrl elsewhere.
childrenstring—Free text instead of keys, e.g. "G then D".
variant"default" | "inline""default"`inline` sits quietly inside a button, menu row or tooltip and takes its colour.
size"sm" | "md""md"
platformKbdPlatform—Force a platform instead of detecting it, e.g. in documentation.

toAriaKeyshortcuts

component

No props of its own; it accepts the native props of its root element.

useKbdPlatform

component

No props of its own; it re-exports a primitive and takes that primitive’s props.

Accessibility #

It is built on native elements and keeps aria-hidden in step with state.

No custom key handling; Tab and the native activation keys do the work.

Motion #

It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.