Forms
⚛️react
Official
Simple

Button

A versatile button component with multiple variants, sizes, and states. Supports icons, loading states, and full accessibility features.

125.0k downloads2.8k starsWCAG AAv2.1.0Updated 3/20/2024
Improve

Preview

Installation

npm install @uicomponents/button

Dependencies

  • @radix-ui/react-slot^1.0.2
    Required
  • class-variance-authority^0.7.0
    Required
  • clsx^2.0.0
    Required
  • tailwind-merge^2.0.0
    Required

Usage

Basic Usage

The simplest button with default styling.

<Button>Click me</Button>

All Variants

Button supports six different visual variants for different contexts.

<div className=class="text-green-600 dark:text-green-400">"flex gap-2">
  <Button variant=class="text-green-600 dark:text-green-400">"default">Default</Button>
  <Button variant=class="text-green-600 dark:text-green-400">"secondary">Secondary</Button>
  <Button variant=class="text-green-600 dark:text-green-400">"destructive">Destructive</Button>
  <Button variant=class="text-green-600 dark:text-green-400">"outline">Outline</Button>
  <Button variant=class="text-green-600 dark:text-green-400">"ghost">Ghost</Button>
  <Button variant=class="text-green-600 dark:text-green-400">"link">Link</Button>
</div>

Sizes

Choose from four sizes: small, default, large, and icon.

<div className=class="text-green-600 dark:text-green-400">"flex items-center gap-2">
  <Button size=class="text-green-600 dark:text-green-400">"sm">Small</Button>
  <Button size=class="text-green-600 dark:text-green-400">"default">Default</Button>
  <Button size=class="text-green-600 dark:text-green-400">"lg">Large</Button>
  <Button size=class="text-green-600 dark:text-green-400">"icon">
    <Plus className=class="text-green-600 dark:text-green-400">"h-4 w-4" />
  </Button>
</div>

Loading State

Combine with a loading spinner for async actions.

<Button disabled>
  <Loader2 className=class="text-green-600 dark:text-green-400">"mr-2 h-4 w-4 animate-spin" />
  Please wait
</Button>

With Icon

Add icons before or after the button text.

<Button>
  <Mail className=class="text-green-600 dark:text-green-400">"mr-2 h-4 w-4" />
  Email
</Button>

<Button>
  Next
  <ArrowRight className=class="text-green-600 dark:text-green-400">"ml-2 h-4 w-4" />
</Button>

As Child

Use the button styling with a different element, like a link.

<Button asChild>
  <Link href=class="text-green-600 dark:text-green-400">"/login">Login</Link>
</Button>

Props

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.

asChild
booleanfalse

Change the default rendered element for the one passed as a child, merging their props and behavior.

disabled
booleanfalse

When true, prevents the user from interacting with the button.

onClick
(event: React.MouseEvent<HTMLButtonElement>) => void—

Event handler called when the button is clicked.

type
"button" | "submit" | "reset""button"

The type of button. Use 'submit' for form submission.

Accessibility

WCAG Level

AA

Keyboard Support

Yes

Screen Reader

Yes

Keyboard Navigation

  • Tab - Move focus to the button
  • Space / Enter - Activate the button

Screen Reader Notes

Buttons are announced as 'button' with their accessible name. Disabled buttons are announced as 'dimmed'.

Focus Management

Buttons have visible focus indicators with a 2px ring offset. Focus is automatically managed when buttons are dynamically added or removed.

ARIA Attributes

AttributeDescription
aria-disabledSet to 'true' when the button is disabled
aria-busySet to 'true' when the button is in a loading state
aria-pressedSet to 'true' when the button is in a pressed/toggle state

Customization

CSS Variables

VariableDefaultDescription
--primaryhsl(222 47% 11%)Primary button background color
--primary-foregroundhsl(210 40% 98%)Primary button text color
--secondaryhsl(210 40% 96%)Secondary button background
--destructivehsl(0 84% 60%)Destructive button background

Changelog

v2.1.0

March 20, 2024
  • Feature
    Added loading state support with aria-busy
  • Fix
    Fixed focus ring offset in high contrast mode
  • Performance
    Reduced bundle size by 12%

v2.0.0

February 15, 2024
  • Breaking
    Renamed 'primary' variant to 'default'
  • Feature
    Added 'link' variant
  • Feature
    Improved TypeScript inference

v1.5.0

January 10, 2024
  • Feature
    Added asChild prop for polymorphism
  • Fix
    Fixed disabled state cursor

Community

24 discussions
3 open issues
2 pull requests

Ready to use Button?

Copy the code above or explore more components in our library.

Explore More