Creative Tim UICreative Tim UI

Shadcn Button

PreviousNext

Versatile button components with multiple variants, sizes, and customization options for any interface.

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

export function ButtonDemo() {
  return <Button>Button</Button>
}

Installation

pnpm dlx @creative-tim/ui@latest add button

Usage

import { Button } from "@/components/ui/button"
<Button>Click me</Button>

Examples

Button Variants

Different visual styles for various use cases and emphasis levels.

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

export function ButtonVariants() {
  return (
    <div className="flex flex-wrap justify-center gap-4">
      <Button variant="ghost">Ghost</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="default">Default</Button>
      <Button variant="secondary">Secondary</Button>
    </div>
  )
}
<Button variant="ghost">Ghost</Button>
<Button variant="outline">Outline</Button>
<Button variant="default">Default</Button>
<Button variant="secondary">Secondary</Button>

Button Sizes

Buttons in different sizes to fit various layout needs.

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

export function ButtonSizes() {
  return (
    <div className="flex flex-wrap items-end justify-center gap-4">
      <Button size="sm" className="h-8 px-3 text-xs">
        X Small
      </Button>
      <Button size="sm">Small</Button>
      <Button size="default">Medium</Button>
      <Button size="lg">Large</Button>
      <Button size="lg" className="h-12 px-8 text-base">
        X Large
      </Button>
    </div>
  )
}
<Button size="sm" className="h-8 px-3 text-xs">X Small</Button>
<Button size="sm">Small</Button>
<Button size="default">Medium</Button>
<Button size="lg">Large</Button>
<Button size="lg" className="h-12 px-8 text-base">X Large</Button>

Button Colors

Buttons with different color schemes for various actions and states.

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

export function ButtonColors() {
  return (
    <div className="flex flex-wrap justify-center gap-4">
      <Button>Primary</Button>
      <Button variant="secondary">Secondary</Button>
      <Button className="bg-blue-500 text-white hover:bg-blue-600">Info</Button>
      <Button className="bg-green-500 text-white hover:bg-green-600">
        Success
      </Button>
      <Button className="bg-yellow-500 text-white hover:bg-yellow-600">
        Warning
      </Button>
      <Button variant="destructive">Error</Button>
    </div>
  )
}
<Button>Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button className="bg-blue-500 hover:bg-blue-600 text-white">Info</Button>
<Button className="bg-green-500 hover:bg-green-600 text-white">Success</Button>
<Button className="bg-yellow-500 hover:bg-yellow-600 text-white">Warning</Button>
<Button variant="destructive">Error</Button>

Button with Icon

Enhance buttons with icons for better visual communication.

import { ArrowRight, RefreshCw, Star, Upload } from "lucide-react"

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

export function ButtonWithIcon() {
  return (
    <div className="flex flex-wrap justify-center gap-4">
      <Button variant="ghost">
        Read More
        <ArrowRight className="ml-2 h-4 w-4" />
      </Button>
      <Button variant="outline">
        Refresh
        <RefreshCw className="ml-2 h-4 w-4" />
      </Button>
      <Button>
        <Upload className="mr-2 h-4 w-4" />
        Upload Files
      </Button>
      <Button variant="secondary">
        Give Us Star
        <Star className="ml-2 h-4 w-4" />
      </Button>
    </div>
  )
}
import { ArrowRight, RefreshCw, Upload, Star } from "lucide-react"
 
<Button variant="ghost">
  Read More
  <ArrowRight className="ml-2 h-4 w-4" />
</Button>
<Button variant="outline">
  Refresh
  <RefreshCw className="ml-2 h-4 w-4" />
</Button>
<Button>
  <Upload className="mr-2 h-4 w-4" />
  Upload Files
</Button>

Loading Button

Buttons with loading states for asynchronous operations.

import { Loader2 } from "lucide-react"

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

export function ButtonLoading() {
  return (
    <div className="flex flex-wrap justify-center gap-4">
      <Button variant="ghost" disabled>
        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
        Loading
      </Button>
      <Button variant="outline" disabled>
        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
        Loading
      </Button>
      <Button disabled>
        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
        Loading
      </Button>
      <Button variant="secondary" disabled>
        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
        Loading
      </Button>
    </div>
  )
}
import { Loader2 } from "lucide-react"
 
;<Button disabled>
  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
  Loading
</Button>

Render buttons as anchor tags for navigation while maintaining button styling.

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

export function ButtonAsLink() {
  return (
    <div className="flex flex-wrap justify-center gap-4">
      <Button variant="ghost" asChild>
        <a href="#">Ghost</a>
      </Button>
      <Button variant="outline" asChild>
        <a href="#">Outline</a>
      </Button>
      <Button asChild>
        <a href="#">Default</a>
      </Button>
      <Button variant="secondary" asChild>
        <a href="#">Secondary</a>
      </Button>
    </div>
  )
}
<Button asChild>
  <a href="#">Link Button</a>
</Button>

Block Level Button

Full-width buttons that span the entire container width.

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

export function ButtonBlockLevel() {
  return (
    <div className="flex w-full flex-col gap-4">
      <Button variant="ghost" className="w-full">
        Ghost Block Level Button
      </Button>
      <Button variant="outline" className="w-full">
        Outline Block Level Button
      </Button>
      <Button className="w-full">Default Block Level Button</Button>
      <Button variant="secondary" className="w-full">
        Secondary Block Level Button
      </Button>
    </div>
  )
}
<Button className="w-full">Block Level Button</Button>

Pill Button

Buttons with fully rounded corners for a modern, pill-shaped appearance.

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

export function ButtonPill() {
  return (
    <div className="flex flex-wrap justify-center gap-4">
      <Button variant="ghost" className="rounded-full">
        Ghost
      </Button>
      <Button variant="outline" className="rounded-full">
        Outline
      </Button>
      <Button className="rounded-full">Default</Button>
      <Button variant="secondary" className="rounded-full">
        Secondary
      </Button>
    </div>
  )
}
<Button className="rounded-full">Pill Button</Button>

Custom Authentication Buttons

Styled buttons for popular authentication providers with custom colors and branding.

import { Bitcoin, Chrome, Facebook } from "lucide-react"

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

export function ButtonCustomAuth() {
  return (
    <div className="flex flex-wrap justify-center gap-4">
      <Button className="border-[#F7931A] bg-[#F7931A] text-white hover:bg-[#F7931A]/90">
        <Bitcoin className="mr-2 h-4 w-4" /> Connect Wallet
      </Button>
      <Button
        variant="outline"
        className="border-gray-300 bg-white text-gray-900 shadow-sm hover:bg-gray-50"
      >
        <Chrome className="mr-2 h-4 w-4" /> Continue with Google
      </Button>
      <Button className="border-[#1877F2] bg-[#1877F2] text-white hover:bg-[#1877F2]/90">
        <Facebook className="mr-2 h-4 w-4" /> Continue with Facebook
      </Button>
    </div>
  )
}
import { Bitcoin, Chrome, Facebook } from "lucide-react"
 
<Button className="border-[#F7931A] bg-[#F7931A] text-white hover:bg-[#F7931A]/90">
  <Bitcoin className="mr-2 h-4 w-4" /> Connect Wallet
</Button>
<Button variant="outline" className="border-gray-300 bg-white text-gray-900 shadow-sm hover:bg-gray-50">
  <Chrome className="mr-2 h-4 w-4" /> Continue with Google
</Button>
<Button className="border-[#1877F2] bg-[#1877F2] text-white hover:bg-[#1877F2]/90">
  <Facebook className="mr-2 h-4 w-4" /> Continue with Facebook
</Button>

Component Props

The Button component extends the standard HTML button element and accepts all native button attributes. In addition, it supports the following props:

variant

Controls the visual style of the button. Available options:

  • default - Primary button style with solid background
  • destructive - For destructive actions with error color
  • outline - Button with border and transparent background
  • secondary - Secondary button style with muted colors
  • ghost - Minimal button with no background or border
  • link - Button styled as a text link

size

Controls the size of the button. Available options:

  • default - Standard button size
  • sm - Small button size
  • lg - Large button size
  • icon - Square button optimized for icons

asChild

When set to true, the button will render its child element instead of a button tag. This is useful for rendering buttons as links or other interactive elements while maintaining button styling.

disabled

When set to true, disables the button and applies disabled styling. The button will not respond to user interactions.

className

Additional CSS classes to customize the button appearance. Use Tailwind CSS classes to override default styles or add custom styling.

Best Practices

  1. Choose the Right Variant: Use default for primary actions, outline or ghost for secondary actions, and destructive for dangerous operations
  2. Consistent Sizing: Maintain consistent button sizes within the same context or form
  3. Icon Usage: Place icons before text for actions and after text for directional cues
  4. Loading States: Always show loading state for asynchronous operations to provide user feedback
  5. Accessibility: Ensure buttons have descriptive text or aria-labels, especially for icon-only buttons
  6. Color Contrast: When using custom colors, ensure sufficient contrast for accessibility (WCAG 2.1 Level AA)
  7. Disabled State: Only disable buttons when necessary, and provide clear feedback about why the button is disabled