Skip to content

MenuItemButton always clips its leadingIcon, hiding decorations such as Badge #192732

Closed
flutter/packages
#12986

Description

@JetA2

Steps to reproduce

When setting clipBehavior to Clip.none on a MenuItemButton, the property is not respected. This seems to be because the internal widget _MenuItemLabel is creating its own ClipRect which has the default clipBehavior of Clip.hardEdge.

This causes issues when the icon has a badge:

Image

Expected results

A menu item with Clip.none should not clip the icon's badge.

Actual results

The icon's badge is always clipped.

Code sample

Code sample
import 'package:material_ui/material_ui.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text('Test'),
          actions: [
            IconButton(
              icon: const Badge(
                label: Text('X'),
                backgroundColor: Colors.blueAccent,
                child: Icon(Icons.receipt),
              ),
              onPressed: () {},
            ),
          ],
        ),
        body: Center(
          child: MenuAnchor(
            builder: (_, controller, _) => IconButton(
              onPressed: () {
                if (controller.isOpen) {
                  controller.close();
                } else {
                  controller.open();
                }
              },
              icon: Icon(Icons.adaptive.more),
            ),
            menuChildren: [
              MenuItemButton(
                clipBehavior: Clip.hardEdge,
                leadingIcon: const Badge(
                  label: Text('X'),
                  backgroundColor: Colors.redAccent,
                  child: Icon(Icons.receipt),
                ),
                onPressed: () {},
                child: Text('Clip.hardEdge'),
              ),
              MenuItemButton(
                clipBehavior: Clip.none,
                leadingIcon: const Badge(
                  label: Text('X'),
                  backgroundColor: Colors.blueAccent,
                  child: Icon(Icons.receipt),
                ),
                onPressed: () {},
                child: Text('Clip.none'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.47.4, on macOS 26.5.2 25F84 darwin-arm64, locale en-DE) [636ms]
    • Flutter version 3.47.4 on channel stable at <redacted>
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 9584c6713b (4 days ago), 2026-09-10 15:25:10 -0700
    • Engine revision 06a2e2a110
    • Dart version 3.13.3
    • DevTools version 2.60.0
    • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios,
      cli-animations, enable-native-assets, enable-record-use, enable-swift-package-manager, omit-legacy-version-file,
      enable-lldb-debugging, enable-uiscene-migration

[✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0) [2.4s]
    • Android SDK at <redacted>
    • Emulator version 36.2.12.0 (build_id 14214601) (CL:N/A)
    • Platform android-37.0, build-tools 36.0.0
    • ANDROID_HOME = <redacted>
    • Java binary at: /opt/homebrew/opt/openjdk@17/bin/java
      This JDK is specified in your Flutter configuration.
      To change the current JDK, run: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment Homebrew (build 17.0.19+0)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 26.6) [1,548ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 17F113
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web [6ms]
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Network resources [410ms]
    • All expected network resources are available.

• No issues found!

Activity

  1. mbcorona commented on Sep 14, 2026

    @mbcorona
    Member

    Hi @JetA2, thanks, reproduced.
    A leadingIcon badge is always clipped by the menu item, with no way to opt out. Routing to the design team to decide whether thats intended or should be adjustable.

  2. added
    p: material_uimaterial_ui package in flutter/packages
    packageflutter/packages repository. See also p: labels.
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    team-designOwned by Design Languages team
    and removed
    in triagePresently being triaged by the triage team
    on Sep 14, 2026
  3. dkwingsmt commented on Sep 22, 2026

    @dkwingsmt
    Contributor

    I agree that this looks confusing. However, I'm wondering if the content is clipped by MenuItemButton at all. Because if the padding is created by, not MenuItemButton itself, but the list containing it, then there's no way for its content to overflow out of MenuItemButton. To achieve what you want, you'll want to removing the padding around MenuItemButtons. Can you take a look?

  4. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    P2Important issues not at the top of the work list
    triaged-designTriaged by Design Languages team
    on Sep 22, 2026
  5. QuncCccccc commented on Sep 23, 2026

    @QuncCccccc
    Contributor

    Hi @JetA2, thanks for filing this issue! I think MenuItemButton.clipBehavior is respected but for a different purpose. It is basically a ButtonStyleButton.clipBehavior, so when we set to Clip.hardEdge/Clip.antiAlias, anything painting outside of the button's shape will get clipped. For example, the code below shows a stadium-shape button, but changing it to Clip.none will make the button have an orange rectangle shape.

    MenuItemButton(
      clipBehavior: Clip.antiAlias, // flip to Clip.none to see a orange rectangle.
      style: const ButtonStyle(
        padding: WidgetStatePropertyAll<EdgeInsetsGeometry>(EdgeInsets.zero),
        shape: WidgetStatePropertyAll<OutlinedBorder>(StadiumBorder()),
        fixedSize: WidgetStatePropertyAll<Size>(Size(220, 48)),
      ),
      onPressed: () {},
      child: Container(width: 220, height: 48, color: Colors.orange),
    )

    But I think this issue is real and the badge should not be clipped. The badge is cut by a hard-coded ClipRect in _MenuItemLabel https://github.com/flutter/packages/blob/main/packages/material_ui/lib/src/menu_anchor.dart#L3330-L3348, and only leadings is wrapped in it; trailings are not, so a Badge on trailings should be fine.

  6. changed the title [-]MenuItemButton does not respect clipBehavior property[/-] [+]`MenuItemButton` always clips its `leadingIcon`, hiding decorations such as `Badge`[/+] on Sep 23, 2026
  7. github-actions commented on Oct 9, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  8. locked as resolved and limited conversation to collaborators on Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listhas reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: material_uimaterial_ui package in flutter/packagespackageflutter/packages repository. See also p: labels.team-designOwned by Design Languages teamtriaged-designTriaged by Design Languages teamwaiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions