Button.tsx

Reusable pressable button component with primary and secondary variants

Purpose

This module provides the application’s standard button component, used across all screens for primary actions and secondary/cancel actions. It handles disabled and loading states and accepts an optional style override for per-callsite customization.

Its responsibilities include:

  • Rendering a Pressable with consistent border radius and padding
  • Applying variant-specific background and text styles
  • Displaying an ActivityIndicator in place of the label while loading
  • Disabling interaction and reducing opacity when disabled or loading
  • Applying a pressed-state opacity reduction when the button is interactive

Invariants

Disabled Combines Loading

The internal isDisabled flag is true when either disabled or loading is true.

Both the Pressable’s disabled prop and the disabled style are driven by this single flag, ensuring the button is never pressable while loading.


Pressed Style Excluded When Disabled

The pressed-state style (opacity: 0.88) is only applied when pressed is true and isDisabled is false.

This prevents a visual flicker if the OS delivers a press event to a newly-disabled button.


Style Override Appended Last

The style prop is appended as the final entry in the style array, allowing callers to override any base or variant style without specificity conflicts.


Variants

Primary

  • Background: theme.primary (#0B1220)
  • Label: theme.primaryText (#FFFFFF), weight 800, 15pt

Secondary

  • Background: theme.bg (#FFFFFF) with a 1px theme.border outline
  • Label: theme.text (#0B1220), weight 800, 15pt

Exports

Button

export function Button({
	label,
	onPress,
	variant?,
	loading?,
	disabled?,
	style?,
}: {
	label: string;
	onPress: () => void;
	variant?: "primary" | "secondary";
	loading?: boolean;
	disabled?: boolean;
	style?: ViewStyle;
}): JSX.Element

Props

PropDefaultDescription
labelButton text (hidden when loading is true)
onPressCallback invoked on press when not disabled
variant"primary"Visual style variant
loadingfalseShows spinner and disables interaction
disabledfalseDisables interaction and reduces opacity
styleundefinedAdditional ViewStyle merged after variant styles