Skip to main content

Button

iOS Android
Button on iOS Button on Android

Native button using MaterialButton with the Material 3 Expressive styles on Android and UIButton with a UIButton.Configuration on iOS. Each platform draws its own button: Android gets the Expressive shapes, sizes and press morph, iOS gets the system button of the iOS version it runs on.

import { Button } from 'react-native-platform-components';

<Button label="Save" onPress={save} />
<Button label="Cancel" variant="text" onPress={cancel} />
<Button icon="plus" variant="tonal" accessibilityLabel="Add" onPress={add} />

Props

PropTypeDescription
labelstringButton text. Omit for an icon-only button
iconPlatformIconIcon before the label, or alone. See Icons
variant'filled' | 'tonal' | 'outlined' | 'text' | 'elevated'Emphasis. See Variants. Default: 'filled'
size'xsmall' | 'small' | 'medium' | 'large' | 'xlarge'Size. See Sizes. Default: 'small'
shape'round' | 'square'Corner shape. See Shape. Default: platform default
disabledbooleanDisables the button
colorColorValueContainer (background) color
tintColorColorValueLabel and icon color
labelStyle{ fontFamily?, fontSize?, fontWeight?, fontStyle? }Label font. See Styling
accessibilityLabelstringScreen-reader label. Defaults to label; give icon-only buttons one
onPress() => voidCalled when the button is pressed

Android Props (android)

PropTypeDescription
rippleColorColorValueRipple shown while pressing
strokeColorColorValueOutline color (outlined variant)
material'm3' | 'expressive'Material style: Material 3 Expressive (default) or the classic Material 3 button. See Material style

Variants

Five levels of emphasis, from highest to lowest. Android uses the Material 3 Expressive button styles; iOS uses the closest UIButton.Configuration, so buttons look like every other button on that iOS version.

VariantAndroidiOS
filledFilled button (materialButtonStyle).filled()
tonalFilled tonal button (materialButtonTonalStyle).tinted()
outlinedOutlined button (materialButtonOutlinedStyle).bordered()
textText button (borderlessButtonStyle).plain()
elevatedElevated button (materialButtonElevatedStyle).gray()

Sizes

Material 3 Expressive defines five button sizes; iOS maps them onto UIButton.Configuration.Size.

SizeAndroid heightiOS
xsmall32dp.mini
small40dp (default).small
medium56dp.medium
large96dp.large
xlarge136dp.large

The button wraps its content. Give it alignSelf: 'stretch' or a width style to make it fill.

Shape

Material 3 Expressive buttons come in two shapes: round (a pill, the default) and square (rounded corners). On Android the shape morphs when pressed, the signature Expressive interaction, and selected buttons in a ButtonGroup morph too. On iOS round sets the capsule corner style and square the large one; unset keeps UIKit's dynamic corners.

<Button label="Round" shape="round" size="medium" />
<Button label="Square" shape="square" size="medium" />

Icons

icon accepts the same shapes as SegmentedControl: an SF Symbol or drawable name, an image asset, or an { ios, android } pair.

// Native symbol on each platform
<Button
label="Share"
icon={{
ios: { type: 'sfSymbol', name: 'square.and.arrow.up' },
android: { type: 'drawable', name: 'share' },
}}
/>

// One image asset for both, drawn as a tinted template
<Button label="Alerts" icon={{ type: 'image', source: require('./bell.png') }} />

A button with an icon and no label is an icon button: on Android it uses the Material 3 Expressive icon button styles (a square container that keeps the variant), on iOS an image-only UIButton. Always give it an accessibilityLabel.

Styling

Colors take any React Native ColorValue. Fonts follow the Text style conventions.

<Button
label="Brand"
color="#FF6B35"
tintColor="white"
labelStyle={{ fontWeight: '700', fontSize: 15 }}
android={{ rippleColor: 'rgba(255, 255, 255, 0.3)' }}
/>
PropAndroidiOS
colorbackgroundTintbaseBackgroundColor
tintColorText color and iconTintbaseForegroundColor
labelStyleTypeface and sizeTitle font
android.rippleColorPress ripple
android.strokeColorOutline (outlined variant)

Without these props the button takes its colors from the theme: the app's Material 3 theme or the brand color set with useNativeTheme on Android, the tint color on iOS.

Inside a FloatingToolbar

Buttons placed in a FloatingToolbar pick up the toolbar's button styles on Android, as Material's own toolbar children do: filled and text buttons become the toolbar's flat buttons, icon-only text buttons become the toolbar's icon buttons, and tonal keeps its container for an emphasized action.

Material style

android.material picks the Android design generation: 'expressive' (default) gives the Material 3 Expressive styles with their five sizes, two shapes and press morph; 'm3' gives the classic Material 3 button, which has one size and shape, so size and shape are ignored. Use 'm3' on screens that keep the older Material 3 look. Buttons inside a FloatingToolbar always take the toolbar's Expressive styles. SegmentedControl and ButtonGroup take the same prop.

Android theme

The Expressive look is a set of widget styles applied over your app theme, so your colors (and useNativeTheme) are kept. It works with a Theme.Material3 app theme and with the library's Material 3 fallback; see Android Theme Configuration.