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 MaterialCommunityIcons by default), 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 '@onlynative/components'
import { ThemeProvider } from '@onlynative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'
export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<FAB
icon="plus"
accessibilityLabel="Add"
onPress={() => {}}
/>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}
Variants
| Variant | Container | Content |
|---|---|---|
primary | primaryContainer | onPrimaryContainer |
secondary | secondaryContainer | onSecondaryContainer |
tertiary | tertiaryContainer | onTertiaryContainer |
surface | surfaceContainerHigh | primary |
Sizes
import { FAB } from '@onlynative/components'
import { ThemeProvider } from '@onlynative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'
export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider>
<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>
)
}
| Size | Container | Icon | Shape |
|---|---|---|---|
small | 40 × 40 | 24dp | cornerMedium (12) |
medium (default) | 56 × 56 | 24dp | cornerLarge (16) |
large | 96 × 96 | 36dp | cornerExtraLarge (28) |
Extended
Pass a label to render an extended FAB. Extended FABs are always 56dp tall — the size prop is unavailable.
import { FAB } from '@onlynative/components'
import { ThemeProvider } from '@onlynative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'
export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider>
<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 '@onlynative/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 '@onlynative/components'
import { ThemeProvider } from '@onlynative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'
export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<FAB
icon="heart"
containerColor="#B00020"
contentColor="#FFFFFF"
accessibilityLabel="Favorite"
onPress={() => {}}
/>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}
Props
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
icon | IconSource | - | Yes | Icon to display. Accepts a string name (resolved via the theme's `iconResolver`, defaulting to `MaterialCommunityIcons`), a pre-rendered element, or a render function that receives `{ size, color }`. |
label | string | - | No | Optional 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. |
variant | enum | primary | No | Color variant. Controls container and content colors. |
size | enum | 'medium' | No | Physical size. Ignored when `label` is set. |
containerColor | string | - | No | Override the container (background) color. State-layer colors (hover, press) are derived automatically. |
contentColor | string | - | No | Override the content (icon + label) color. State-layer colors are derived automatically when no `containerColor` is set. |
labelStyle | StyleProp<TextStyle> | - | No | Style applied to the label text. Only used when `label` is set. |
style | StyleProp<ViewStyle> | - | No | Style applied to the root 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 | - | No | Called when the FAB is pressed. |
disabled | boolean | | No | Disables the FAB. |
accessibilityLabel | string | - | No | Accessible 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). |
onKeyDown | (event: { nativeEvent: { key?: string; }; }) => void | - | No | - |