Button.tsx
Versatile button component with multiple variants and sizes
The Button component is a flexible, accessible button built with Radix UI Slot and class-variance-authority for variant management.
Features
- Multiple visual variants (default, destructive, outline, secondary, ghost, link)
- Size options (sm, default, lg, icon)
- Polymorphic with
asChildprop - Full TypeScript support
- Accessible with keyboard navigation
Basic Usage
import { Button } from '@/components/ui/Button';
export default function Page() {
return <Button>Click me</Button>;
}Variants
Default
Primary brand-colored button:
<Button variant="default">Default Button</Button>Destructive
For dangerous actions:
<Button variant="destructive">Delete Account</Button>Outline
Bordered button with transparent background:
<Button variant="outline">Outline Button</Button>Secondary
Neutral-colored button:
<Button variant="secondary">Secondary Button</Button>Ghost
Minimal button with hover effect:
<Button variant="ghost">Ghost Button</Button>Link
Text button with underline on hover:
<Button variant="link">Link Button</Button>Sizes
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
<Button size="icon">
<Icon />
</Button>As Child (Polymorphic)
Render as a different element while keeping button styles:
import Link from 'next/link';
import { Button } from '@/components/ui/Button';
<Button asChild>
<Link href="/dashboard">Go to Dashboard</Link>
</Button>With Icons
import { ArrowRight } from 'lucide-react';
import { Button } from '@/components/ui/Button';
<Button>
Continue
<ArrowRight className="ml-2 h-4 w-4" />
</Button>Disabled State
<Button disabled>Disabled Button</Button>Loading State
import { Loader2 } from 'lucide-react';
<Button disabled>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Loading...
</Button>Implementation
The Button uses class-variance-authority for variant management:
const buttonVariants = cva(
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors',
{
variants: {
variant: {
default: 'bg-brand text-brand-foreground hover:bg-brand/90',
outline: 'border border-neutral-border hover:bg-accent',
},
size: {
default: 'h-9 px-4 py-2',
sm: 'h-8 px-3 text-xs',
lg: 'h-10 px-8',
icon: 'h-9 w-9',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
);Props
The Button extends standard HTML button attributes and adds:
variant: Visual style variantsize: Button sizeasChild: Render as child element (polymorphic)className: Additional CSS classes
Accessibility
- Keyboard accessible (Enter/Space to activate)
- Focus visible styles
- Disabled state prevents interaction
- Proper ARIA attributes when used with icons
How is this guide ?
Last updated on