FloatingActionMenuButton
A floating-action circle whose press opens an anchored menu of related actions above it.
Implementation previewEvery example. In one place.
Explore every named example, including states, compositions, and theme variants.
Playground
Example source
packages/design-system/src/components/primitives/FloatingActionMenuButton/FloatingActionMenuButton.stories.tsxExport PlaygroundImplementation preview · Local Storybook build · 0.2.0-preview.1. Source specification status does not approve this runtime.
Stories + source JSON ↗Local specification source status: preview. Implementation preview pending sign-off.
A floating-action circle whose press opens an anchored menu of related actions above it.
Implementation API 1 entry point · source-derived preview
Read the actual callable API and preserve its composition constraints. Each union branch is a complete alternative; props marked forbidden cannot be supplied.
import { FloatingActionMenuButton } from '@cloakedinc/design-system';FloatingActionMenuButtonFloatingActionMenuButtonProps
packages/design-system/src/components/primitives/FloatingActionMenuButton/FloatingActionMenuButton.tsx:44
| Prop | Type | Presence | Notes |
|---|---|---|---|
icon | React.ReactNode | Required | Glyph rendered in the circle, usually an `Icon`. |
ariaLabel | string | Required | Accessible name for the trigger; also labels the menu. |
items | MenuItem[] | Required | Rows in the anchored menu (the shared `Menu` contract). |
onSelect | (value: string) => void | Required | Called with the pressed item's value; the menu closes first. |
hidden | boolean | undefined | Optional | Removes the trigger (e.g. while a sheet is open). |
defaultOpen | boolean | undefined | Optional | Renders the menu open on mount. |
haptic | HapticFeedback | undefined | Optional | Haptic feedback for trigger presses. Defaults to `true` (`light`).Source default: true |
className | string | undefined | Optional | Class hook on the anchor wrapper, e.g. lifting `bottom` above a tab bar. |
style | React.CSSProperties | undefined | Optional | Inline style override on the anchor wrapper. |
testId | string | undefined | Optional | Optional test selector. The popover gets `${testId}-menu`. |
Only explicit destructured parameter initializers are extracted. Other runtime defaults remain in implementation source.
Overview
The floating-action circle whose press opens an anchored menu of related actions —
the web counterpart of the iOS FloatingActionMenuButton (which wraps the native
pull-down menu). It shares FloatingActionButton's chrome and anchoring but is a
separate component: the interaction contract differs (aria-haspopup trigger,
open/close state, no loading), which is the FAB/SpeedDial boundary every major
design system draws.
Anchored menu
The popover opens upward from the trigger, right-aligned, inside the same
containing block — so it rides screen transitions with the FAB. Rows reuse the
shared Menu contract (MenuItem: leading icon, destructive, disabled) and
their haptics. Tapping outside or selecting a row closes it; selection closes
before onSelect fires.
Usage by variant
| Choice | Use when | Avoid when |
|---|---|---|
FloatingActionButton | The screen has ONE primary creation action — press runs it directly, with optional loading. | Cramming multiple actions behind a single tap. |
FloatingActionMenuButton | The screen has 2–5 closely related creation actions (compose via email / text / call). Press reveals them without leaving the screen. | A single action (use FloatingActionButton); long or data-driven pick lists (use Select or BottomSheet + Menu). |
Component specification
$schema
../../../specs/component-spec.schema.jsonParts
- Id
- trigger
- Label
- Trigger
- Description
- The FloatingActionButton chrome carrying menu-trigger semantics (aria-haspopup, aria-expanded).
- Id
- popover
- Label
- Popover
- Description
- The anchored surface above the trigger holding the menu rows.
- Id
- rows
- Label
- Menu rows
- Description
- Shared Menu rows with leading icons, destructive and disabled treatments.
- Id
- dismiss-layer
- Label
- Dismiss layer
- Description
- Invisible full-screen layer that closes the menu on an outside tap.
Allowed Design Choices
- Variants
- Default
- Label
- Default
- Description
- Single treatment; there is no variant axis.
- Sizes
- Default
- Label
- Default
- Description
- Fixed 48px trigger; the popover sizes to its rows.
Variants
- Id
- default
- Label
- Default
- Description
- Glass trigger circle with an anchored menu opening upward, right-aligned.
- Platforms
- ios
- web
Sizes
- Id
- default
- Label
- Default
- Description
- 48px trigger matching FloatingActionButton; popover height follows content.
Measurements
- Id
- trigger-diameter
- Label
- Trigger diameter
- Kind
- exact
- Token
- --cds-size-48
- Value
- 48
- Unit
- px
- Applies To
- trigger
- Id
- popover-gap
- Label
- Gap between trigger and popover
- Kind
- exact
- Token
- --cds-space-8
- Value
- 8
- Unit
- px
- Applies To
- popover
- Id
- popover-min-width
- Label
- Popover minimum width
- Kind
- exact
- Token
- --cds-size-240
- Value
- 240
- Unit
- px
- Applies To
- popover
- Id
- popover-radius
- Label
- Popover corner radius
- Kind
- exact
- Token
- --cds-radius-lg
- Value
- 20
- Unit
- px
- Applies To
- popover
Layout
- Alignment
- The popover is right-aligned to the trigger and opens upward with a bottom-right transform origin.
- Flow
- A fixed anchor wrapper owns positioning and hosts the trigger, popover, and dismiss layer, so a positioning override moves the whole assembly.
- Notes
- Not portaled, matching FloatingActionButton: a transformed screen container contains all three layers so the assembly rides screen transitions.
- The popover z-tier sits just above the trigger and far below the BottomSheet/Dialog overlay tier.
Typography And Color
- Typography
- None specified
- Colors
- Label
- Trigger container
- Description
- Shares FloatingActionButton's frosted-glass fill.
- Token
- --cds-fab-container
- Label
- Popover surface
- Description
- Frosted like the trigger, with the heavy menu-material blur for row legibility.
- Token
- --cds-fab-container
States
- Id
- closed
- Label
- Closed
- Description
- Only the trigger is visible; aria-expanded is false.
- Id
- open
- Label
- Open
- Description
- The popover scales in above the trigger; an outside tap or row selection closes it.
- Id
- hidden
- Label
- Hidden
- Description
- The hidden prop removes the whole assembly.
Behavior
- Label
- Toggle
- Description
- Pressing the trigger toggles the menu; it never runs an action directly and has no loading state.
- Label
- Select
- Description
- Row selection closes the menu, then calls onSelect with the row value.
- Label
- Dismiss
- Description
- Tapping anywhere outside the popover closes it without selecting.
Accessibility
- Label
- Menu trigger semantics
- Description
- The trigger exposes aria-haspopup=menu and reflects open state via aria-expanded.
- Label
- Menu semantics
- Description
- Rows render through Menu, which provides role=menu and per-row accessible names.
- Label
- Accessible name
- Description
- ariaLabel is required and labels both the trigger and the menu.
Content Adaptation
- Label
- Row count
- Description
- Use 2-5 closely related actions; longer or data-driven lists belong in Select or a BottomSheet.
Motion Haptics
- Motion
- Label
- Open
- Description
- The popover scales and fades in from its bottom-right anchor over the base duration; reduced-motion renders it instantly.
- Label
- Close
- Description
- Dismissal or selection scales and fades the popover out with the exit curve before unmounting.
- Haptics
- Label
- Trigger and rows
- Description
- The trigger fires a light haptic; rows fire their own through the shared Menu.
Platform Differences
- Platforms
- web
- Description
- iOS presents the native pull-down menu (glass, anchored by the system); web renders a private anchored popover styled with design-system surface tokens.
- Rationale
- WKWebView content cannot invoke the native menu, so the web version approximates its anchoring and motion with the shared Menu rows.
This design-owned implementation is ready to try and review. It does not establish product approval. Imported specifications retain their original review status.
Inspect version 0.2.0-preview.1 ↗