Skip to main content

Triggers an action or event when clicked. Fully accessible with keyboard navigation and perfect RTL support.

Preview

Installation

Terminalbash

Usage

Reacttsx

Examples

Variants

tsx

Sizes

tsx

With Icons

tsx

Loading State

tsx

Props

NameTypeDefaultDescription
variant
'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost' | 'link''primary'Visual style variant of the button
size
'sm' | 'md' | 'lg' | 'xl' | 'icon''md'Size of the button
loading
booleanfalseShows loading spinner and disables the button
disabled
booleanfalseDisables the button
asChild
booleanfalseRender as a child element (useful with Next.js Link)

Accessibility

Keyboard Navigation

  • Tab: Focus the button
  • Enter or Space: Activate the button

Screen Reader

The button role is automatically announced. Use aria-label for icon-only buttons.

ARIA Attributes

  • role="button": Automatically applied to button elements
  • aria-disabled: Set when disabled or loading

RTL Considerations

Icon Mirroring

Some icons should mirror in RTL (arrows, chevrons) while others should not (plus, heart, settings). Here's when to use each approach:

ScenarioSolution
Directional buttons (arrows, chevrons)ButtonArrow component
Non-directional icons (plus, heart)Button - no special handling
Edge cases (rare directional icons)rtl:rotate-180 class

Example

Buttons automatically support RTL layout. Icons positioned with logical properties (me-* for margin-inline-end, ms-* for margin-inline-start) will flip correctly.

LTR (English)

RTL (العربية)

Use Cases

Form submissions and actions

Call-to-action triggers

Dialog and modal openers

Toggle and state changes

Best Practices

Do

  • Use clear, action-oriented labels (e.g., "Save changes")
  • Show loading state for async actions
  • Use the primary variant for the main action on a page
  • Ensure sufficient size for touch targets (44×44px minimum)

Don't

  • Don't use buttons for navigation — use links or ButtonArrow
  • Don't place multiple primary buttons in one view
  • Don't disable without explaining why
  • Don't nest interactive elements inside buttons

Related Components