FAB menu
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.kmdFAB section. Animation viamotion.kmdR9.1 spring +shape-library.kmdR2 morph.
Princípios
- *-6 items*— < 2 → use single FAB. > 6 → migrate to Navigation drawer.
- *taggered expansion*— items appear in sequence (50-100ms offset) via spring.
- *oggle morph*— main FAB morphs FAB → "X" shape on open; reverse on close.
- *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 (left |
| Toggle at top of viewport | Force below (auto-flip) |
| Toggle at side | Force opposite direction |
R4 — Expansion animation
On tap toggle (open):
- Toggle FAB morph: FAB shape → "X" (Cookie
4 → diagonal cross via `shapelibrary.kmd` Cookie-4 → Diamond morph). - Items appear: stagger 60ms offset per item; each via
motion-spatial-fastspring (slight overshoot). - Item labels: fade
in via `motioneffect-fast`. - Optional scrim: backdrop tint
surface-dim0.4 alpha (configurable).
On tap toggle (close) OR outside tap OR item selection OR ESC:
- Reverse — items fade-out in reverse order (stagger 30ms; faster than open).
- Toggle morph back: "X" → FAB shape.
- 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 (icon |
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.
Cross-link
- Companion:
buttons.kmdFAB variants - Animation drivers:
motion.kmdR9.1,shape-library.kmdR2 - Layout:
app-layout/window-size-classes.kmd(direction rules) - Migration when > 6 items:
navigation.kmddrawer - Refs: M3 FAB menu pattern; legacy speed-dial replaced