FAB menu

mandatory

Material 3 Expressive FAB menu — successor of legacy "speed-dial". ToggleFloatingActionButton + N FloatingActionButtonMenuItems with staggered spring expansion + shape morph (FAB → "X"). Max 6 items (above → migrate to Navigation drawer).

Spec — FAB menu

Companion: buttons.kmd FAB section. Animation via motion.kmd R9.1 spring + shape-library.kmd R2 morph.

Princípios

  1. *-6 items*— < 2 → use single FAB. > 6 → migrate to Navigation drawer.
  2. *taggered expansion*— items appear in sequence (50-100ms offset) via spring.
  3. *oggle morph*— main FAB morphs FAB → "X" shape on open; reverse on close.
  4. *nchored above by default*— fan upward; auto-flip if window orientation requires.

R1 — Anatomia

              Item 3 ⬡  ← label
              Item 2 ⬡
              Item 1 ⬡
   ┌──────────────────┐
   │      [×]         │  ← toggle FAB (morphed)
   └──────────────────┘

Slots:

Slot Function
Toggle FAB Primary. Tap = open/close menu; shape morph between FAB (default) and "X" (open).
Menu items 1-6 secondary actions; each a small FAB + label chip.

R2 — Sizes

Toggle FAB sizes inherit buttons.kmd FAB:

  • Small (40dp) / Default (56dp) / Large (96dp).

Menu items: small FAB only (40dp) — visually subordinate.

R3 — Anchor + direction

Default: above (fan upward from toggle).

Auto-flip rules:

Window orientation/class Direction
Compact portrait (mobile) Above (default)
Compact landscape (mobile) Above (still — UX consistency)
MediumExpanded (tabletdesktop) Beside (leftoftoggle if RTL; rightoftoggle if LTR)
Toggle at top of viewport Force below (auto-flip)
Toggle at side Force opposite direction

R4 — Expansion animation

On tap toggle (open):

  1. Toggle FAB morph: FAB shape → "X" (Cookie4 → diagonal cross via `shapelibrary.kmd` Cookie-4 → Diamond morph).
  2. Items appear: stagger 60ms offset per item; each via motion-spatial-fast spring (slight overshoot).
  3. Item labels: fadein via `motioneffect-fast`.
  4. Optional scrim: backdrop tint surface-dim 0.4 alpha (configurable).

On tap toggle (close) OR outside tap OR item selection OR ESC:

  1. Reverse — items fade-out in reverse order (stagger 30ms; faster than open).
  2. Toggle morph back: "X" → FAB shape.
  3. Scrim fades out.

R5 — Threshold + alternatives

Item count Recommended pattern
1 Single FAB (no menu)
2-6 FAB menu (this spec)
7+ Migrate to Navigation drawer ou Bottom sheet

Anti-pattern: hiding important destructive actions inside FAB menu (use Confirm dialog instead).

R6 — Surface bindings

Surface API
Flutter KoderFabMenu({toggleIcon, items, onItemTap, direction}) em koder_kit/ (futuro)
Web <koder-fab-menu> em koder_web_kit
Compose Android KoderFabMenu (futuro)
SwiftUI iOS idem (futuro)
CLI / TUI n/a

R7 — Acessibilidade

  • Toggle: role="button" aria-haspopup="menu" aria-expanded="<state>" aria-label="More actions".
  • Items: role="menuitem" aria-label="<action>".
  • Keyboard: Tab to toggle + Enter opens; Arrow Up/Down navigates items; Enter selects; ESC closes.
  • Focus trap: while open, Tab cycles within items + toggle only.
  • Screen reader announces toggle state change.

R8 — i18n

Key en-US pt-BR
fab_menu.toggle.label_closed "More actions" "Mais ações"
fab_menu.toggle.label_open "Close menu" "Fechar menu"

R9 — Reduced-motion

Open/close: instant. Toggle morph: skip; show static "X" icon swap. Staggered appearance: replaced by simultaneous fade-in (no stagger).

R10 — Per-preset variation

Preset FAB menu style
material3 / material_expressive Default morph + stagger spring
material2 Simple icon swap + linear stagger (no spring)
terminal_classic List below toggle (no animation)
brutalist Sharp items; no morph
cyberpunk_neon Default + glow on items + connection lines toggle ↔ items
minimalist_mono No labels (icononly); ultraspartan

T-suite

  • *1*Mount closed: toggle FAB visible; items hidden.
  • *2*Open: tap toggle → items appear staggered; toggle morphs to X.
  • *3*Item count 3: render 3 items vertically above toggle.
  • *4*Direction auto-flip: position toggle at top edge → menu opens BELOW.
  • *5*Tablet landscape: render direction = beside.
  • *6*Item select: tap item → menu closes; onItemTap fires.
  • *7*Outside tap closes: tap scrim → menu closes.
  • *8*ESC closes: menu open + ESC → closes.
  • *9*Keyboard nav: arrows + Enter functional.
  • *10*Reduced-motion: instant open/close.
  • *11*A11y: focus trap; aria-expanded transitions.
  • *1*> 6 items: spec validation OR runtime warning suggesting Navigation drawer.

Source: ../home/koder/dev/koder/meta/docs/stack/specs/components/fab-menu.kmd