Skip to content

Enhance Menu / Select to fully match Material 3 Expressive specs (incl. floating UI, grouping, submenus, selection, density) #236

@e1berd

Description

@e1berd

The problem

The current <Menu> / Select implementation looks and behaves more like a Material 2 / MDC menu:

Image

vs

Image

rectangular shape with small corner radius (~4px instead of M3 ~28dp for expressive vertical menus)
missing proper surface elevation + dynamic color overlay / tint
entrance animation is very basic (usually just opacity + small scale) → missing expressive motion (overshoot, shared axis / container transform)
ripple / state layers on items don't always follow latest M3 tokens
no tonal/filled variant support for menu surface
spacing, typography variants and divider insets feel closer to M2

What Material 3 (especially Expressive update from Nov 2025) expects (roughly, based on https://m3.material.io/components/menus/specs):

  • Container: large rounded corners (~28dp from shape.large tokens), elevation level 2–3 with shadow and overlay
  • Surface: variants like standard (surface-based, low emphasis), vibrant (tertiary-based, high emphasis) + dynamic tint/overlay (e.g., surface container low, tertiary container)
  • Animation: enter/exit with fade through + scale (1.1–1.2 overshoot), or container transform/shared axis; submenu motion with shape morphing (corners adjust dynamically)
  • Items: proper state layers (hover, focus, pressed, selected, disabled), ripple effects, larger touch targets (min 48dp height), support for leading/trailing icons, badges, supporting text
  • Positioning: auto-repositioning to avoid screen edges; floating in front of other UI, triggered by buttons/text fields/selected text
  • Grouping (sections/labels): Use gaps (more expressive than dividers) to bundle similar items — limit to 1-2 per menu, avoid in scrollable; optional label text for sections (not to confuse with simple dividers, which are for separation only)
  • Dividers: Optional, with insets (e.g., 8dp padding), height 1dp
  • Submenus/cascading: Supported with non-overlapping reveal next to parent item, expressive motion (focus shifts with hover, shape morphing); better for large screens
  • Selection types: Single-select (only one item active, auto-deselect others) or multi-select (multiple checked, menu stays open until dismiss) — show checkmarks/vibrant highlights for selected
  • Spacing/density: Adjustable density levels (0 to -3 on web-like impl), reducing padding between MenuItems (e.g., from standard 12dp to compressed); container width min 112dp, max 280dp
  • Other: Scrollable support with persistent scrollbars; accessibility slots; no buttons/switches inside items
Image

Perhaps this component might need a universal wrapper? For example, something like this:

<Floating>  
  {#snippet reference()}  
    <Button> click me </Button>  
  {/snippet}  
  
  <Menu>  
    <MenuItem> Floating Content! </MenuItem>  
  </Menu>  
</Floating>  

This would help implement the behavior described in the documentation M3

ps: I would also like to point out that the select on Firefox and Firefox-based browsers is displayed as a simple native select:

Image Image

pps: sorry for my so-so english, I’m still learning

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions