Button

Buttons are the most fundamental interactive elements for users to perform actions. Trigger operations with clicks or taps — used for form submission, navigation, and more.

4
Variants
4
Colors
5
Sizes
Pure
React

Playground

Preview
solidD
Variant
Color
Size
Radius
Icon
Weight
Width
State
Label
<Button>Button</Button>

Variants

Style

Solid
Solid fill — the most visually prominent option
Submit, Save, Purchase
Outline
Neutral — blends with the background
View details, Edit
Ghost
Minimal — no background fill, ideal for toolbars
Toolbar, Nav
Link
Text link style — for inline actions
See more, Details

Solid Colors

Default
Dark — the most versatile CTA
Submit, Save
Primary
Brand color — for brand-emphasis actions
Sign up
Secondary
Supplementary — pairs with a primary action
Cancel, Back
Destructive
Destructive — for deletes and irreversible actions
Delete, Reset

Sizes

xs
Height28px
H-Padding10px
Gap4px
Icon14px
Font12px
sm
Height32px
H-Padding12px
Gap8px
Icon14px
Font13px
md
Height36px
H-Padding14px
Gap8px
Icon16px
Font14px
default
Height40px
H-Padding16px
Gap8px
Icon16px
Font14px
lg
Height48px
H-Padding24px
Gap8px
Icon16px
Font16px

Touch target: WCAG 2.5.8 requires a minimum 24px touch area. Even the smallest xs (28px) meets the WCAG standard.

Features

With Icons

<Button variant="outline" leftIcon={<Search />}>Search</Button>
<Button variant="outline" rightIcon={<ChevronRight />}>Continue</Button>
<Button variant="outline" leftIcon={<Search />} rightIcon={<ChevronRight />}>
  Search
</Button>

States

Solid Primary
Outline
// Solid Primary States
<Button color="primary">Default</Button>
<Button color="primary" loading>Loading</Button>
<Button color="primary" disabled>Disabled</Button>

// Outline States
<Button variant="outline">Default</Button>
<Button variant="outline" loading>Loading</Button>
<Button variant="outline" disabled>Disabled</Button>

API

Props

variant"solid"
"solid" | "outline" | "ghost" | "link"

Button style. Font weight: solid=600, outline/ghost/link=400

color"default"
"default" | "primary" | "secondary" | "destructive"

Color for solid variant (default=dark, primary=brand, secondary=secondary, destructive=error). Ignored for non-solid

size"default"
"xs" | "sm" | "md" | "default" | "lg" | "icon"

Button height and padding

radius"default"
"none" | "sm" | "base" | "default" | "lg" | "xl" | "2xl" | "3xl" | "full"

Border radius size (6px)

fullWidthfalse
boolean

Display at 100% width

loadingfalse
boolean

Loading state

disabledfalse
boolean

Disabled state

leftIconundefined
ReactNode

Left icon

rightIconundefined
ReactNode

Right icon

fontWeightundefined
"normal" | "semibold"

Override font weight. Defaults to variant default (solid=600, outline/ghost/link=400). Priority: direct prop > ButtonGroup context > variant default

selectedfalse
boolean

Selected state (outline/ghost only). outline=bg-background-muted, ghost=font-semibold. No effect on other variants

pressEffectundefined
boolean

Press effect (active:scale-pressed). Defaults to true. Set false to disable

asChildfalse
boolean

Render as Slot

Anatomy

1
2
3
Button
1
Container
Outer frame · border-radius · background
2
Icon
Left/right placement · optional
3
Label
Text label · required
4
Gap
Gap between elements

Best Practices

Recommended

  • One primary button per page
  • Action-oriented labels ("Submit", "Save")
  • Show loading state for async operations
  • Ensure sufficient touch area (WCAG 2.5.8: 24px+)

Avoid

  • Don't place multiple primary buttons side by side
  • Avoid vague labels like "Click here"
  • Don't disable buttons without reason
  • Don't use destructive for safe operations

Accessibility

Keyboard

TabMove focus
EnterActivate button
SpaceActivate button

WCAG 2.2 Compliance

  • Contrast ratio 4.5:1 or higher
  • Focus indicator
  • Native disabled attribute
  • aria-busy (auto-applied during loading)
  • aria-hidden (auto-applied to icons)
  • aria-pressed (auto-applied when selected)