Kbd
FreeKeys as small raised caps: one shortcut per kbd, ⌘ on a Mac and Ctrl elsewhere, with spoken names for symbols.
pnpm dlx shadcn@latest add https://caliperui.site/r/kbd.jsonKeyboard 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 #
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.
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.
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.