@@ -19,6 +19,7 @@ import 'input_border.dart';
19
19
import 'input_decorator.dart' ;
20
20
import 'material_state.dart' ;
21
21
import 'menu_anchor.dart' ;
22
+ import 'menu_button_theme.dart' ;
22
23
import 'menu_style.dart' ;
23
24
import 'text_field.dart' ;
24
25
import 'theme.dart' ;
@@ -107,7 +108,6 @@ class DropdownMenuEntry<T> {
107
108
final ButtonStyle ? style;
108
109
}
109
110
110
-
111
111
/// A dropdown menu that can be opened from a [TextField] . The selected
112
112
/// menu item is displayed in that field.
113
113
///
@@ -643,14 +643,53 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
643
643
// paddings so its leading icon will be aligned with the leading icon of
644
644
// the text field.
645
645
final double padding = entry.leadingIcon == null ? (leadingPadding ?? _kDefaultHorizontalPadding) : _kDefaultHorizontalPadding;
646
- final ButtonStyle defaultStyle = switch (textDirection) {
646
+ ButtonStyle effectiveStyle = entry.style ?? switch (textDirection) {
647
647
TextDirection .rtl => MenuItemButton .styleFrom (padding: EdgeInsets .only (left: _kDefaultHorizontalPadding, right: padding)),
648
648
TextDirection .ltr => MenuItemButton .styleFrom (padding: EdgeInsets .only (left: padding, right: _kDefaultHorizontalPadding)),
649
649
};
650
650
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
+ }
654
693
655
694
Widget label = entry.labelWidget ?? Text (entry.label);
656
695
if (widget.width != null ) {
@@ -661,15 +700,6 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
661
700
);
662
701
}
663
702
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
-
673
703
final Widget menuItemButton = MenuItemButton (
674
704
key: enableScrollToHighlight ? buttonItemKeys[i] : null ,
675
705
style: effectiveStyle,
0 commit comments