Skip to content

No Accessibility label on expanded menu of MenuAnchor #184876

Closed
flutter/packages
#12806

Description

@ravi-coforge

Steps to reproduce

  1. Open the Menu

Expected results

There should be a way to add an accessibility label to the expanded menu.

Actual results

There is no way to add an accessibility label to the expanded menu.

Code sample

Code sample
import 'package:flutter/material.dart';

/// 🔥 DUMMY ENTITY (same as your StateEntity)
class StateEntity {
  final String state;
  final String abbreviation;

  StateEntity({required this.state, required this.abbreviation});
}

class DropdownDemoPage extends StatefulWidget {
  const DropdownDemoPage({super.key});

  @override
  State<DropdownDemoPage> createState() => _DropdownDemoPageState();
}

class _DropdownDemoPageState extends State<DropdownDemoPage> {
  final MenuController _menuController = MenuController();

  bool _isDropdownOpen = false;
  String? selectedState;

  /// 🔥 HARDCODE DATA
  final List<StateEntity> states = <StateEntity>[
    StateEntity(state: 'Maharashtra', abbreviation: 'MH'),
    StateEntity(state: 'Gujarat', abbreviation: 'GJ'),
    StateEntity(state: 'Delhi', abbreviation: 'DL'),
    StateEntity(state: 'Karnataka', abbreviation: 'KA'),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Dropdown Demo')),
      body: Padding(
        padding: const EdgeInsets.fromLTRB(16, 40, 16, 16),
        child: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
            return MenuAnchor(
              controller: _menuController,
              crossAxisUnconstrained: false,

              onOpen: () {
                setState(() => _isDropdownOpen = true);
              },
              onClose: () {
                setState(() => _isDropdownOpen = false);
              },

              style: MenuStyle(
                backgroundColor:
                    const WidgetStatePropertyAll<Color>(Colors.white),
                surfaceTintColor:
                    const WidgetStatePropertyAll<Color>(Colors.transparent),
                shape: WidgetStatePropertyAll<RoundedRectangleBorder>(
                  RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(8),
                  ),
                ),
                fixedSize: WidgetStatePropertyAll<Size>(
                  Size(constraints.maxWidth, 200),
                ),
              ),

              /// 🔥 DROPDOWN ITEMS
              menuChildren: states.map((StateEntity e) {
                final bool isSelected = e.abbreviation == selectedState;

                return MenuItemButton(
                  onPressed: () {
                    setState(() {
                      selectedState = e.abbreviation;
                    });
                    _menuController.close();
                  },
                  leadingIcon: isSelected
                      ? const Icon(Icons.check)
                      : const Icon(Icons.check, color: Colors.transparent),
                  child: Padding(
                    padding: const EdgeInsets.symmetric(vertical: 10),
                    child: Text(e.state),
                  ),
                );
              }).toList(),

              /// 🔥 MAIN FIELD UI
              builder: (BuildContext context, MenuController controller, Widget? child) {
                return MergeSemantics(
                  child: Semantics(
                    button: true,
                    label: 'State Dropdown',
                    onTap: () {
                      controller.isOpen
                          ? controller.close()
                          : controller.open();
                    },
                    container: true,
                    child: InkWell(
                      onTap: () {
                        controller.isOpen
                            ? controller.close()
                            : controller.open();
                      },
                      child: SizedBox(
                        width: double.infinity,
                        child: InputDecorator(
                          decoration: InputDecoration(
                            contentPadding: const EdgeInsets.symmetric(
                                horizontal: 12, vertical: 14),
                            border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(4),
                              borderSide: BorderSide(
                                color:
                                    _isDropdownOpen ? Colors.blue : Colors.grey,
                                width: _isDropdownOpen ? 2 : 1,
                              ),
                            ),
                            suffixIcon: Icon(
                              _isDropdownOpen
                                  ? Icons.arrow_drop_up
                                  : Icons.arrow_drop_down,
                            ),
                          ),
                          child: Text(
                            selectedState != null
                                ? states
                                    .firstWhere(
                                        (StateEntity e) => e.abbreviation == selectedState)
                                    .state
                                : 'Select',
                            style: TextStyle(
                              color: selectedState == null
                                  ? Colors.grey
                                  : Colors.black,
                            ),
                          ),
                        ),
                      ),
                    ),
                  ),
                );
              },
            );
          },
        ),
      ),
    );
  }
}
 

Screenshots or Video

Screenshots / Video demonstration Image Image

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
┌─────────────────────────────────────────────────────────┐
│ A new version of Flutter is available!                  │
│                                                         │
│ To update to the latest version, run "flutter upgrade". │
└─────────────────────────────────────────────────────────┘
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.38.5, on macOS 26.3.1 25D771280a darwin-arm64, locale en-IN)
[✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0)
[!] Xcode - develop for iOS and macOS (Xcode 26.2)
    ! CocoaPods 1.15.2 out of date (1.16.2 is recommended).
        CocoaPods is a package manager for iOS or macOS platform code.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/to/platform-plugins
      To update CocoaPods, see https://guides.cocoapods.org/using/getting-started.html#updating-cocoapods
[✓] Chrome - develop for the web
[✓] Connected device (3 available)
    ! Error: Browsing on the local area network for iPhone. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)
    ! Error: Browsing on the local area network for Coforge’s iPhone. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)
[✓] Network resources

! Doctor found issues in 1 category.

Activity

  1. added
    in triagePresently being triaged by the triage team
    frameworkflutter/packages/flutter repository. See also f: labels.
    p: material_uimaterial_ui package in flutter/packages
    a: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)
    team-accessibilityOwned by Framework Accessibility team (i.e. responsible for accessibility code in flutter/flutter)
    c: proposalA detailed proposal for a change to Flutter
    and removed
    in triagePresently being triaged by the triage team
    on Apr 11, 2026
  2. mbcorona commented on Apr 11, 2026

    @mbcorona
    Member

    Hi @ravi-coforge , thanks for reporting this issue, im routing it as a proposal to team-accessibility to evaluate.

  3. added
    P2Important issues not at the top of the work list
    on Apr 15, 2026
  4. self-assigned this
    on Apr 21, 2026
  5. added
    packageflutter/packages repository. See also p: labels.
    and removed
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Aug 17, 2026
  6. added a commit that references this issue on Sep 11, 2026
    87910ce
  7. github-actions commented on Sep 25, 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 Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work lista: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)c: proposalA detailed proposal for a change to Flutterp: material_uimaterial_ui package in flutter/packagespackageflutter/packages repository. See also p: labels.team-accessibilityOwned by Framework Accessibility team (i.e. responsible for accessibility code in flutter/flutter)triaged-accessibilityTriaged by Framework Accessibility team

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions