Skip to content
omaris

Data Display

Kbd

A key cap — the <kbd> a shortcut is drawn with.

import { Kbd } from 'omaris'
Learn

Examples

Basic

keys="mod+k" draws the whole combo — ⌘ K on a Mac, Ctrl + K elsewhere — and each symbol is read by its name. Children draw a single cap.

Search anywhere with Control+ K.

Send with Control+ Enter, new line with Shift+ Enter.

Close with Esc.

<script lang="ts">	import { Kbd, Text } from 'omaris';</script>​<div class="flex flex-col items-start gap-3">	<Text variant="body-md">Search anywhere with <Kbd keys="mod+k" />.</Text>	<Text variant="body-md">		Send with <Kbd keys="mod+enter" size="sm" />, new line with		<Kbd keys="shift+enter" size="sm" />.	</Text>	<Text variant="body-md">Close with <Kbd>Esc</Kbd>.</Text></div>

Shortcut sheet

A shortcut sheet. platform pins a keyboard for a comparison like this one; left on auto, the reader's own keyboard is the one drawn.

Open the command palette
Command K
New issue
C
Toggle the sidebar
Command B
Go to settings
Command ,
Every shortcut
Shift /
<script lang="ts">	import { Kbd, SegmentedButton, Text } from 'omaris';​	const SHORTCUTS = [		{ action: 'Open the command palette', keys: 'mod+k' },		{ action: 'New issue', keys: 'c' },		{ action: 'Toggle the sidebar', keys: 'mod+b' },		{ action: 'Go to settings', keys: 'mod+,' },		{ action: 'Every shortcut', keys: 'shift+/' }	];​	let platform = $state('apple');</script>​<div class="flex w-full max-w-md flex-col gap-3">	<SegmentedButton		bind:value={platform}		label="Keyboard"		items={[			{ value: 'apple', label: 'Mac' },			{ value: 'other', label: 'Windows' }		]}	/>​	<dl class="divide-y divide-border rounded-shape-md border border-border">		{#each SHORTCUTS as shortcut (shortcut.keys)}			<div class="flex items-center justify-between gap-4 px-4 py-2.5">				<Text as="dt" variant="body-md">{shortcut.action}</Text>				<dd>					<Kbd keys={shortcut.keys} platform={platform === 'apple' ? 'apple' : 'other'} size="sm" />				</dd>			</div>		{/each}	</dl></div>

Overridden

classes reaches the caps, the row and the separator; separator replaces the +; and a title or aria-* the caller sets lands on the root.

Shift· Control· P Command K Space
<script lang="ts">	import { Kbd, formatShortcut } from 'omaris';</script>​<div class="flex flex-wrap items-center gap-4">	<Kbd		keys="mod+shift+p"		platform="other"		separator="·"		classes={{ separator: 'px-0.5 text-primary' }}	/>	<Kbd		keys="mod+k"		platform="apple"		title={formatShortcut('mod+k', { platform: 'apple' })}		classes={{			root: 'gap-0',			key: 'rounded-none border-primary bg-primary-container text-primary-container-foreground first:rounded-s-shape-sm last:rounded-e-shape-sm'		}}	/>	<Kbd variant="flat" class="rounded-full px-3">Space</Kbd></div>

When to use it

Use it for

  • A shortcut beside the thing it triggers — a menu row, a Command Palette result, a button's tooltip: <Kbd keys="mod+k" size="sm" />.
  • A shortcut sheet or a help page, one row per action, with keys so every reader sees their own keyboard.
  • A key named in running text — "press <kbd>Esc</kbd> to close" — as a single cap with children.
  • The string form, formatShortcut('mod+k'), where a cap cannot go: a title, a tooltip, an aria-keyshortcuts attribute ({ aria: true }).

Not for

  • A status or a count → Badge. A cap reads as a key, and a key reads as something to press.
  • A code identifier or a value to copy → Code Block, or <Text font="mono"> inline.
  • A button that performs the shortcut → Button with the Kbd inside it; a cap is not pressable.

Do

  • Write mod rather than cmd or ctrl for the primary modifier. It is ⌘ on Apple devices and Ctrl everywhere else, and it is what matchShortcut binds.
  • Use size="sm" inside a menu row, a list item or a chip, and variant="flat" where the row already has its own surface.
  • Match the listener to the label: bind with matchShortcut(event, 'mod+k') so the key that is drawn is the key that works, on every keyboard layout.
  • Pin platform only when comparing keyboards side by side; left on auto, the reader's own keyboard is the one drawn.

Don't

  • Hand-write ⌘K in a label. A Windows reader sees a key they do not have, and a screen reader skips the symbol entirely.
  • Put a shortcut on a phone-only screen. There is no keyboard; the cap is noise.
  • Style the caps with class when you mean classes.key — on a combo, class is the row the caps sit in.

Quick reference

variant
  • raised (default)
  • flat
size
  • sm
  • md (default)
  • lg

API

Kbd

A key cap — the <kbd> a shortcut is drawn with.

Give it keys and it draws the whole combo, one cap per key, in the platform's own spelling: keys="mod+k" is ⌘ K on a Mac and Ctrl + K everywhere else, with the modifiers in the order that keyboard writes them. Each symbol carries its name for a screen reader, so ⌘ is read as "Command" rather than skipped.

Give it children instead and it is one cap around whatever you wrote.

The server does not know the keyboard, so it renders Ctrl; the cap swaps to ⌘ on hydration. Pass platform to pin it.

import { Kbd } from 'omaris'
<Kbd keys="mod+k" /><Kbd keys={['shift', 'enter']} size="sm" /><Kbd>Esc</Kbd>

Parts

Every element this renders is reachable from outside. Pass Tailwind for one part as classes={{ part: '…' }}; class covers the root and is merged last, so it always wins.

root
The combo. Not a cap itself — the row the caps sit in.
key
One key cap.
separator
The + between caps on a non-Apple keyboard.

Props

keys
string | readonly string[]

The combo to draw: 'mod+k', 'shift+enter', or the same as an array. mod is ⌘ on Apple devices and Ctrl elsewhere. Without it, the children are drawn as one cap.

variant

Defaults to 'raised'

KbdVariant
raised
A cap with depth: a heavier bottom edge, like the real key.
flat
Flat, for inside a menu row or a chip where depth is noise.
size

Defaults to 'md'

KbdSize
sm
md
lg
platform

Defaults to 'auto'

ShortcutPlatform

Which keyboard to draw for. auto asks the browser once it has hydrated, and draws Ctrl until then.

separator
string | false

Drawn between caps. Defaults to nothing on a Mac, where combos are written ⌘K, and + elsewhere, where they are written Ctrl+K. false for none anywhere.

class
string
classes
KbdClasses

Per-part Tailwind overrides. class still covers the root.

children
Snippet

One cap's content, when keys is not set.