ComponentsActions

Kbd

A keyboard key, shown wherever a shortcut can be learned: tooltips, menus, the search field and the shortcuts sheet. One chip per key.

Playground

Change the label to try a key. The code under the preview updates as you go; copy it into your page.

K
import { Kbd } from '@/ui/kbd';<Kbd>  K</Kbd>

Single key

One chip per key. Letters in capitals; named keys as a symbol or a short word.

ER/?↵EscTab
import { Kbd } from '@/ui/kbd';

export default function KbdSingle() {
  return (
    <div className="flex flex-wrap items-center gap-100">
      <Kbd>E</Kbd>
      <Kbd>R</Kbd>
      <Kbd>/</Kbd>
      <Kbd>?</Kbd>
      <Kbd>↵</Kbd>
      <Kbd>Esc</Kbd>
      <Kbd>Tab</Kbd>
    </div>
  );
}

Combination

Pass key names to KbdGroup keys and it renders one Kbd per key, 4px apart, with no "+". Modifiers come first. Mod is ⌘ on a Mac and Ctrl elsewhere, so a screen passes names and never picks the symbol itself.

⌘K⌘Z⌘↵⌘⇧Space
import { KbdGroup } from '@/ui/kbd';

export default function KbdCombination() {
  return (
    <div className="flex flex-wrap items-center gap-300">
      <KbdGroup keys={['Mod', 'K']} />
      <KbdGroup keys={['Mod', 'Z']} />
      <KbdGroup keys={['Mod', 'Enter']} />
      <KbdGroup keys={['Mod', 'Shift', 'Space']} />
    </div>
  );
}

Platform

Mac shows ⌘ ⌥ ⇧ ⌃ ↵; Windows and Linux show Ctrl, Alt, Shift and Enter. KbdGroup follows the reader's platform; platform fixes it, as in this table.

Shortcut
Mac
Windows and Linux
Open search
⌘K
CtrlK
Hold to talk to Flo
⌘⇧Space
CtrlShiftSpace
import { KbdGroup } from '@/ui/kbd';

export default function KbdPlatform() {
  return (
    <dl className="grid grid-cols-[auto_auto_auto] items-center gap-x-300 gap-y-100 text-body text-text">
      <dt className="text-body-small font-medium text-text-subtle">Shortcut</dt>
      <dd className="text-body-small font-medium text-text-subtle">Mac</dd>
      <dd className="text-body-small font-medium text-text-subtle">Windows and Linux</dd>
      <dt>Open search</dt>
      <dd><KbdGroup keys={['Mod', 'K']} platform="apple" /></dd>
      <dd><KbdGroup keys={['Mod', 'K']} platform="other" /></dd>
      <dt>Hold to talk to Flo</dt>
      <dd><KbdGroup keys={['Mod', 'Shift', 'Space']} platform="apple" /></dd>
      <dd><KbdGroup keys={['Mod', 'Shift', 'Space']} platform="other" /></dd>
    </dl>
  );
}

In context

In a tooltip

Hover or focus the button. Inside a tooltip the key takes a 20% white fill and white text, set by the tooltip.

import { ArchiveIcon } from '@phosphor-icons/react';
import { Button } from '@/ui/button';
import { Kbd } from '@/ui/kbd';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/ui/tooltip';

export default function KbdInTooltip() {
  return (
    <Tooltip>
      <TooltipTrigger render={<Button variant="ghost" data-icon-only="" aria-label="Archive" aria-keyshortcuts="E" />}>
        <ArchiveIcon />
      </TooltipTrigger>
      <TooltipContent>
        Archive
        <Kbd>E</Kbd>
      </TooltipContent>
    </Tooltip>
  );
}

In a menu item

Pushed to the end of the item.

Open record↵
Duplicate⌘D
import { KbdGroup } from '@/ui/kbd';

export default function KbdInMenuItem() {
  return (
    <div className="flex w-56 flex-col rounded-large bg-surface p-050 text-body font-medium text-text shadow-control">
      <div className="flex h-7 items-center gap-100 rounded-medium px-100">
        Open record
        <KbdGroup keys={['Enter']} className="ms-auto" />
      </div>
      <div className="flex h-7 items-center gap-100 rounded-medium px-100">
        Duplicate
        <KbdGroup keys={['Mod', 'D']} className="ms-auto" />
      </div>
    </div>
  );
}

In a field

Shown at the end of a search field, and hidden once the field has focus or text.

/
import { MagnifyingGlassIcon } from '@phosphor-icons/react';
import { Kbd } from '@/ui/kbd';

export default function KbdInField() {
  return (
    <div className="flex h-7 w-64 items-center gap-075 rounded-large bg-surface px-100 shadow-control">
      <MagnifyingGlassIcon className="size-4 shrink-0 text-text-subtle" />
      <input
        type="search"
        aria-label="Search candidates"
        aria-keyshortcuts="/"
        placeholder="Search candidates"
        className="peer min-w-0 flex-1 bg-transparent text-body text-text outline-none placeholder:text-text-subtle"
      />
      {/* Hidden once the field has focus or text. */}
      <Kbd className="peer-focus:hidden peer-[:not(:placeholder-shown)]:hidden">/</Kbd>
    </div>
  );
}

On this page