Button Component

Versatile button component with 6 variants, 6 sizes, loading states, icon support, and full accessibility.

Button Variants

Six semantic variants for different actions

primaryMain call-to-action buttons
secondarySecondary actions, less emphasis
outlineAlternative actions, subtle emphasis
ghostTertiary actions, minimal visual weight
destructiveDangerous actions (delete, remove)
linkText-style links with button behavior

Button Sizes

Six sizes including icon-only variants

Standard Sizes

Icon-Only Sizes

Buttons with Icons

Add icons before or after button text

Loading States

Built-in loading spinner with accessible labels

Full Width

Buttons can stretch to fill their container

Disabled State

All variants have consistent disabled styling

Code Examples

How to use the Button component

Basic Usage

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

export function Example() {
  return (
    <div>
      <Button>Click me</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="outline">Outline</Button>
    </div>
  )
}

With Icons

import { Button } from '@/components/ui/button'
import { Download, Send } from 'lucide-react'

<Button leftIcon={<Download />}>
  Download
</Button>

<Button rightIcon={<Send />}>
  Send
</Button>

// Icon only
<Button size="icon">
  <Settings />
</Button>

Loading State

const [loading, setLoading] = useState(false)

<Button
  loading={loading}
  loadingText="Saving..."
  onClick={() => setLoading(true)}
>
  Save Changes
</Button>

As Link (Polymorphic)

import Link from 'next/link'

<Button asChild>
  <Link href="/about">About Us</Link>
</Button>

API Reference

Component props and their types

PropTypeDefaultDescription
variantstringprimaryButton style variant
sizestringmdButton size
fullWidthbooleanfalseStretch to full width
loadingbooleanfalseShow loading spinner
loadingTextstring-Label for loading state
leftIconReactNode-Icon before text
rightIconReactNode-Icon after text
asChildbooleanfalsePolymorphic rendering
disabledbooleanfalseDisable interaction

Accessibility Features

Built-in WCAG 2.2 AA compliance

  • Keyboard navigation: Full support for Enter and Space keys
  • Focus visible: Clear focus ring with 2px width (WCAG 2.4.7)
  • Touch targets: Minimum 40px height (WCAG 2.5.8)
  • Loading states: Proper aria-busy and aria-disabled attributes
  • Color contrast: 4.5:1 ratio for all variants
  • Disabled state: Prevents interaction via pointer-events-none