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
labelprop as the accessibility label. For icon only buttons, passaccessibilityLabelexplicitly so screen readers have something to announce. - Accessibility State: Sets
disabledwhen the button is non-interactive, andbusyduring 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)