Skip to content

feat: modernize Menu to the latest Material Design specs #4977

Description

@adrcotfas
  • Modernize the Menu component to the latest specs. Reuse the newly introduced theme tokens (typography, motion, shape etc).
    See https://m3.material.io/components/menus for the full picture.
  • Extract component specific tokens for easier maintenance.
  • Get inspired from TextInput/TextField, Switch, Checkbox, FAB components which have gone through modernization.

Current State

Menu

MD3 spec: Menus
Specs link: https://m3.material.io/components/menus/specs

Color tokens

  • Container background: theme.colors.elevation[level2] which resolves to surfaceContainerLow ✅ (standard color scheme)
  • Menu.Item label text: onSurface
  • Menu.Item leading/trailing icon: onSurfaceVariant
  • Menu.Item disabled opacity: stateOpacity.disabled (0.38) ✅
  • No selected item state: spec defines tertiaryContainer bg / onTertiaryContainer text+icon for selected menu items
  • No vibrant color scheme (M3 Expressive): tertiaryContainer container / onTertiaryContainer icons+labels / tertiary selected bg / onTertiary selected text+icon

Spacing / sizing

  • Container paddingVertical: 8
  • Item min/max width: 112dp / 280dp ✅
  • Item paddingHorizontal: 12
  • Icon leading margin: 12dp after icon ✅
  • Item height: 48dp (standard), 32dp (dense) – baseline menu values ✅
  • Menu.Item label text uses bodyLarge; spec requires labelLarge
  • Menu.Item has no supporting text slot (bodySmall); spec anatomy includes optional supporting text per item
  • Menu.Item has no trailing supporting text slot (labelLarge); spec anatomy includes optional trailing text per item

Shape

  • Container: borderRadius: theme.roundness = 4dp; spec corner.large = 4 * roundness = 16dp ❌
  • First child item: spec corner.medium top corners; not implemented
  • Last child item: spec corner.medium bottom corners; not implemented
  • Selected item: spec corner.medium; not implemented
  • No per-item shape rounding at all; all items are rectangles

Behavior

  • Open/close: scale + opacity animation ✅ (but uses Easing.bezier(0.4, 0, 0.2, 1) from old M3 motion guidelines; M3 Expressive uses spring-based motion)
  • Dismisses on outside press ✅
  • Keyboard-aware positioning ✅
  • RTL support ✅
  • Escape key dismissal on web ✅
  • Back handler on Android ✅
  • No item selection state / active item support
  • No grouped layout (gaps between item groups); current workaround uses Divider which is not the spec-aligned grouping mechanism for vertical menus
  • No submenu support
  • No badge support on items
  • M3 Expressive vertical menu shape morphing (active container shape animates as focus moves to submenu) not implemented

Notes

  • The current component implements the baseline menu variant only. The M3 Expressive vertical menu is a largely new feature surface (new shapes, selection states, vibrant color scheme, submenu motion, grouped layout) that requires significant additions.
  • The borderRadius: theme.roundness bug is a significant visual regression vs spec – the container should be visibly rounded.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions