Fab positions itself absolute inset-0, so it reaches for a backdrop that fills its nearest positioned ancestor. Wrap it in a relative container sized to whatever area it should float over, usually the whole screen. Give one action a color to make it stand out from the rest of the stack:
One boolean, two timing tracks.open drives the icon rotation, the backdrop opacity, and every action's entrance and exit, but opening and closing each get their own duration and easing pair (200ms ease-out in, 160ms ease-in out), so closing always reads snappier than opening.
Timing curves, not springs. This FAB is meant to be opened and closed repeatedly in a single session, a spring's overshoot on the tenth open starts to read as sloppy rather than charming, so every animated value here is a deterministic withTiming curve.
The backdrop and action stack never unmount. Both stay in the tree at all times with pointerEvents toggled between "auto" and "none" based on open, so a closing frame still gets to render its fade-out instead of being cut off, and a fully-closed frame doesn't eat touches meant for whatever sits behind the FAB.
The stagger reverses on close. Opening delays each action by index * 40ms, so the action nearest the FAB leads. Closing uses the reverse order, so the farthest action tucks away first and the nearest lingers closest to where the icon is reforming.
Action bubbles are secondary by default. Without a color, each bubble matches its label chip, a white or neutral-800 background rather than a clone of the main FAB's bold color, so the open stack reads as a fanned-out menu instead of three duplicate buttons. Passing color on one action gives it a solid bubble with a white icon so it can still stand out.
Tapping an action closes first, then fires onPress. The haptic plays immediately so the tap always feels acknowledged, even if onPress kicks off something slow like a navigation transition. Tapping the backdrop just closes, no action fires.