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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions