Fab button.
The Floating Action Button is the one primary action on a mobile surface — fixed near a screen edge, floating above content on the highest elevation layer Sprout has. A screen gets at most one. If a second action feels equally urgent, that is a sign the primary action was named wrong, not a reason to add a second FAB.
Try it
Anatomy
An icon on its own for Standard and Mini; an icon plus a short label for Extended. No Type mixes a label with no icon.
Type & size
Three fixed sizes, not a S/M/L scale like Buttons — pick the Type that matches the surface, don't scale one to fit.
56 × 56px — icon only40 × 40px — icon only, for a dense secondary surface48px tall, hugs its label — icon + textStandard is the default for a screen's one primary action. Mini is for a denser secondary surface (inside a panel, not the main screen) where a 56px target would crowd the content. Extended spends the extra width only when the action genuinely needs a label to be understood — don't reach for it just to fill space.
Elevation
The Floater layer — the same shadow as a dialog or a toast, and the reason a FAB never needs a border.
var(--shadow-floater) in light mode; in dark mode the shadow is inert and the lighter fill (var(--accent) flips to primary-300) does the lifting instead — the same light/dark mechanism documented in full on Shadow & elevation. Never add a second shadow or a border on top of it.
Placement
Fixed to a corner, clear of everything else that floats.
Do & don't
Specification
Every value is a token, ported from the Figma component.
Accessibility
Props (React)
Proposal — no React primitive ships yet. This is the target shape, not an import.
type FabButtonProps = {
type?: "standard" | "mini" | "extended"; // default "standard" — fixed sizes, not S/M/L
round?: boolean; // default true — pill/circle vs a squircle
icon: IconName; // 24px, required — a FAB is never icon-less
label?: ReactNode; // "extended" only; ignored otherwise
"aria-label": string; // required when type !== "extended"
onClick: () => void;
};