@@ -19,6 +19,7 @@ import 'input_border.dart';
1919import 'input_decorator.dart' ;
2020import 'material_state.dart' ;
2121import 'menu_anchor.dart' ;
22+ import 'menu_button_theme.dart' ;
2223import 'menu_style.dart' ;
2324import 'text_field.dart' ;
2425import 'theme.dart' ;
@@ -107,7 +108,6 @@ class DropdownMenuEntry<T> {
107108 final ButtonStyle ? style;
108109}
109110
110-
111111/// A dropdown menu that can be opened from a [TextField] . The selected
112112/// menu item is displayed in that field.
113113///
@@ -643,14 +643,53 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
643643 // paddings so its leading icon will be aligned with the leading icon of
644644 // the text field.
645645 final double padding = entry.leadingIcon == null ? (leadingPadding ?? _kDefaultHorizontalPadding) : _kDefaultHorizontalPadding;
646- final ButtonStyle defaultStyle = switch (textDirection) {
646+ ButtonStyle effectiveStyle = entry.style ?? switch (textDirection) {
647647 TextDirection .rtl => MenuItemButton .styleFrom (padding: EdgeInsets .only (left: _kDefaultHorizontalPadding, right: padding)),
648648 TextDirection .ltr => MenuItemButton .styleFrom (padding: EdgeInsets .only (left: padding, right: _kDefaultHorizontalPadding)),
649649 };
650650
651- ButtonStyle effectiveStyle = entry.style ?? defaultStyle;
652- final Color focusedBackgroundColor = effectiveStyle.foregroundColor? .resolve (< MaterialState > {MaterialState .focused})
653- ?? Theme .of (context).colorScheme.onSurface;
651+ final ButtonStyle ? themeStyle = MenuButtonTheme .of (context).style;
652+
653+ final WidgetStateProperty <Color ?>? effectiveForegroundColor = entry.style? .foregroundColor ?? themeStyle? .foregroundColor;
654+ final WidgetStateProperty <Color ?>? effectiveIconColor = entry.style? .iconColor ?? themeStyle? .iconColor;
655+ final WidgetStateProperty <Color ?>? effectiveOverlayColor = entry.style? .overlayColor ?? themeStyle? .overlayColor;
656+ final WidgetStateProperty <Color ?>? effectiveBackgroundColor = entry.style? .backgroundColor ?? themeStyle? .backgroundColor;
657+
658+ // Simulate the focused state because the text field should always be focused
659+ // during traversal. Include potential MenuItemButton theme in the focus
660+ // simulation for all colors in the theme.
661+ if (entry.enabled && i == focusedIndex) {
662+ // Query the Material 3 default style.
663+ // TODO(bleroux): replace once a standard way for accessing defaults will be defined.
664+ // See: https://github.com/flutter/flutter/issues/130135.
665+ final ButtonStyle defaultStyle = const MenuItemButton ().defaultStyleOf (context);
666+
667+ Color ? resolveFocusedColor (WidgetStateProperty <Color ?>? colorStateProperty) {
668+ return colorStateProperty? .resolve (< MaterialState > {MaterialState .focused});
669+ }
670+
671+ final Color focusedForegroundColor = resolveFocusedColor (effectiveForegroundColor ?? defaultStyle.foregroundColor! )! ;
672+ final Color focusedIconColor = resolveFocusedColor (effectiveIconColor ?? defaultStyle.iconColor! )! ;
673+ final Color focusedOverlayColor = resolveFocusedColor (effectiveOverlayColor ?? defaultStyle.overlayColor! )! ;
674+ // For the background color we can't rely on the default style which is transparent.
675+ // Defaults to onSurface.withOpacity(0.12).
676+ final Color focusedBackgroundColor = resolveFocusedColor (effectiveBackgroundColor)
677+ ?? Theme .of (context).colorScheme.onSurface.withOpacity (0.12 );
678+
679+ effectiveStyle = effectiveStyle.copyWith (
680+ backgroundColor: MaterialStatePropertyAll <Color >(focusedBackgroundColor),
681+ foregroundColor: MaterialStatePropertyAll <Color >(focusedForegroundColor),
682+ iconColor: MaterialStatePropertyAll <Color >(focusedIconColor),
683+ overlayColor: MaterialStatePropertyAll <Color >(focusedOverlayColor),
684+ );
685+ } else {
686+ effectiveStyle = effectiveStyle.copyWith (
687+ backgroundColor: effectiveBackgroundColor,
688+ foregroundColor: effectiveForegroundColor,
689+ iconColor: effectiveIconColor,
690+ overlayColor: effectiveOverlayColor,
691+ );
692+ }
654693
655694 Widget label = entry.labelWidget ?? Text (entry.label);
656695 if (widget.width != null ) {
@@ -661,15 +700,6 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
661700 );
662701 }
663702
664- // Simulate the focused state because the text field should always be focused
665- // during traversal. If the menu item has a custom foreground color, the "focused"
666- // color will also change to foregroundColor.withOpacity(0.12).
667- effectiveStyle = entry.enabled && i == focusedIndex
668- ? effectiveStyle.copyWith (
669- backgroundColor: MaterialStatePropertyAll <Color >(focusedBackgroundColor.withOpacity (0.12 ))
670- )
671- : effectiveStyle;
672-
673703 final Widget menuItemButton = MenuItemButton (
674704 key: enableScrollToHighlight ? buttonItemKeys[i] : null ,
675705 style: effectiveStyle,
0 commit comments