Kbd
The one keyboard-key chip — deterministic modifier labels resolved by the caller, a keys array, and three inline sizes.
- Status
- Since
0.1.0- Accessibility pattern
- native kbd element
Last updated
Install
Add Kbd from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.
pnpm dlx shadcn@latest add @vegastack/kbdUsage
import { Kbd, KbdGroup } from '@/components/ui/kbd';
// Single key
<Kbd>⌘</Kbd>
// A combo as an array — each token is its own chip
<Kbd keys={['⌘', 'K']} />;Anatomy
Kbd is a compound component. Every exported part, with the
data-slot it renders (generated from the canonical source):
Examples
Anatomy
Kbd renders a single <kbd> chip, or — when given a keys array — a row of chips wrapped in a
KbdGroup. Compose KbdGroup yourself to mix in non-key content.
<KbdGroup>
<Kbd>⌘</Kbd>
<Kbd>K</Kbd>
</KbdGroup>Combos
Pass a keys array to render a shortcut, or compose individual Kbd chips inside a KbdGroup.
Write tokens as mac glyphs; os decides how they render. The default is os="other"
(words), so pass os="mac" — or the resolved platform — for the glyphs.
Sizes
xs, sm, and md — sized to sit inline with text, menus, and tooltips. All three use
one type role, text-code-sm; md previously reached the same 12px through text-sm,
the same pixel size named twice.
Platform Labels
Kbd is server-safe and deterministic: it reads no navigator and therefore never
guesses the platform. Resolving the platform is the caller's job — run usePlatform()
and pass the answer down. os defaults to "other", the same fallback usePlatform
reports before hydration, so an unwired chip shows a word every reader understands rather
than shipping ⌘ to a Windows majority.
The rewrite applies whether you pass a keys array or a single string child (⌘ → Ctrl,
⇧ → Shift, ⌥ → Alt, ⌃ → Ctrl, ⏎/↵ → Enter, ⌫ → Bksp). On mac the glyph
is rendered visually with an sr-only spoken name beside it, because a screen reader
announces ⌘ as "place of interest sign" or skips it entirely.
// The wiring every caller should use
const { os } = usePlatform();
<Kbd keys={["⌘", "K"]} os={os === "mac" ? "mac" : "other"} />;
<Kbd os="mac" keys={['⌘', 'K']} /> {/* ⌘ K */}
<Kbd os="other" keys={['⌘', 'K']} /> {/* Ctrl K (the default) */}
// Single string children are rewritten too
<Kbd os="other">⌘</Kbd> {/* Ctrl */}Playground
Change the size and platform to watch the ⌘ glyph swap to Ctrl, then copy the generated JSX.
<Kbd keys={['⌘', 'K']} />API Reference
Kbd
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | — | A single key label — used when keys is not provided. |
keys | readonly string[] | — | Explicit key tokens to render. Each token becomes its own <kbd>. Modifier
glyphs (⌘, ⇧, ⌥, ⌃, ⏎, ⌫) are rewritten to words on non-mac
platforms. Takes precedence over children. |
os | "mac" | "other" | 'other' | Platform label mode. 'other' renders readable Windows/Linux modifier words
(Ctrl, Alt, …); 'mac' renders the glyphs (⌘, ⌥, …) paired with
sr-only spoken names.
Defaults to 'other' — the same SSR default usePlatform reports (audit
B2-10). Kbd is server-safe and deliberately reads no navigator, so the
platform is the CALLER's to resolve: run usePlatform() and pass the result
down. An unwired badge then shows a word every reader understands rather than
a mac glyph shipped to a Windows majority. |
size | "md" | "sm" | "xs" | 'md' | Size of the key chip — mirrors the lower end of the shared scale. |
Data attributes and CSS variables on Kbd
| Attribute | Values |
|---|---|
data-size | mirrors a prop or state value |
data-slot | "kbd" |
KbdGroup
KbdGroup adds no props of its own — it accepts everything the underlying element or Base UI primitive accepts (className, ref, ARIA attributes, event handlers).
Data attributes and CSS variables on KbdGroup
| Attribute | Values |
|---|---|
data-slot | "kbd-group" |
The kbdVariants CVA helper is also exported for advanced styling — call kbdVariants({ size })
to reuse the chip classes (the single size axis: xs | sm | md) on a custom element.
Accessibility
- Renders a native, non-interactive
<kbd>element — the semantic element for keyboard input, so assistive tech announces it as such. - The chip is a label, never a control: it does not receive focus and carries no
tabindex. Wire the actual shortcut up on the relevant control (e.g. a button or a menu item). - Modifier glyphs are rewritten to readable words on non-mac platforms, so a shortcut is never
announced as an unfamiliar symbol. On mac the glyph is
aria-hiddenand an sr-only word (Command,Option, …) carries the accessible name. Kbdis the only key chip in the system:TooltipKbdrenders it rather than restyling a second<kbd>, so a shortcut hint reads identically wherever it appears.
| Key | Behavior |
|---|---|
| (none) | Kbd is presentational — it has no interactive keyboard behavior. |
| Contract | States tested |
|---|---|
| Behaviour | default |
| Accessibility | native-or-base-ui-semantics, browser-accessibility-test |
| Visual | default |