Skip to main content

FloatingActionButton

iOS Android
FloatingActionButton on iOS FloatingActionButton on Android

The Material floating action button (FAB): the screen's primary action, floating over the content. Android renders the real Material widgets, FloatingActionButton for an icon and ExtendedFloatingActionButton with a label, which shrinks to its icon and extends again with Material's own animation.

iOS has no floating action button. There, FloatingActionButton renders the system's prominent button in a round shape: a UIButton with the .prominentGlass() configuration on iOS 26 (Liquid Glass) and .filled() before, a circle with the icon, or a capsule with the icon and label. It is not a Material look-alike.

iOS 26iOS 18Android
Extended FloatingActionButton on iOS 26: a prominent glass capsuleExtended FloatingActionButton on iOS 18: a filled capsuleExtendedFloatingActionButton on Android
import { FloatingActionButton } from 'react-native-platform-components';

<FloatingActionButton
icon={{ ios: 'pencil', android: 'edit' }}
label="Compose"
onPress={compose}
style={{ position: 'absolute', right: 16, bottom: insets.bottom + 16 }}
/>

The button doesn't position itself on either platform: place it in your layout, usually absolutely at the bottom end of the screen, clear of the safe area (see Placement).

Props​

PropTypeDescription
iconPlatformIconThe icon. See Icons
labelstringLabel next to the icon: the extended FAB. Omit for an icon-only button
extendedbooleanWhether a button with a label shows it. Changing it animates. See Extended. Default: true
size'small' | 'regular' | 'medium' | 'large'Size. See Sizes. Default: 'regular'
colorColorValueContainer color. See Colors
tintColorColorValueIcon and label color
disabledbooleanDisables the button
accessibilityLabelstringScreen-reader label. Defaults to label; give icon-only buttons one
haptics'selection' | 'light' | 'medium' | 'heavy' | 'success' | 'warning' | 'error' | 'none'Haptic played when the button is pressed. See Haptics. Default: none
onPress() => voidCalled when the button is pressed
scrollViewNativeIDstringThe nativeID of a ScrollView or FlatList whose scrolling shrinks and extends the button. See Shrink on scroll
testIDstringTest identifier

Sizes​

sizeAndroid FABAndroid extended FABiOS
'small'40dp small FAB (in a 48dp touch target)56dp small extended44pt circle
'regular' (default)56dp FAB56dp small extended56pt circle
'medium'80dp medium FAB80dp medium extended80pt circle
'large'96dp large FAB96dp large extended96pt circle

Android uses the theme's FAB styles for each size (floatingActionButtonSmallStyle, floatingActionButtonStyle, floatingActionButtonMediumStyle, floatingActionButtonLargeStyle and the three extended styles), so a Material 3 Expressive app theme gets the Expressive FABs and a customized FAB style carries over. Material 3 Expressive drops the small FAB in favor of the medium one; small is the Material 3 small FAB. Extended FABs come in three sizes, so small and regular both use the 56dp one.

On iOS the button is a circle of the size's diameter (the small one keeps the 44pt minimum touch target), and extended, a capsule of the same height. The SF Symbol and the label scale with the size.

iOS 26iOS 18Android
The four sizes on iOS 26The four sizes on iOS 18The small, regular, medium and large FABs on Android

Extended​

A button with a label is the extended FAB. extended={false} shrinks it to its icon, and true extends it again:

  • Android: ExtendedFloatingActionButton.shrink() and extend(), Material's animation. The shrunk button is the FAB of the same size.
  • iOS: the capsule animates to a circle and back.

The button sits at the end (right, in left-to-right layouts) of its view and shrinks toward that edge, and the view keeps the extended width until the button has shrunk. Anchor the button by its end edge (right or end), as Material places a FAB, so it doesn't jump.

The label stays the button's accessibility label while shrunk.

Shrink on scroll​

Pass the nativeID of the ScrollView (or FlatList) the button floats over as scrollViewNativeID: an extended button shrinks to its icon while the content scrolls down, and extends again scrolling up, and always at the top of the content. There's no scroll handler to write; the native view follows the scroll view's offset.

Setting scrollViewNativeID turns the behavior on. It only applies to a button with a label, and extended={false} keeps the button shrunk regardless of scrolling. It works alongside a TabBar that follows the same ScrollView.

<View style={{ flex: 1 }}>
<FlatList nativeID="inbox" data={messages} renderItem={renderMessage} />
<FloatingActionButton
icon={{ ios: 'pencil', android: 'edit' }}
label="Compose"
scrollViewNativeID="inbox"
onPress={compose}
style={{ position: 'absolute', right: 16, bottom: insets.bottom + 16 }}
/>
</View>
iOS 26Android
At the topExtended over a list on iOS 26Extended over a list on Android
Scrolled downShrunk to its icon after scrolling on iOS 26Shrunk to its icon after scrolling on Android

A ScrollView nested in another vertical ScrollView needs nestedScrollEnabled on Android to scroll at all.

Colors​

The button takes the Material colors on Android (the primary container, with the "on" color for the icon and label), including a brand color set with useNativeTheme, and the tint color on iOS. color and tintColor override them:

  • Android: color is the backgroundTint and tintColor the icon tint and text color. The disabled colors stay Material's.
  • iOS: color is the configuration's baseBackgroundColor, which tints the prominent glass on iOS 26, and tintColor its baseForegroundColor. The iOS 26 prominent glass draws the icon and label with its own vibrancy, a light tint over the container color with a lighter rim rather than plain white, as it does for a Button with variant="prominentGlass".
iOS 26Android
Custom colors on iOS 26Custom colors on Android
<FloatingActionButton icon="plus" label="New" color="#FF6B35" tintColor="#FFFFFF" onPress={add} />

Placement​

The button is a view in your layout that takes its own size. Material floats the FAB 16dp from the bottom and end edges of the screen, above any bottom bar; do the same with absolute positioning and add the bottom safe-area inset, for example with react-native-safe-area-context:

const insets = useSafeAreaInsets();

<View style={{ flex: 1 }}>
<Content />
<FloatingActionButton
icon="plus"
accessibilityLabel="New message"
onPress={compose}
style={{ position: 'absolute', right: 16 + insets.right, bottom: 16 + insets.bottom }}
/>
</View>

On iOS, Apple's apps put the primary action in the navigation bar or toolbar rather than a floating button. FloatingActionButton gives a cross-platform screen the same action in the same place; if an iOS screen already has a toolbar, a Button there may fit better.

Not included​

  • The Material 3 Expressive FAB menu. The FAB that opens a list of related actions is only in Jetpack Compose (FloatingActionButtonMenu); Material Components for Android 1.14.0, the View library this component uses, doesn't have it.
  • Hiding the button (hide() / show()). Render it conditionally instead; on scroll, scrollViewNativeID shrinks an extended button.

Testing​

testID is on the button's view: tap it with element(by.id(...)). The Jest mock renders a Pressable with the button role, labeled by accessibilityLabel or label.

Android theme​

The FAB is a Material widget, so it works with a Theme.Material3 app theme and with the library's Material 3 fallback; see Android Theme Configuration.