Button

Displays a button or a component that looks like a button.

tsx
import { Button } from "@/components/ui/button"
export function ButtonDemo() {
return <Button>Button</Button>
}

Installation

CLI

bash
npx fivui add button

Manual

Copy and paste the following code into your project.

components/ui/button.tsx
import * as React from 'react';
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';
const buttonVariants = cva(
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
{
variants: {
variant: {
default:
'bg-primary text-primary-foreground hover:bg-primary/90',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline:
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
secondary:
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : 'button';
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
}
);
Button.displayName = 'Button';
export { Button, buttonVariants };

Usage

tsx
import { Button } from "@/components/ui/button"
tsx
<Button variant="outline">Button</Button>

Link

You can use the asChild prop to make another component look like a button. Here's an example of a link that looks like a button.

tsx
import { Link } from "next/link"
import { Button } from "@/components/ui/button"
export function LinkAsButton() {
return (
<Button asChild>
<Link href="/login">Login</Link>
</Button>
)
}

Examples

Default

tsx
import { Button } from "@/components/ui/button"
export function ButtonDemo() {
return <Button>Button</Button>
}

Secondary

tsx
import { Button } from "@/components/ui/button"
export function ButtonSecondary() {
return <Button variant="secondary">Secondary</Button>
}

Destructive

tsx
import { Button } from "@/components/ui/button"
export function ButtonDestructive() {
return <Button variant="destructive">Destructive</Button>
}

Outline

tsx
import { Button } from "@/components/ui/button"
export function ButtonOutline() {
return <Button variant="outline">Outline</Button>
}

Ghost

tsx
import { Button } from "@/components/ui/button"
export function ButtonGhost() {
return <Button variant="ghost">Ghost</Button>
}

Link

tsx
import { Button } from "@/components/ui/button"
export function ButtonLink() {
return <Button variant="link">Link</Button>
}

Icon

tsx
import { ChevronRight } from "lucide-react"
import { Button } from "@/components/ui/button"
export function ButtonIcon() {
return (
<Button variant="outline" size="icon">
<ChevronRight className="h-4 w-4" />
</Button>
)
}

With Icon

tsx
import { GitBranch } from "lucide-react"
import { Button } from "@/components/ui/button"
export function ButtonWithIcon() {
return (
<Button variant="outline" size="sm">
<GitBranch className="mr-2 h-4 w-4" />
New Branch
</Button>
)
}

Loading

tsx
import { Loader2 } from "lucide-react"
import { Button } from "@/components/ui/button"
export function ButtonLoading() {
return (
<Button disabled>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Please wait
</Button>
)
}

API Reference

Button

PropTypeDefaultDescription
variant"default" | "destructive" | "outline" | "secondary" | "ghost" | "link""default"The visual style variant of the button
size"default" | "sm" | "lg" | "icon""default"The size of the button
asChildbooleanfalseChange the default rendered element for the one passed as a child, merging their props and behavior

Button also accepts all standard HTML button attributes and React button props.

View Slot Docs