Skip to main content

FAB

Floating action buttons (FABs) represent the screen's primary action. They appear in front of all other content, typically pinned to a corner. Follows the Material Design 3 Floating Action Button specification.

The icon prop accepts three forms — a string name (resolved via the theme's iconResolver, for example mdiResolver for MaterialDesignIcons), a pre-rendered React element from any icon library, or a render function that receives the resolved { size, color }. See the Icons guide for details.

Usage​

import { FAB } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<FAB
icon="plus"
accessibilityLabel="Add"
onPress={() => {}}
/>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

Variants​

VariantContainerContent
primaryprimaryContaineronPrimaryContainer
secondarysecondaryContaineronSecondaryContainer
tertiarytertiaryContaineronTertiaryContainer
surfacesurfaceContainerHighprimary

Sizes​

import { FAB } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 16 }}>
<FAB icon="plus" size="small" accessibilityLabel="Add (small)" onPress={() => {}} />
<FAB icon="plus" size="medium" accessibilityLabel="Add (medium)" onPress={() => {}} />
<FAB icon="plus" size="large" accessibilityLabel="Add (large)" onPress={() => {}} />
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}
SizeContainerIconShape
small40 × 4024dpcornerMedium (12)
medium (default)56 × 5624dpcornerLarge (16)
large96 × 9636dpcornerExtraLarge (28)

Extended​

Pass a label to render an extended FAB. Extended FABs are always 56dp tall — the size prop is unavailable.

import { FAB } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', gap: 12 }}>
<FAB icon="plus" label="Compose" onPress={() => {}} />
<FAB icon="pencil-outline" label="Edit" variant="surface" onPress={() => {}} />
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

The label doubles as the accessible name, so accessibilityLabel is optional in extended mode (override it if you need a more descriptive name for screen readers).

Bring your own icon library​

import { FAB } from '@rootnative/components'
import { Plus } from 'lucide-react-native'

<FAB
icon={({ size, color }) => <Plus size={size} color={color} />}
accessibilityLabel="Add"
/>

Custom Colors​

Override containerColor and contentColor to bypass the variant defaults. State-layer colors (hover, press, focus) are derived automatically.

import { FAB } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<FAB
icon="heart"
containerColor="#B00020"
contentColor="#FFFFFF"
accessibilityLabel="Favorite"
onPress={() => {}}
/>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

Props​

PropTypeDefaultRequiredDescription
iconIconSource-YesIcon to display. Accepts a string name (resolved via the theme's `iconResolver`, for example `mdiResolver`), a pre-rendered element, or a render function that receives `{ size, color }`.
labelstring-NoOptional text label. When provided, renders an extended FAB (56dp tall) and `size` is ignored. The label is also used as the accessible name unless `accessibilityLabel` is also set.
variantenumprimaryNoColor variant. Controls container and content colors.
sizeenum'medium'NoPhysical size. Ignored when `label` is set.
containerColorstring-NoOverride the container (background) color. State-layer colors (hover, press) are derived automatically.
contentColorstring-NoOverride the content (icon + label) color. State-layer colors are derived automatically when no `containerColor` is set.
labelStyleStyleProp<TextStyle>-NoStyle applied to the label text. Only used when `label` is set.
styleStyleProp<ViewStyle>-NoStyle for the component. The keys that place or size it in its parent — `alignSelf`, `flex`, `flexGrow`, `flexShrink`, `flexBasis`, `width`, the margins, `position`, the insets and `zIndex` — go to the outer wrapper, so the focus ring and the shadow move with it. `minWidth` and `maxWidth` go with a `width`; alone, they style the container. The wrapper sets no `alignSelf`, so the parent's `alignItems` places the component. In a parent that stretches its children, the component keeps its own width at the start edge. Every other key styles the container. Static form only — the function form `(state) => style` is not supported because the component drives its container background through Reanimated. Use `containerColor` / `contentColor` for state-aware styling.
onPress() => void-NoCalled when the FAB is pressed.
disabledbooleanNoDisables the FAB.
accessibilityLabelstring-NoAccessible name for screen readers. Required for icon-only FABs. When `label` is set, defaults to the label and may be omitted (override only if you need a more descriptive name).
hrefAttrs{ target?: string; rel?: string; download?: string | boolean; }-NoWeb only. The `target`, `rel` and `download` of the `<a>` that a view with an `href` renders, for example under Expo Router's `<Link asChild>`. `target: '_blank'` opens the link in a new tab. Native ignores it.
onKeyDown(event: PressableKeyDownEvent) => void-No-