Keyboard Shortcuts
spell-ui/kbdFreeComponent
Display keyboard shortcuts with proper key symbols.
Live preview
live · rendered by the registry
Rendered by spell-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://spell.sh/r/kbd.jsonSource
1"use client";23import { cn } from "@/lib/utils";4import { useEffect, useState } from "react";5import { useHotkeys } from "react-hotkeys-hook";67type KeyItem = string | { display: string; key: string };89interface KbdProps {10 keys: KeyItem[];11 className?: string;12 active?: boolean;13 listenToKeyboard?: boolean;14}1516const keySymbolMap = {17 command: "⌘",18 cmd: "⌘",19 control: "⌃",20 ctrl: "⌃",21 alt: "⌥",22 option: "⌥",23 space: "␣",24 arrowleft: "←",25 left: "←",26 arrowdown: "↓",27 down: "↓",28 arrowup: "↑",29 up: "↑",30 arrowright: "→",31 right: "→",32} as const;3334const keyHotkeyMap: Record<string, string> = {35 command: "meta",36 cmd: "meta",37 control: "ctrl",38 ctrl: "ctrl",39 alt: "alt",40 option: "alt",41 shift: "shift",42 enter: "enter",43 return: "enter",44 space: "space",45 arrowleft: "left",46 left: "left",47 arrowdown: "down",48 down: "down",49 arrowup: "up",50 up: "up",51 arrowright: "right",52 right: "right",53};5455export function Kbd({ keys = [], className, active, listenToKeyboard = false }: KbdProps) {56 const [isPressed, setIsPressed] = useState(false);5758 const getKeyDisplay = (item: KeyItem): string => {59 const key = typeof item === "string" ? item : item.display;60 const lowerKey = key.toLowerCase();61 return keySymbolMap[lowerKey as keyof typeof keySymbolMap] || key.toUpperCase();62 };6364 const getHotkeyString = (): string => {65 return keys66 .map((item) => {67 const key = typeof item === "string" ? item : item.key;68 const lowerKey = key.toLowerCase();69 return keyHotkeyMap[lowerKey] || lowerKey;70 })71 .join("+");72 };7374 useHotkeys(75 getHotkeyString(),76 () => setIsPressed(true),77 {78 enabled: listenToKeyboard,79 keydown: true,80 keyup: false,81 preventDefault: false,82 },83 [keys, listenToKeyboard]84 );8586 useEffect(() => {87 if (!listenToKeyboard) return;8889 const handleKeyUp = () => {90 setIsPressed(false);91 };9293 const handleBlur = () => {94 setIsPressed(false);95 };9697 window.addEventListener("keyup", handleKeyUp);98 window.addEventListener("blur", handleBlur);99100 return () => {101 window.removeEventListener("keyup", handleKeyUp);102 window.removeEventListener("blur", handleBlur);103 };104 }, [listenToKeyboard]);105106 const isActive = active || isPressed;107108 return (109 <kbd110 className={cn(111// … truncated
What it pulls in
npm packages
Files it writes
More from spell-ui
All 33 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Checkboxanimated-checkbox | spell-ui | Components | Free | 1 dep | |
| Animated Gradientanimated-gradient | spell-ui | Components | Free | no deps | |
| Badgebadge | spell-ui | Components | Free | 2 deps | |
| Bars Spinnerbars-spinner | spell-ui | Components | Free | no deps | |
| Blur Revealblur-reveal | spell-ui | Components | Free | 1 dep | |
| Chartchart | spell-ui | Components | Free | no deps | |
| Color Selectorcolor-selector | spell-ui | Components | Free | no deps | |
| Copy Buttoncopy-button | spell-ui | Components | Free | 1 dep |
