Inputs/Button

Button

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

Themed

When to Use

Use Button when you need to:

  • Trigger an action like submit, save, delete, or navigate
  • Provide a clear call-to-action in forms or dialogs
  • Toggle visibility or state (open/close, expand/collapse)
  • Initiate processes like uploads, downloads, or searches
  • Create navigation that needs button styling (using asChild)

When Not to Use

  • Inline text navigation - use a standard link or variant="link"
  • Icon-only actions in toolbars - consider Icon Button for animated feedback
  • Binary toggle states - use Toggle or Switch
  • Grouped exclusive options - use Toggle Group

Default

The default appearance of the button component.

Sizes

Available size options: sm, default, lg, with matching icon variants (icon-sm, icon, icon-lg).

Variants

Different visual styles for various use cases and emphasis levels.

States

Interactive states including disabled and focus indicators.

Disabled

Focus

Tab to any button to see the focus ring. Focus styles include a ring with 3px width using the ring color from your theme.

Icon

Icon-only buttons for compact actions. Use size='icon' variants for square buttons.

With Icon

Buttons with leading or trailing icons. Spacing is automatically adjusted based on button size.

Rounded

Use the rounded-full class to create pill-shaped buttons.

Loading

Loading state with spinner icon. Combine disabled prop with Loader2 icon.

As Child

Use asChild prop to render buttons as links or other components while preserving button styles.

UX & Design Guidelines

Visual Hierarchy

Use variant="default" for primary actions (one per view), variant="secondary" or variant="outline" for secondary actions, and variant="ghost" for tertiary/low-emphasis actions. Reserve variant="destructive" for irreversible actions.

Spacing & Layout

When grouping buttons, use gap-2 for tight layouts or gap-4 for standard spacing. Place the primary action on the right in modal dialogs (following platform conventions). Use consistent sizing within a group.

Responsive Behavior

On mobile, consider using size="lg" for better touch targets (minimum 44×44px). Icon-only buttons should expand to include labels on larger screens when space permits. Full-width buttons (className="w-full") work well in narrow containers.

Color & Contrast

All button variants meet WCAG 2.1 AA contrast requirements. The primary variant uses bg-primary with text-primary-foreground for maximum contrast. Disabled states reduce opacity to 50% while maintaining readability.

Accessibility

Keyboard Navigation

  • Tab — Move focus to/from the button
  • Enter or Space — Activate the button
  • When using asChild with links, Enter navigates (standard link behavior)

Screen Reader Support

  • Buttons announce their text content and role automatically
  • Icon-only buttons require aria-label for screen reader users
  • Disabled state is announced via disabled attribute
  • Use aria-describedby for additional context on destructive actions

Focus Management

Visible focus ring with 3px width using focus-visible:ring-[3px]. Focus states meet WCAG 2.1 Level AA requirements. The ring color adapts to the button variant (destructive buttons use a red ring).

Touch Targets

Default size is 36px height (h-9), meeting minimum touch target recommendations. Use size="lg" (40px) for critical touch interactions. Icon buttons maintain square dimensions for consistent hit areas.

ARIA Attributes

{/* Standard button */}
<Button onClick={handleSubmit}>Submit Form</Button>

{/* Icon-only button - requires aria-label */}
<Button size="icon" aria-label="Search">
  <Search className="size-4" />
</Button>

{/* Button that controls expanded state */}
<Button
  aria-expanded={isOpen}
  aria-controls="dropdown-menu"
  onClick={toggleMenu}
>
  Menu
</Button>

{/* Destructive action with confirmation context */}
<Button
  variant="destructive"
  aria-describedby="delete-warning"
>
  Delete Account
</Button>
<span id="delete-warning" className="sr-only">
  This action cannot be undone
</span>

API Reference

The Button component accepts the following props in addition to standard button attributes.

PropTypeDefaultDescription
variant"default" | "outline" | "ghost" | "destructive" | "secondary" | "link""default"The visual style variant of the button.
size"default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg""default"The size of the button. Icon sizes create square buttons.
asChildbooleanfalseWhen true, the button will render its child as the root element, merging props and behavior.
disabledbooleanfalseWhen true, prevents user interaction and applies disabled styles.
classNamestringAdditional CSS classes to apply to the button.