Bruno Leroux 6f743e3266
Add DropdownMenu.decorationBuilder (#176264)
## Description

This PR adds `DropdownMenu.decorationBuilder`.
The goal is to make `DropdownMenu` more flexible.

Before this PR, several fields are used by `DropdownMenu` to create an
inner `InputDecoration`. This approach has several limitations:
- `InputDecoration` has more fields that the ones that are exposed
- `DropdownMenu` makes some choices that can't be change. Especially, it
creates an IconButton (with hardcoded padding) which is passed to
`InputDecoration.suffixIcon`. This inner `IconButton` introduces some
difficulty related to focus management and UI customization.

The new `DropdownMenu.decorationBuilder` property offers users a way to
take control on the inner `InputDecoration` in a non-breaking way.

In a future PR, this property will help replacing the default
`IconButton`.
Currently users can replace the `IconButton` using this code sample:

<details><summary>DropdownMenu without IconButton</summary>

```dart
import 'package:flutter/material.dart';

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

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

  final List<DropdownMenuEntry<String>> menuEntries = [
    "Red",
    "Green",
    "Blue",
  ].map((t) => DropdownMenuEntry<String>(label: t, value: t)).toList();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: SizedBox(
            width: 220,
            child: DropdownMenu<String>(
              expandedInsets: EdgeInsets.zero,
              requestFocusOnTap: true,
              dropdownMenuEntries: menuEntries,
              decorationBuilder: (context, controller) {
                return InputDecoration(
                  labelText: 'Label text',
                  helperText: 'Select a color or enter one',
                  suffixIcon: controller.isOpen
                      ? const Icon(Icons.arrow_drop_up)
                      : const Icon(Icons.arrow_drop_down),
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}
``` 

</details> 

## Related Issue

Fixes [DropDownMenu secondary trailing
widget](https://github.com/flutter/flutter/issues/175847)
Will help for [Make DropdownMenu's trailing icon not focusable by
default](https://github.com/flutter/flutter/issues/174096)

## Related discussions

https://github.com/flutter/flutter/issues/175847#issuecomment-3330098375
https://github.com/flutter/flutter/pull/175558#discussion_r2380227394

## Tests

- Adds 7 tests.
2025-10-20 09:45:20 +00:00
..