Renders keyboard keys and shortcuts.
Kbd knows the common keys by name, so "mod+k" becomes ⌘K on Apple
platforms and Ctrl+K everywhere else — one string, correct on every machine.
import { Kbd } from 'frontile';
Pass a shortcut to @keys as +-separated keys.
import { Kbd } from 'frontile';
<template>
<div class='flex items-center gap-4 not-prose p-2'>
<Kbd @keys='mod+k' />
<Kbd @keys='mod+shift+p' />
<Kbd @keys='enter' />
<Kbd @keys='esc' />
<Kbd @keys='up' />
</div>
</template>
Anything that is not a known key renders as given, and a single letter is capitalised. Pass a block for arbitrary content.
import { Kbd } from 'frontile';
<template>
<div class='flex items-center gap-4 not-prose p-2'>
<Kbd @keys='F5' />
<Kbd @keys='mod+/' />
<Kbd>Fn</Kbd>
</div>
</template>
Named keys are case-insensitive.
| Group | Names |
|---|---|
| Modifiers | mod, meta / cmd / command, ctrl / control, alt / option, shift, win, fn |
| Special | enter / return, esc / escape, tab, space, backspace, del / delete, capslock, plus |
| Navigation | up, down, left, right, pageup, pagedown, home, end |
Use plus when you need a literal +, since + is the separator.
Only three keys differ by platform:
| Name | Apple | Elsewhere |
|---|---|---|
mod |
⌘ |
Ctrl |
ctrl |
⌃ |
Ctrl |
alt |
⌥ |
Alt |
Prefer mod for application shortcuts — it names the role, so it follows the
platform. Use meta only when you mean the Command key specifically.
@display='merged' puts every glyph in a single cap, and @separator places a
character between caps.
import { Kbd } from 'frontile';
<template>
<div class='flex items-center gap-4 not-prose p-2'>
<Kbd @keys='mod+k' />
<Kbd @keys='mod+k' @display='merged' />
<Kbd @keys='ctrl+b' @separator='+' />
</div>
</template>
import { Kbd } from 'frontile';
<template>
<div class='flex items-center gap-4 not-prose p-2'>
<Kbd @keys='mod+k' @size='sm' />
<Kbd @keys='mod+k' @size='md' />
<Kbd @keys='mod+k' @size='lg' />
</div>
</template>
import { Kbd } from 'frontile';
const variants = ['solid', 'outline', 'subtle'];
const intents = [
'default',
'primary',
'secondary',
'success',
'warning',
'danger'
];
<template>
<div class='flex flex-col gap-3 not-prose p-2'>
{{#each variants as |variant|}}
<div class='flex items-center gap-3'>
{{#each intents as |intent|}}
<Kbd @keys='mod+k' @variant={{variant}} @color={{intent}} />
{{/each}}
</div>
{{/each}}
</div>
</template>
Two variants take their colour from their surroundings rather than from
@color. inherit keeps a hairline box drawn in the current colour, which is
what lets a keycap sit on a filled, active row without the row's theme having to
repaint it. plain drops the box entirely, for a quiet trailing shortcut.
import { Kbd } from 'frontile';
<template>
<div class='flex flex-col gap-2 not-prose p-2'>
<div
class='flex items-center justify-between gap-3 rounded-lg bg-primary-soft text-on-primary-soft px-3 py-2'
>
<span>Open command palette</span>
<Kbd @keys='mod+k' @variant='inherit' @size='sm' />
</div>
<div class='flex items-center justify-between gap-3 rounded-lg px-3 py-2'>
<span>Open command palette</span>
<Kbd @keys='mod+k' @variant='plain' @size='sm' />
</div>
</div>
</template>
Listbox, Dropdown and Command render their items' @shortcut through
Kbd. Their keycaps default to inherit, so a shortcut stays legible on an
active or filled row; pass @shortcutVariant on the Listbox or Dropdown
to change every item at once.
By default the platform is detected from the browser. Set it explicitly when detection cannot work or would be wrong — during server rendering, where every visitor looks non-Apple, or in tests, which would otherwise depend on the machine running them.
import { setKbdPlatform } from 'frontile';
setKbdPlatform('apple'); // or 'other', or 'auto' to detect
@platform overrides it for a single keycap.
Rendered as nested <kbd> elements, which is how HTML expresses a key
combination.
Symbol glyphs are hidden from assistive technology and their names announced
instead, since "⌘" read aloud is meaningless. Glyphs that already read correctly
— Esc, Ctrl, a letter — are left alone, because labelling them would
announce the name twice. Named keys also carry a title, which helps sighted
users who do not recognise a glyph.
Element: HTMLElement
Renders keyboard keys and shortcuts.
A wrapper <kbd> holds one child <kbd> per key, which is the HTML
specification's own idiom for a key combination.
| Name | Type | Default | Description |
|---|---|---|---|
class
|
string
|
- | Custom class name, it will override the default ones using Tailwind Merge library. |
classes
|
SlotsToClasses<'base' | 'separator' | 'key'>
|
- |
Custom CSS classes for styling the individual slots: base for the
wrapper, key for each cap, separator for the character between caps.
|
color
|
enum
|
'neutral'
|
|
display
|
enum
|
'split'
|
split gives each key its own cap; merged puts every glyph in one.
|
keys
|
string
|
- |
The shortcut to render, as Named keys resolve to glyphs ( Ignored when a block is passed. |
platform
|
enum
|
- |
Overrides the platform for this keycap only. Prefer setKbdPlatform to
set it once for the whole app.
|
separator
|
string
|
- |
Rendered between caps, e.g. "+". Only applies when @display is
split.
|
size
|
enum
|
'md'
|
|
variant
|
enum
|
'solid'
|
inherit follows the colour it sits on, for keycaps on a filled row.
plain drops the box entirely, for quiet trailing shortcuts.
|
| Name | Type | Default | Description |
|---|---|---|---|
default
*
|
Array
|
- |
Replaces @keys with arbitrary content, rendered as a single cap.
|