Skip to content
38

Kbd Button

A pressable 3D keycap with hover lift and a pressed state, for shortcut legends and keyboard-driven UIs. Pairs with shadcn's Kbd and KbdGroup for inline shortcuts and chords.

Example

Installation

npx shadcn@latest add https://hirael.com/r/kbd-button.json

Usage

import { KbdButton } from "@/components/kbd-button"

Paths assume the default @/ alias from your components.json. The example above shows the parts composed.

API

<KbdButton />

+ native element props

No props of its own; forwards everything to the underlying element.

Component source

import { cn } from '@/lib/utils';

const KbdButton = ({ className, ...props }: React.ComponentProps<'button'>) => {
  return (
    <button
      type="button"
      data-slot="kbd-button"
      className={cn(
        'relative inline-flex touch-manipulation items-center justify-center overflow-hidden select-none',
        'h-8 min-w-8 px-2',
        'font-sans text-sm font-medium text-foreground',
        'rounded-lg border border-input',
        'bg-linear-to-b from-card to-card/80',
        '[-webkit-tap-highlight-color:transparent]',
        'shadow-[0_1px_0_1px_var(--border),0_2px_4px_-1px_color-mix(in_oklch,var(--foreground)_14%,transparent),0_4px_6px_-2px_color-mix(in_oklch,var(--foreground)_8%,transparent)]',
        'before:pointer-events-none before:absolute before:inset-x-[2px] before:top-[2px] before:h-[40%] before:rounded-t-md before:bg-linear-to-b before:from-primary/20 before:to-transparent',
        'transition-[translate,box-shadow,filter] duration-100 ease-out',
        'hover:brightness-105',
        'hover:shadow-[0_1px_0_1px_var(--border),0_3px_6px_-1px_color-mix(in_oklch,var(--foreground)_17%,transparent),0_6px_10px_-2px_color-mix(in_oklch,var(--foreground)_10%,transparent)]',
        'active:translate-y-[2px] active:brightness-95',
        'active:shadow-[0_0_0_1px_var(--border),0_1px_2px_0_color-mix(in_oklch,var(--foreground)_12%,transparent)]',
        'outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50',
        'disabled:pointer-events-none disabled:opacity-50',
        className,
      )}
      {...props}
    />
  );
};

export { KbdButton };

Shipped