shadcn.io is not affiliated with official shadcn/ui
The label comes first and the shortcut follows in key caps, such as Search docs ⌘K, so the faster way is visible every time someone reaches for the button. The button only shows the shortcut: your app binds the keys, as the Hotkey demo does.
Use it for actions people repeat: a command palette, Save, New issue, Send. Skip the caps on buttons without a shortcut, and on touch-first screens where nobody has a keyboard. It wraps the Button, so variant and size work as usual, and the caps are the Kbd, tinted to read on every variant. The optional hover reveal is a CSS transition that slides and fades the caps in, and only fades them with reduced motion.
Installation
Usage
import { KbdButton } from "@/components/ui/kbd-button";<KbdButton shortcut={["⌘", "S"]}>Save</KbdButton>Demos
Hotkey
shortcut takes the keys as they should read, one cap each: ["⌘", "K"], ["Ctrl", "S"], ["N"]. Binding them is your app's: here the page listens for N, skips it while someone types in a field, and runs the same action as a press. A hotkey library does the same in one line.
Show on Hover
showShortcutOn="hover" hides the caps until the button is hovered or focused from the keyboard, then slides them in, for dense menus where shortcuts are useful to discover but shouldn't compete with the labels. The space is kept, so nothing shifts.
Accessibility
The caps are part of the button's text, so the shortcut is read with the label. The button also gets aria-keyshortcuts from shortcut, such as Meta+K for ⌘ K, the standard way to tell assistive tech about a shortcut; pass aria-keyshortcuts yourself to spell it another way. Hover-only caps also appear on keyboard focus.
- Enter
- Activate the button.
- Space
- Activate the button.
FAQ
How do I write the shortcut?
As an array of keys, one cap each, written as they should read: ["⌘", "K"], ["Ctrl", "Shift", "P"], ["/"]. The modifier glyphs ⌘, ⌃, ⌥ and ⇧, and Cmd, Ctrl and Option, are spelled out for aria-keyshortcuts; other keys go in as written.
Why doesn't pressing the shortcut press the button?
The button only shows it, so it can't fight with your app's other shortcuts or a hotkey library you already use. Listen for the keys where your app handles shortcuts and run the same action, as the Hotkey demo does.
How do I show ⌘ on a Mac and Ctrl on Windows?
Pick the keys from the visitor's platform where you render the button, such as ["⌘", "K"] on Apple devices and ["Ctrl", "K"] elsewhere, and bind both in your listener. The button shows what you pass.
Can I hide the caps until hover?
Pass showShortcutOn="hover". They slide and fade in on hover and on keyboard focus, and keep their space so the label doesn't move.
How do I put the caps at the far end of a wide button?
They already go there: the caps take the space left after the label, so a full-width button, as in the Show on Hover demo, has the label at the start and the shortcut at the end.
API Reference
KbdButton
data-slot="kbd-button-shortcut"
children?ReactNode
The label, before the shortcut.
focusableWhenDisabled?boolean
Whether the button should be focusable when disabled.
- Default
false
nativeButton?boolean
Whether the component renders a native <button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (for example, <div>).
- Default
true
shortcut?string[]
The shortcut's keys, one cap each, as they should read: ["⌘", "K"],
["Ctrl", "S"], ["/"]. It's shown only: bind the keys yourself.
- Default
[]
showShortcutOn?"always" | "hover"
When the shortcut shows: always, or only while the button is hovered or has keyboard focus, sliding in. It keeps its space either way.
- Type
"always" | "hover"- Default
"always"
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
Related
- Pro
Input Button
ControlsThe search a shortcut opens
- Pro
Theme Toggle Button
ControlsA header action worth a shortcut
Copy Button
Progress & resultsAnother repeatable power-user action
- Pro
Underline Button
Hover revealsQuiet nav links for dense menus
Arrow Button
Hover revealsLabel plus a trailing cue, CSS only
Icon Button
Hover revealsCompact toolbar actions