About this animation
Related guides
A floating action menu that opens along an arc and collapses into its button, with configurable label fonts and accent color.
How it works
- The component measures its own container and places a Nimbus workspace scene, glass tab bar, and 60 pt gradient FAB from that layout.
- One continuous
progressshared value drives the veil, plus-to-close rotation, gooey Skia metaballs, and every action's spring path. - Static icons are batched by visual group, while the five action icons, gooey trails, and rotating plus share one Skia canvas. The screen stays under six WebGL contexts on web.
- Gesture Handler tracks a touch from the FAB through the 150-degree arc, selecting the nearest action without React state on every frame.
- Release over an action calls
onAction, shows a compact confirmation toast, and reverses the same arc in reverse order. - Reduced motion replaces the arc and gooey transition with a calm fade while preserving tap access to every action.
Install
npx expo install expo-blur expo-linear-gradient @shopify/react-native-skia react-native-gesture-handler react-native-reanimated react-native-workletsUsage
import RadialFabMenu from './RadialFabMenu';
export function WorkspaceScreen() {
return <RadialFabMenu onAction={(label) => trackAction(label)} />;
}The forwarded ref exposes open(), close(), and playUploadMoment() for product tours and demos.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
actions | typeof ACTIONS | ACTIONS | Action labels and colors are fixed to the built-in Lucide action set. |
onAction | (label: string) => void | undefined | Called after an action is selected. |
fontFamily | string | undefined | Typeface used by the menu labels. |
selectedFontFamily | string | undefined | Typeface used by the selected action label. |
style | StyleProp<ViewStyle> | undefined | Optional container style. |
accessibilityLabel | string | 'Radial action menu' | Accessible label for the menu. |
testID | string | undefined | Test identifier applied to the outer container. |
accentColor | string | '#7C5CFF' | Accent used by the primary action and navigation. |
Compatibility
- Expo SDK 58, React Native 0.88, Reanimated 4.7, Worklets 0.13, Skia 2.14.
- iOS, Android, and web are supported by the implementation.
expo-bluris included in Expo Go. Skia and gesture interactions may require a development build in a client project.
Accessibility
The menu exposes a labeled menu role, a toggle action, and one accessibility action for every radial option. Every action remains reachable by a 44 pt-plus touch target. useReducedMotion() removes the arc and gooey movement and uses a short fade instead, and confirmations are announced as live alerts.
Why this one
The familiar radial FAB pattern becomes a believable Nimbus workspace rather than a floating demo control. A single interruptible progress value keeps the liquid departure, stagger, veil, and plus-to-close rotation coherent, while tinted action materials, a spacious 150-degree fan, grouped web-safe icon rendering, and the guided upload tour create a useful product moment instead of decorative motion.
Customization notes
Movement follows gestures, scroll position, or interruptible spring physics. A global duration is not exposed; reduced-motion fades retain their short fixed timing.




