MD3
Expressive
MATERIAL DESIGN 3 EXPRESSIVE

Floating Action Button (FAB) Menu

The FAB menu opens from a Floating Action Button to display multiple related actions with smooth MD3 staggered animations.

Floating Action Button menus help group related actions under a single, prominent floating button. On tap, the FAB transforms and reveals a list of specific actions.

Introduction

The MD3 Expressive FAB Menu (or Speed Dial) is an advanced variant of the FAB. It allows a single primary action button to expand into a suite of related actions, saving screen space while keeping multiple options easily accessible. It features high-end staggered entrance animations and a fluid transformation of the main toggle button.

Anatomy

  • Main FAB (Toggle): The primary button that the user interacts with to open the menu. Often changes its icon (e.g., from "Add" to "Close") when expanded.
  • Menu Items: A vertical list of secondary action buttons that appear above the main FAB.
  • Labels: Descriptive text for each menu item, typically displayed next to the secondary icons.
  • Click-Outside Dismiss: Dismisses the open menu on outside pointer interactions without rendering a full-screen blocking overlay, preserving page scroll and background element interactions.

Variants

Sizes

The main toggle FAB supports the three standard MD3 Expressive sizes:

  • Baseline (Default / sm): 56dp
  • Medium (md): 80dp
  • Large (lg): 96dp
Loading demo...

Color Styles

FAB Menus can be styled using Primary, Secondary, or Tertiary container roles, which are applied consistently to the toggle and all menu items.

Loading demo...

Features

Staggered Animations

When the menu opens, the items appear one after another with a slight delay, creating a fluid, "waterfall" effect that is a hallmark of Material Design 3 Expressive.

Alignment

Items can be aligned to the start, end, or center relative to the toggle FAB, allowing for flexible positioning in different corners or edges of the screen.

Loading demo...

Click Outside to Close

Clicking or tapping anywhere outside the open menu container automatically dismisses it. Because this is powered by document-level event listeners rather than a blocking modal overlay, background elements (such as buttons, links, and scroll areas) remain interactive.

This behavior is enabled by default and can be disabled by setting closeOnBackdropClick={false}.

Loading demo...

Usage

Basic Usage

import { FABMenu, Icon } from "@bug-on/m3-expressive/buttons";
import * as React from "react";

export function Example() {
  const [isOpen, setIsOpen] = React.useState(false);

  const actions = [
    { id: "image", label: "Image", icon: <Icon name="image" />, onClick: () => {} },
    { id: "video", label: "Video", icon: <Icon name="videocam" />, onClick: () => {} },
    { id: "file", label: "File", icon: <Icon name="description" />, onClick: () => {} },
  ];

  return (
    <FABMenu
      expanded={isOpen}
      onToggle={setIsOpen}
      items={actions}
      aria-label="Create new content"
    />
  );
}

Disabling Click-Outside Dismiss

If you want the menu to only close via explicit interaction with the toggle button, an action item, or the Escape key, set closeOnBackdropClick={false}:

<FABMenu
  expanded={isOpen}
  onToggle={setIsOpen}
  items={actions}
  closeOnBackdropClick={false}
  aria-label="Sticky actions menu"
/>

Best Practices

Do

  • Use a FAB Menu for 3 to 6 related actions.
  • Ensure the main toggle icon clearly communicates that it can be expanded (e.g., an "Add" or "Menu" icon).
  • Provide clear labels for all secondary actions.
  • Use consistent color styles for all elements in the menu.

Don't

  • Don't use a FAB Menu for actions that are completely unrelated.
  • Avoid putting more than 6 actions in a single FAB Menu; it can become difficult to use and visually cluttered.
  • Don't use a FAB Menu if the actions are critical and should be always visible (use a Toolbar instead).

Accessibility

  • Keyboard: Press Esc to close the menu. Use ArrowUp/ArrowDown or Tab/Shift+Tab to navigate through items.
  • Outside pointer: Clicking or tapping outside automatically closes the menu.
  • Roles: Correctly implements role="group" on outer container, role="menu" on list, and role="menuitem" on actions.
  • States: Uses aria-expanded and aria-haspopup="menu" on the main toggle button.
  • Labels: Every menu item supports a label for visual clarity and accessibility.

API Reference

FABMenu

PropTypeDefaultDescription
expandedboolean—Required. Controlled open state.
onToggle(open: boolean) => void—Required. Open state change callback.
itemsFABMenuItemData[]—Required. Array of action items.
colorVariant"primary" | "secondary" | "tertiary""primary"MD3 container color role.
size"sm" | "md" | "lg""sm"FAB size variant controlling container dimensions per MD3 spec.
alignment"start" | "end" | "center""end"Menu items alignment relative to Toggle FAB.
closeOnBackdropClickbooleantrueWhen true, clicking/tapping outside the menu container closes it.
focusLastbooleantrueMoves focus to the last item (closest to FAB) when expanded.
classNamestring—Custom CSS className for container.
aria-labelstring—Accessible label for Toggle FAB and container group.

FABMenuItemData

PropertyTypeDefaultDescription
idstring—Required. Unique ID used for React keys and focus tracking.
labelstring—Descriptive label adjacent to icon. Omit for icon-only item.
iconReactNode—Required. Icon element.
onClick() => void—Required. Action callback when activated.
disabledbooleanfalseDisables interaction while preserving focusability (aria-disabled).
classNamestring—Additional CSS class names for item.