UI.MD

Button

An interactive button with multiple variants, sizes, icons, loading state, and Motion layout animation.

Installation

$
npx shadcn@latest add https://ui.mattdowney.com/r/button.json

Usage

import { Button } from "@/components/ui/button"

Examples

Default

Variants

Sizes

With Icon

Pass an element: it works anywhere, including from a Server Component. A bare component reference (iconStart={Mail}) also works, but only from a Client Component, because a function cannot cross the server/client boundary.

With Badge

The counter holds one treatment through hover instead of restyling with the button, so the number never gets harder to read as the pointer lands. On filled buttons it is an opaque chip; on tinted ones it steps a shade deeper than the surface.

Loading

API Reference

PropTypeDefaultDescription
variant"default" | "soft" | "outline" | "ghost" | "destructive" | "subtle" | "link""default"Visual style of the button. soft is the accent-tinted secondary that pairs with default; subtle is its neutral equivalent for toolbars.
size"default" | "xs" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | "inline""default"Height and padding preset. icon (32px), icon-sm (24px), and icon-lg (40px) are square; inline flows with surrounding text.
iconStartLucideIcon | ReactNode-Icon rendered before the label. Prefer an element (<Mail />); a bare component (Mail) still works but cannot be passed from a Server Component.
iconEndLucideIcon | ReactNode-Icon rendered after the label. Prefer an element (<ChevronRight />); a bare component still works but cannot be passed from a Server Component.
iconSize"xs" | "sm" | "default" | "lg" | "xl"-Overrides the icon size implied by size.
badgeReact.ReactNode-Count badge rendered after the label, tinted to match the variant.
badgeClassNamestring-Extra classes for the badge element.
loadingbooleanfalseShows a centered spinner, locks in the variant's hover styling, and blocks clicks while preserving the button's width.
layoutAnimationbooleanfalseMotion layout animation on content changes. Set false to prevent glitches on rapid state changes; disabled automatically under reduced motion.
asChildbooleanfalseRenders the child element instead of a <button>, merging classes and injecting icons, badge, and spinner into it.