Skip to content

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.

Terminal window
npx shadcn@latest add https://joaocarmassi.com/components/button.json

The 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:

Terminal window
npx shadcn@latest add @prisma/button
import { Button } from '@/components/ui/button';

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>

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

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 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>

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>

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>

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 animations for link-style buttons.

<Button variant="link" effect="underline">Underline</Button>
<Button variant="link" effect="hoverUnderline">Hover Underline</Button>

A continuous pulsating glow effect.

<Button effect="pulsating">Pulsating</Button>
<Button variant="destructive" effect="pulsating">Pulsating</Button>

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

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>

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" />

<Button disabled>Disabled</Button>
<Button disabled variant="destructive">Disabled</Button>
<Button disabled variant="outline">Disabled</Button>
<Button disabled variant="secondary">Disabled</Button>

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>

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

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:

radix-vega
radix-nova
radix-maia
radix-lyra
radix-mira
radix-luma
radix-rhea
radix-sera

See Styles & Themes for setup and the full list of supported styles.