atom

Button

A versatile button component supporting multiple variants, sizes, colors, and states.

Overview

The Button component is a fundamental interactive element used for triggering actions, submitting forms, or invoking navigation via onPress. It supports multiple visual variants, sizes, and states to accommodate various use cases.

Props

Prop Type Default Description
label string - Button text content
onPress (event: GestureResponderEvent) => void - Gesture handler invoked on tap
variant 'primary' | 'secondary' | 'ghost' 'primary' Visual style variant
size 'sm' | 'md' | 'lg' 'md' Size variant
color 'base' | 'primary' | 'primary-alt' | 'success' | 'warning' | 'danger' 'primary' Semantic color scheme
radius 'square' | 'sm' | 'md' | 'lg' | 'rounded' 'md' Border radius variant
iconStart (props: { color: string; size: number }) => ReactNode - Icon displayed before label
iconEnd (props: { color: string; size: number }) => ReactNode - Icon displayed after label
icon (props: { color: string; size: number }) => ReactNode - Icon for icon-only button
disabled boolean false Whether the button is disabled
loading { active: boolean; color?: keyof Theme['colors'] } undefined Shows loading spinner; prevents onPress while active
accessibilityLabel string defaults to the label value Accessibility label for screen readers (falls back to label)
testID string - ID for testing purposes

Variants

Variant

The variant prop controls the visual prominence of the button.

<Button label="Primary" variant="primary" />
<Button label="Secondary" variant="secondary" />
<Button label="Ghost" variant="ghost" />

Sizes

Three size options for different contexts.

<Button label="Small" size="sm" />
<Button label="Medium" size="md" />
<Button label="Large" size="lg" />

Colors

Semantic colors communicate intent.

<Button label="Primary" color="primary" />
<Button label="Success" color="success" />
<Button label="Warning" color="warning" />
<Button label="Danger" color="danger" />

Radius

Control border radius from square to fully rounded.

<Button label="Square" radius="square" />
<Button label="Small" radius="sm" />
<Button label="Medium" radius="md" />
<Button label="Rounded" radius="rounded" />

Examples

States

<Button label="Default" />
<Button label="Disabled" disabled />
<Button label="Loading" loading={{ active: true }} />

With Icons

Icons must be a ReactNode. Icons are hidden during loading.

<Button label="Save" iconStart={(props) => <Save {...props} />} />
<Button label="Next" iconEnd={(props) => <MoveRight {...props} />} />
<Button icon={(props) => <Menu {...props} />} accessibilityLabel="hamburger-menu" radius="rounded" />

Accessibility

  • Accessibility Role: Sets accessibilityRole="button" so screen readers announce the element as a button.
  • Accessibility Label: Uses the label prop as the accessibility label. For icon only buttons, pass accessibilityLabel explicitly so screen readers have something to announce.
  • Accessibility State: Sets disabled when the button is non-interactive, and busy during loading.
  • Screen Reader: Announces button label and current state (disabled, loading).
  • WCAG Compliance: Meets AA standards for color contrast and touch target size.

Best Practices

  • Use descriptive labels that clearly indicate the action
  • Use only one primary button per context to indicate the main action
  • Reserve danger color for destructive or irreversible actions
  • Always pass a label or accessibilityLabel (especially for icon only buttons)