Floating action menu
A floating action button that expands into secondary actions.
Draft
Specified, not implemented yet. It builds on Overlay for the scrim and the layer above the tab bar. The API may change.
One button floats above the content, in thumb reach. Pressing it doesn’t do one thing, it opens a short list of related ones: a text note, a checklist, a photo. The screen keeps one entry point for creating, and the choice comes after.
Tap the + button. The screen dims, the plus turns into a close, and three labeled actions rise from the button. Pick one, tap the dimmed screen, or press Escape (the back gesture in an app) to close.
The menu, frame by frame:
One button, above the tab bar, in thumb reach.
Scrim, labeled actions, the plus becomes a close.
The action runs and the menu collapses at once.
Six actions: that’s a sheet or a menu, not a FAB.
When to use it
- A main “create” action that comes in a few kinds: note, checklist, photo; message, group, channel.
- Screens where that action matters more than anything else, and stays useful wherever the user has scrolled.
Don’t use it for a single action: a plain floating button is enough. Don’t put more than four actions in it, or actions unrelated to each other. That’s a BottomSheet or a Menu.
How it works
| State | Button | Actions | Scrim |
|---|---|---|---|
| Closed | Plus | Hidden | None |
| Open | Close, rotated 45° | Visible, labeled | Dims the screen and the tab bar |
- Opening. Actions appear one after the other, closest to the button first, 40ms apart. The whole thing takes about 200ms.
- Closest is most used. The first action above the button is the one people pick most. The thumb travels less.
- Always labeled. Icons alone make users guess. Each action shows its label next to it.
- Closing. Picking an action, tapping the scrim, the close button, or the back gesture. The action runs as the menu collapses, without waiting for the animation.
- Placement. 16pt from the edge, above the tab bar, never over it.
Implementation
| Library | Used for |
|---|---|
| React state | open, toggled by the button. |
react-native-reanimated | Rotation of the icon, and staggered entering / exiting on the actions. |
| Overlay | The scrim and the layer that sits above the tab bar. |
| React Navigation | usePreventRemove so back closes the menu instead of leaving the screen. |
const [open, setOpen] = useState(false);
usePreventRemove(open, () => setOpen(false));
<FloatingActionMenu open={open} onOpenChange={setOpen} icon="plus">
<FloatingActionMenu.Action icon="edit" label="Text note" onPress={newNote} />
<FloatingActionMenu.Action
icon="check"
label="Checklist"
onPress={newChecklist}
/>
<FloatingActionMenu.Action icon="camera" label="Photo" onPress={newPhoto} />
</FloatingActionMenu>;Accessibility
- The button exposes
accessibilityState={{ expanded }}and its label changes: “Create”, then “Close”. - When the menu opens, focus moves to the first action. When it closes, focus goes back to the button.
- With Reduce Motion on, the actions appear without sliding and the icon swaps without rotating.
Related
- Overlay
- BottomTabBar, for a single main action
- BottomSheet, for longer lists of actions