Button
A versatile button component built on top of Radix UI and styled with Tailwind CSS. Supports multiple variants, sizes, visual effects, icons, and loading states.
Installation
Section titled “Installation”npx shadcn@latest add https://joaocarmassi.com/components/button.jsonpnpm dlx shadcn@latest add https://joaocarmassi.com/components/button.jsonnpx shadcn@latest add https://joaocarmassi.com/components/button.jsonbunx --bun shadcn@latest add https://joaocarmassi.com/components/button.jsonThe direct URL serves the radix-vega variant. The Button is style-aware — its sizes, radius, and type scale differ per shadcn style. To let the CLI pick the variant that matches your project’s theme automatically, register the @prisma namespace once (see Styles & Themes) and install by name:
npx shadcn@latest add @prisma/buttonpnpm dlx shadcn@latest add @prisma/buttonnpx shadcn@latest add @prisma/buttonbunx --bun shadcn@latest add @prisma/buttonImport
Section titled “Import”import { Button } from '@/components/ui/button';Variants
Section titled “Variants”The variant prop controls the visual style of the button.
<Button variant="default">Default</Button><Button variant="destructive">Destructive</Button><Button variant="outline">Outline</Button><Button variant="secondary">Secondary</Button><Button variant="ghost">Ghost</Button><Button variant="link">Link</Button>| Variant | Description |
|---|---|
default |
Primary button with solid background |
destructive |
For dangerous or destructive actions |
outline |
Bordered button with transparent fill |
secondary |
Subtle, less prominent button |
ghost |
No background until hovered |
link |
Styled as a text link with underline |
The size prop controls the dimensions of the button.
<Button size="xs">Extra Small</Button><Button size="sm">Small</Button><Button size="default">Default</Button><Button size="lg">Large</Button>Icon Sizes
Section titled “Icon Sizes”For icon-only buttons, use the icon size variants.
import { Plus } from 'lucide-react';<Button size="icon-xs"><Plus /></Button><Button size="icon-sm"><Plus /></Button><Button size="icon"><Plus /></Button><Button size="icon-lg"><Plus /></Button>| Size | Description |
|---|---|
default |
Standard height (36px) |
xs |
Extra small |
sm |
Small |
lg |
Large |
icon |
Square button for icons |
icon-xs |
Extra small icon button |
icon-sm |
Small icon button |
icon-lg |
Large icon button |
Effects
Section titled “Effects”The effect prop adds visual animations and transitions to the button.
A continuous animated shine sweeping across the button.
<Button effect="shine">Shine</Button><Button variant="destructive" effect="shine">Shine Destructive</Button><Button variant="secondary" effect="shine">Shine Secondary</Button>Shine Hover
Section titled “Shine Hover”Shine effect that triggers only on hover.
<Button effect="shineHover">Shine Hover</Button><Button variant="destructive" effect="shineHover">Shine Hover</Button><Button variant="secondary" effect="shineHover">Shine Hover</Button>Ring Hover
Section titled “Ring Hover”Displays a colored ring around the button on hover.
<Button effect="ringHover">Ring Hover</Button><Button variant="destructive" effect="ringHover">Ring Hover</Button><Button variant="outline" effect="ringHover">Ring Hover</Button>Gooey Right / Gooey Left
Section titled “Gooey Right / Gooey Left”A fluid gooey animation sweeping from right or left on hover.
<Button effect="gooeyRight">Gooey Right</Button><Button effect="gooeyLeft">Gooey Left</Button><Button effect="gooeyRight" variant="destructive">Gooey Right</Button><Button effect="gooeyLeft" variant="destructive">Gooey Left</Button>Expand Icon
Section titled “Expand Icon”An icon that expands from hidden on hover. Requires icon and iconPlacement props.
import { ArrowRight, ChevronRight, Mail } from 'lucide-react';<Button effect="expandIcon" icon={ArrowRight} iconPlacement="right"> Continue</Button><Button effect="expandIcon" icon={ChevronRight} iconPlacement="right" variant="outline"> Next Step</Button><Button effect="expandIcon" icon={Mail} iconPlacement="left"> Send Email</Button>Underline / Hover Underline
Section titled “Underline / Hover Underline”Underline animations for link-style buttons.
<Button variant="link" effect="underline">Underline</Button><Button variant="link" effect="hoverUnderline">Hover Underline</Button>Pulsating
Section titled “Pulsating”A continuous pulsating glow effect.
<Button effect="pulsating">Pulsating</Button><Button variant="destructive" effect="pulsating">Pulsating</Button>Rainbow
Section titled “Rainbow”An animated rainbow gradient border effect.
<Button effect="rainbow">Rainbow</Button><Button size="lg" effect="rainbow">Rainbow Large</Button>| Effect | Description |
|---|---|
shine |
Continuous animated shine |
shineHover |
Shine triggered on hover |
ringHover |
Colored ring on hover |
gooeyRight |
Fluid gooey animation from right |
gooeyLeft |
Fluid gooey animation from left |
expandIcon |
Icon expands on hover |
underline |
Underline that disappears on hover |
hoverUnderline |
Underline that appears on hover |
pulsating |
Continuous pulsating glow |
rainbow |
Animated rainbow gradient border |
With Icons
Section titled “With Icons”Place icon components directly as children of the button.
import { Mail, Download, Trash2, Heart, Search, ArrowRight,} from 'lucide-react';<Button><Mail /> Send Email</Button><Button variant="outline"><Download /> Download</Button><Button variant="destructive"><Trash2 /> Delete</Button><Button variant="secondary"><Heart /> Favorite</Button><Button variant="ghost"><Search /> Search</Button><Button>Next <ArrowRight /></Button>Loading State
Section titled “Loading State”Set loading to show a spinner and disable the button.
<Button loading>Saving...</Button><Button loading variant="destructive">Deleting...</Button><Button loading variant="outline">Loading...</Button><Button loading size="icon" /><Button loading size="icon-sm" />Disabled State
Section titled “Disabled State”<Button disabled>Disabled</Button><Button disabled variant="destructive">Disabled</Button><Button disabled variant="outline">Disabled</Button><Button disabled variant="secondary">Disabled</Button>As Child
Section titled “As Child”Use asChild to render the button styles on a different element, such as an anchor or Next.js Link.
import Link from 'next/link';
<Button asChild variant="link"> <Link href="/docs">Go to Docs</Link></Button>
<Button asChild> <a href="https://github.com" target="_blank" rel="noopener noreferrer"> GitHub </a></Button>API Reference
Section titled “API Reference”| Prop | Type | Default | Description |
|---|---|---|---|
variant |
"default" | "destructive" | "outline" | "secondary" | "ghost" | "link" |
"default" |
Visual style of the button |
size |
"default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" |
"default" |
Size of the button |
effect |
"shine" | "shineHover" | "ringHover" | "gooeyRight" | "gooeyLeft" | "expandIcon" | "underline" | "hoverUnderline" | "pulsating" | "rainbow" |
undefined |
Visual effect applied to the button |
icon |
React.ElementType |
undefined |
Icon component to render |
iconPlacement |
"left" | "right" |
undefined |
Position of the icon |
loading |
boolean |
false |
Shows a spinner and disables the button |
asChild |
boolean |
false |
Renders as child element via Radix Slot |
disabled |
boolean |
false |
Disables the button |
className |
string |
undefined |
Additional CSS classes |
Theme styles
Section titled “Theme styles”The Button ships in a dedicated variant for each supported shadcn style. Installed through the @prisma namespace, the CLI delivers the one matching the style in your components.json — same API, different sizing, radius, and type scale:
See Styles & Themes for setup and the full list of supported styles.