Skip to main content

Button

Inputs & Controls

Button

Material 3 button set with text, outlined, contained, tonal, and elevated variants.

Usage

Trigger primary workflows, confirm actions, or launch dialogs across surfaces.

Highlights

  • Compound component pattern with Button.Text, Button.Icon
  • State layer + ripple feedback
  • Built-in ActivityIndicator for loading states

When to use it

  • You need accessible CTA with consistent spacing.
  • Buttons must adapt to tokens via variant system.

Compound Components

ComponentDescription
Button.TextRenders styled text within the button. Automatically applies typography based on button size.
Button.IconRenders an icon. Accepts `name` and `type` props for icon selection.
Button.ActivityIndicatorRenders a loading spinner. Automatically inherits size and color from button context.

Examples

Basic Usage with Button.Text

Use Button.Text compound component to render text within the button.

Preview (Web)
import { Button } from 'react-native-molecules/components/Button';

export default function Example() {
  return (
      <Button variant="contained" onPress={() => console.log('Pressed')}>
          <Button.Text>Submit</Button.Text>
      </Button>
  );
}

Button Variants

Preview (Web)
import { View } from 'react-native';
import { Button } from 'react-native-molecules/components/Button';

export default function Example() {
  return (
      <View style={{ gap: 8, alignItems: 'center' }}>
          <Button variant="text">
              <Button.Text>Text Button</Button.Text>
          </Button>
          <Button variant="outlined">
              <Button.Text>Outlined Button</Button.Text>
          </Button>
          <Button variant="contained">
              <Button.Text>Contained Button</Button.Text>
          </Button>
          <Button variant="contained-tonal">
              <Button.Text>Tonal Button</Button.Text>
          </Button>
          <Button variant="elevated">
              <Button.Text>Elevated Button</Button.Text>
          </Button>
      </View>
  );
}

With Icon

Use Button.Icon to add icons before or after text.

Preview (Web)
import { View } from 'react-native';
import { Button } from 'react-native-molecules/components/Button';

export default function Example() {
  return (
      <View style={{ gap: 8, alignItems: 'center' }}>
          {/* Icon before text */}
          <Button variant="contained">
              <Button.Icon name="plus" type="material-community" />
              <Button.Text>Add Item</Button.Text>
          </Button>
          
          {/* Icon after text */}
          <Button variant="outlined">
              <Button.Text>Next</Button.Text>
              <Button.Icon name="chevron-right" type="material-community" />
          </Button>
          
          {/* Icons on both sides */}
          <Button variant="elevated">
              <Button.Icon name="account" type="material-community" />
              <Button.Text>Profile</Button.Text>
              <Button.Icon name="chevron-right" type="material-community" />
          </Button>
      </View>
  );
}

Shape Variants

Buttons support rounded (default) and square shapes.

Preview (Web)
import { View } from 'react-native';
import { Button } from 'react-native-molecules/components/Button';

export default function Example() {
  return (
      <View style={{ flexDirection: 'row', gap: 8, flexWrap: 'wrap' }}>
          <Button variant="contained" shape="rounded">
              <Button.Text>Rounded</Button.Text>
          </Button>
          <Button variant="contained" shape="square">
              <Button.Text>Square</Button.Text>
          </Button>
      </View>
  );
}

Sizes

Buttons support xs, sm (default), md, lg, and xl sizes.

Preview (Web)
import { View } from 'react-native';
import { Button } from 'react-native-molecules/components/Button';

export default function Example() {
  return (
      <View style={{ gap: 8, alignItems: 'flex-start' }}>
          <Button variant="contained" size="xs">
              <Button.Text>Extra Small</Button.Text>
          </Button>
          <Button variant="contained" size="sm">
              <Button.Text>Small</Button.Text>
          </Button>
          <Button variant="contained" size="md">
              <Button.Text>Medium</Button.Text>
          </Button>
          <Button variant="contained" size="lg">
              <Button.Text>Large</Button.Text>
          </Button>
          <Button variant="contained" size="xl">
              <Button.Text>Extra Large</Button.Text>
          </Button>
      </View>
  );
}

Loading State with ActivityIndicator

Use Button.ActivityIndicator to show a loading spinner. Set disabledPress to prevent interaction while loading.

Preview (Web)
import { useState } from 'react';
import { View } from 'react-native';
import { Button } from 'react-native-molecules/components/Button';

export default function Example() {
  const [isLoading, setIsLoading] = useState(false);
  
  const handlePress = () => {
      setIsLoading(true);
      setTimeout(() => setIsLoading(false), 2000);
  };
  
  return (
      <View style={{ gap: 8, alignItems: 'center' }}>
          {/* Loading with text */}
          <Button 
              variant="contained" 
              onPress={handlePress}
              disabledPress={isLoading}
          >
              {isLoading ? (
                  <>
                      <Button.ActivityIndicator />
                      <Button.Text>Loading...</Button.Text>
                  </>
              ) : (
                  <Button.Text>Submit</Button.Text>
              )}
          </Button>
          
          {/* Loading spinner only */}
          <Button variant="contained" disabledPress>
              <Button.ActivityIndicator />
          </Button>
      </View>
  );
}

Disabled State

Preview (Web)
import { View } from 'react-native';
import { Button } from 'react-native-molecules/components/Button';

export default function Example() {
  return (
      <View style={{ gap: 8, alignItems: 'center' }}>
          <Button variant="contained" disabled>
              <Button.Text>Disabled Contained</Button.Text>
          </Button>
          <Button variant="outlined" disabled>
              <Button.Text>Disabled Outlined</Button.Text>
          </Button>
          <Button variant="text" disabled>
              <Button.Text>Disabled Text</Button.Text>
          </Button>
      </View>
  );
}
PropTypeDefaultDescription
childrenReactNodeContent of the button. Use Button.Icon and Button.Text compound components.
testIDstring | undefinedtestID to be used on tests.
accessibilityLabelstring | undefinedAccessibility label for the button. This is read by the screen reader when the user taps the button.
accessibilityHintstring | undefinedAccessibility hint for the button. This is read by the screen reader when the user taps the button.
elevationMD3Elevation | undefined
variantButtonVariant | undefinedMode of the button. You can change the mode to adjust the styling to give it desired emphasis. - `text` - flat button without background or outline, used for the lowest priority actions, especially when presenting multiple options. - `outlined` - button with an outline without background, typically used for important, but not primary action – represents medium emphasis. - `contained` - button with a background color, used for important action, have the most visual impact and high emphasis. - `elevated` - button with a background color and elevation, used when absolutely necessary e.g. button requires visual separation from a patterned background.
shapeButtonShape | undefinedShape of the button. - `rounded` - fully rounded corners (default) - `square` - square corners with medium border radius
disabledboolean | undefinedWhether the button is disabled. A disabled button is greyed out and `onPress` is not called on touch.
styleStyleProp<TextStyle>
sizeButtonSize | undefined
stateLayerPropsViewProps | undefinedprops for the stateLayer
textRelatedStyleStyleProp<TextStyle>
disabledPressboolean | undefined
Defined in react-native-molecules/components/Button