Add missing overlayColor
property in styleFrom
methods (#146685)
fixes [Add missing `overlayColor` property in `styleFrom` methods](https://github.com/flutter/flutter/issues/146636) ### Code sample <details> <summary>expand to view the code sample</summary> ```dart import 'package:flutter/material.dart'; enum Sizes { extraSmall, small, medium, large, extraLarge } void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ Text('styleFrom(overlayColor: Colors.red)', style: Theme.of(context).textTheme.titleLarge), TextButton( style: TextButton.styleFrom(overlayColor: Colors.red), onPressed: () {}, child: const Text('TextButton'), ), IconButton( style: IconButton.styleFrom( overlayColor: Colors.red, ), onPressed: () {}, icon: const Icon(Icons.add), ), MenuBar( children: [ MenuItemButton( style: MenuItemButton.styleFrom(overlayColor: Colors.red), child: const Text('MenuItemButton'), onPressed: () {}, ), SubmenuButton( style: SubmenuButton.styleFrom(overlayColor: Colors.red), menuChildren: [ MenuItemButton( child: const Text('MenuItemButton'), onPressed: () {}, ), ], child: const Text('SubmenuButton'), ), ], ), SegmentedButton<Sizes>( style: SegmentedButton.styleFrom(overlayColor: Colors.red), segments: const <ButtonSegment<Sizes>>[ ButtonSegment<Sizes>( value: Sizes.extraSmall, label: Text('XS')), ButtonSegment<Sizes>(value: Sizes.small, label: Text('S')), ButtonSegment<Sizes>(value: Sizes.medium, label: Text('M')), ButtonSegment<Sizes>( value: Sizes.large, label: Text('L'), ), ButtonSegment<Sizes>( value: Sizes.extraLarge, label: Text('XL')), ], selected: const {Sizes.medium}, onSelectionChanged: (Set<Sizes> newSelection) {}, multiSelectionEnabled: true, ), ], ), ), ), ); } } ``` </details> ### Preview 
This commit is contained in:
parent
ffea970ce8
commit
fa85f69e47
@ -120,27 +120,27 @@ class _${blockName}DefaultsM3 extends SegmentedButtonThemeData {
|
|||||||
@override
|
@override
|
||||||
Widget? get selectedIcon => const Icon(Icons.check);
|
Widget? get selectedIcon => const Icon(Icons.check);
|
||||||
|
|
||||||
static MaterialStateProperty<Color?> resolveStateColor(Color? unselectedColor, Color? selectedColor){
|
static MaterialStateProperty<Color?> resolveStateColor(Color? unselectedColor, Color? selectedColor, Color? overlayColor){
|
||||||
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
if (states.contains(MaterialState.selected)) {
|
if (states.contains(MaterialState.selected)) {
|
||||||
if (states.contains(MaterialState.pressed)) {
|
if (states.contains(MaterialState.pressed)) {
|
||||||
return selectedColor?.withOpacity(0.1);
|
return (overlayColor ?? selectedColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.hovered)) {
|
if (states.contains(MaterialState.hovered)) {
|
||||||
return selectedColor?.withOpacity(0.08);
|
return (overlayColor ?? selectedColor)?.withOpacity(0.08);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.focused)) {
|
if (states.contains(MaterialState.focused)) {
|
||||||
return selectedColor?.withOpacity(0.1);
|
return (overlayColor ?? selectedColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (states.contains(MaterialState.pressed)) {
|
if (states.contains(MaterialState.pressed)) {
|
||||||
return unselectedColor?.withOpacity(0.1);
|
return (overlayColor ?? unselectedColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.hovered)) {
|
if (states.contains(MaterialState.hovered)) {
|
||||||
return unselectedColor?.withOpacity(0.08);
|
return (overlayColor ?? unselectedColor)?.withOpacity(0.08);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.focused)) {
|
if (states.contains(MaterialState.focused)) {
|
||||||
return unselectedColor?.withOpacity(0.1);
|
return (overlayColor ?? unselectedColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Colors.transparent;
|
return Colors.transparent;
|
||||||
|
@ -573,9 +573,15 @@ class IconButton extends StatelessWidget {
|
|||||||
/// [ButtonStyle.foregroundColor] value. Specify a value for [foregroundColor]
|
/// [ButtonStyle.foregroundColor] value. Specify a value for [foregroundColor]
|
||||||
/// to specify the color of the button's icons. The [hoverColor], [focusColor]
|
/// to specify the color of the button's icons. The [hoverColor], [focusColor]
|
||||||
/// and [highlightColor] colors are used to indicate the hover, focus,
|
/// and [highlightColor] colors are used to indicate the hover, focus,
|
||||||
/// and pressed states. Use [backgroundColor] for the button's background
|
/// and pressed states if [overlayColor] isn't specified.
|
||||||
/// fill color. Use [disabledForegroundColor] and [disabledBackgroundColor]
|
///
|
||||||
/// to specify the button's disabled icon and fill color.
|
/// If [overlayColor] is specified and its value is [Colors.transparent]
|
||||||
|
/// then the pressed/focused/hovered highlights are effectively defeated.
|
||||||
|
/// Otherwise a [MaterialStateProperty] with the same opacities as the
|
||||||
|
/// default is created.
|
||||||
|
///
|
||||||
|
/// Use [backgroundColor] for the button's background fill color. Use [disabledForegroundColor]
|
||||||
|
/// and [disabledBackgroundColor] to specify the button's disabled icon and fill color.
|
||||||
///
|
///
|
||||||
/// Similarly, the [enabledMouseCursor] and [disabledMouseCursor]
|
/// Similarly, the [enabledMouseCursor] and [disabledMouseCursor]
|
||||||
/// parameters are used to construct [ButtonStyle].mouseCursor.
|
/// parameters are used to construct [ButtonStyle].mouseCursor.
|
||||||
@ -611,6 +617,7 @@ class IconButton extends StatelessWidget {
|
|||||||
Color? highlightColor,
|
Color? highlightColor,
|
||||||
Color? shadowColor,
|
Color? shadowColor,
|
||||||
Color? surfaceTintColor,
|
Color? surfaceTintColor,
|
||||||
|
Color? overlayColor,
|
||||||
double? elevation,
|
double? elevation,
|
||||||
Size? minimumSize,
|
Size? minimumSize,
|
||||||
Size? fixedSize,
|
Size? fixedSize,
|
||||||
@ -629,20 +636,24 @@ class IconButton extends StatelessWidget {
|
|||||||
InteractiveInkFeatureFactory? splashFactory,
|
InteractiveInkFeatureFactory? splashFactory,
|
||||||
}) {
|
}) {
|
||||||
final MaterialStateProperty<Color?>? buttonBackgroundColor = (backgroundColor == null && disabledBackgroundColor == null)
|
final MaterialStateProperty<Color?>? buttonBackgroundColor = (backgroundColor == null && disabledBackgroundColor == null)
|
||||||
? null
|
? null
|
||||||
: _IconButtonDefaultBackground(backgroundColor, disabledBackgroundColor);
|
: _IconButtonDefaultBackground(backgroundColor, disabledBackgroundColor);
|
||||||
final MaterialStateProperty<Color?>? buttonForegroundColor = (foregroundColor == null && disabledForegroundColor == null)
|
final MaterialStateProperty<Color?>? buttonForegroundColor = (foregroundColor == null && disabledForegroundColor == null)
|
||||||
|
? null
|
||||||
|
: _IconButtonDefaultForeground(foregroundColor, disabledForegroundColor);
|
||||||
|
final MaterialStateProperty<Color?>? overlayColorProp = (foregroundColor == null &&
|
||||||
|
hoverColor == null && focusColor == null && highlightColor == null && overlayColor == null)
|
||||||
? null
|
? null
|
||||||
: _IconButtonDefaultForeground(foregroundColor, disabledForegroundColor);
|
: switch (overlayColor) {
|
||||||
final MaterialStateProperty<Color?>? overlayColor = (foregroundColor == null && hoverColor == null && focusColor == null && highlightColor == null)
|
(final Color overlayColor) when overlayColor.value == 0 => const MaterialStatePropertyAll<Color?>(Colors.transparent),
|
||||||
? null
|
_ => _IconButtonDefaultOverlay(foregroundColor, focusColor, hoverColor, highlightColor, overlayColor),
|
||||||
: _IconButtonDefaultOverlay(foregroundColor, focusColor, hoverColor, highlightColor);
|
};
|
||||||
final MaterialStateProperty<MouseCursor?> mouseCursor = _IconButtonDefaultMouseCursor(enabledMouseCursor, disabledMouseCursor);
|
final MaterialStateProperty<MouseCursor?> mouseCursor = _IconButtonDefaultMouseCursor(enabledMouseCursor, disabledMouseCursor);
|
||||||
|
|
||||||
return ButtonStyle(
|
return ButtonStyle(
|
||||||
backgroundColor: buttonBackgroundColor,
|
backgroundColor: buttonBackgroundColor,
|
||||||
foregroundColor: buttonForegroundColor,
|
foregroundColor: buttonForegroundColor,
|
||||||
overlayColor: overlayColor,
|
overlayColor: overlayColorProp,
|
||||||
shadowColor: ButtonStyleButton.allOrNull<Color>(shadowColor),
|
shadowColor: ButtonStyleButton.allOrNull<Color>(shadowColor),
|
||||||
surfaceTintColor: ButtonStyleButton.allOrNull<Color>(surfaceTintColor),
|
surfaceTintColor: ButtonStyleButton.allOrNull<Color>(surfaceTintColor),
|
||||||
elevation: ButtonStyleButton.allOrNull<double>(elevation),
|
elevation: ButtonStyleButton.allOrNull<double>(elevation),
|
||||||
@ -1023,34 +1034,41 @@ class _IconButtonDefaultForeground extends MaterialStateProperty<Color?> {
|
|||||||
|
|
||||||
@immutable
|
@immutable
|
||||||
class _IconButtonDefaultOverlay extends MaterialStateProperty<Color?> {
|
class _IconButtonDefaultOverlay extends MaterialStateProperty<Color?> {
|
||||||
_IconButtonDefaultOverlay(this.foregroundColor, this.focusColor, this.hoverColor, this.highlightColor);
|
_IconButtonDefaultOverlay(
|
||||||
|
this.foregroundColor,
|
||||||
|
this.focusColor,
|
||||||
|
this.hoverColor,
|
||||||
|
this.highlightColor,
|
||||||
|
this.overlayColor,
|
||||||
|
);
|
||||||
|
|
||||||
final Color? foregroundColor;
|
final Color? foregroundColor;
|
||||||
final Color? focusColor;
|
final Color? focusColor;
|
||||||
final Color? hoverColor;
|
final Color? hoverColor;
|
||||||
final Color? highlightColor;
|
final Color? highlightColor;
|
||||||
|
final Color? overlayColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? resolve(Set<MaterialState> states) {
|
Color? resolve(Set<MaterialState> states) {
|
||||||
if (states.contains(MaterialState.selected)) {
|
if (states.contains(MaterialState.selected)) {
|
||||||
if (states.contains(MaterialState.pressed)) {
|
if (states.contains(MaterialState.pressed)) {
|
||||||
return highlightColor ?? foregroundColor?.withOpacity(0.1);
|
return highlightColor ?? (overlayColor ?? foregroundColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.hovered)) {
|
if (states.contains(MaterialState.hovered)) {
|
||||||
return hoverColor ?? foregroundColor?.withOpacity(0.08);
|
return hoverColor ?? (overlayColor ?? foregroundColor)?.withOpacity(0.08);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.focused)) {
|
if (states.contains(MaterialState.focused)) {
|
||||||
return focusColor ?? foregroundColor?.withOpacity(0.1);
|
return focusColor ?? (overlayColor ?? foregroundColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.pressed)) {
|
if (states.contains(MaterialState.pressed)) {
|
||||||
return highlightColor ?? foregroundColor?.withOpacity(0.1);
|
return highlightColor ?? (overlayColor ?? foregroundColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.hovered)) {
|
if (states.contains(MaterialState.hovered)) {
|
||||||
return hoverColor ?? foregroundColor?.withOpacity(0.08);
|
return hoverColor ?? (overlayColor ?? foregroundColor)?.withOpacity(0.08);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.focused)) {
|
if (states.contains(MaterialState.focused)) {
|
||||||
return focusColor ?? foregroundColor?.withOpacity(0.1);
|
return focusColor ?? (overlayColor ?? foregroundColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1022,6 +1022,7 @@ class MenuItemButton extends StatefulWidget {
|
|||||||
Color? surfaceTintColor,
|
Color? surfaceTintColor,
|
||||||
Color? iconColor,
|
Color? iconColor,
|
||||||
TextStyle? textStyle,
|
TextStyle? textStyle,
|
||||||
|
Color? overlayColor,
|
||||||
double? elevation,
|
double? elevation,
|
||||||
EdgeInsetsGeometry? padding,
|
EdgeInsetsGeometry? padding,
|
||||||
Size? minimumSize,
|
Size? minimumSize,
|
||||||
@ -1047,6 +1048,7 @@ class MenuItemButton extends StatefulWidget {
|
|||||||
surfaceTintColor: surfaceTintColor,
|
surfaceTintColor: surfaceTintColor,
|
||||||
iconColor: iconColor,
|
iconColor: iconColor,
|
||||||
textStyle: textStyle,
|
textStyle: textStyle,
|
||||||
|
overlayColor: overlayColor,
|
||||||
elevation: elevation,
|
elevation: elevation,
|
||||||
padding: padding,
|
padding: padding,
|
||||||
minimumSize: minimumSize,
|
minimumSize: minimumSize,
|
||||||
@ -1775,6 +1777,7 @@ class SubmenuButton extends StatefulWidget {
|
|||||||
Color? surfaceTintColor,
|
Color? surfaceTintColor,
|
||||||
Color? iconColor,
|
Color? iconColor,
|
||||||
TextStyle? textStyle,
|
TextStyle? textStyle,
|
||||||
|
Color? overlayColor,
|
||||||
double? elevation,
|
double? elevation,
|
||||||
EdgeInsetsGeometry? padding,
|
EdgeInsetsGeometry? padding,
|
||||||
Size? minimumSize,
|
Size? minimumSize,
|
||||||
@ -1800,6 +1803,7 @@ class SubmenuButton extends StatefulWidget {
|
|||||||
surfaceTintColor: surfaceTintColor,
|
surfaceTintColor: surfaceTintColor,
|
||||||
iconColor: iconColor,
|
iconColor: iconColor,
|
||||||
textStyle: textStyle,
|
textStyle: textStyle,
|
||||||
|
overlayColor: overlayColor,
|
||||||
elevation: elevation,
|
elevation: elevation,
|
||||||
padding: padding,
|
padding: padding,
|
||||||
minimumSize: minimumSize,
|
minimumSize: minimumSize,
|
||||||
|
@ -203,7 +203,12 @@ class SegmentedButton<T> extends StatefulWidget {
|
|||||||
///
|
///
|
||||||
/// The [foregroundColor], [selectedForegroundColor], and [disabledForegroundColor]
|
/// The [foregroundColor], [selectedForegroundColor], and [disabledForegroundColor]
|
||||||
/// colors are used to create a [MaterialStateProperty] [ButtonStyle.foregroundColor],
|
/// colors are used to create a [MaterialStateProperty] [ButtonStyle.foregroundColor],
|
||||||
/// and a derived [ButtonStyle.overlayColor].
|
/// and a derived [ButtonStyle.overlayColor] if [overlayColor] isn't specified.
|
||||||
|
///
|
||||||
|
/// If [overlayColor] is specified and its value is [Colors.transparent]
|
||||||
|
/// then the pressed/focused/hovered highlights are effectively defeated.
|
||||||
|
/// Otherwise a [MaterialStateProperty] with the same opacities as the
|
||||||
|
/// default is created.
|
||||||
///
|
///
|
||||||
/// The [backgroundColor], [selectedBackgroundColor] and [disabledBackgroundColor]
|
/// The [backgroundColor], [selectedBackgroundColor] and [disabledBackgroundColor]
|
||||||
/// colors are used to create a [MaterialStateProperty] [ButtonStyle.backgroundColor].
|
/// colors are used to create a [MaterialStateProperty] [ButtonStyle.backgroundColor].
|
||||||
@ -261,6 +266,7 @@ class SegmentedButton<T> extends StatefulWidget {
|
|||||||
Color? disabledBackgroundColor,
|
Color? disabledBackgroundColor,
|
||||||
Color? shadowColor,
|
Color? shadowColor,
|
||||||
Color? surfaceTintColor,
|
Color? surfaceTintColor,
|
||||||
|
Color? overlayColor,
|
||||||
double? elevation,
|
double? elevation,
|
||||||
TextStyle? textStyle,
|
TextStyle? textStyle,
|
||||||
EdgeInsetsGeometry? padding,
|
EdgeInsetsGeometry? padding,
|
||||||
@ -286,9 +292,13 @@ class SegmentedButton<T> extends StatefulWidget {
|
|||||||
(backgroundColor == null && disabledBackgroundColor == null && selectedBackgroundColor == null)
|
(backgroundColor == null && disabledBackgroundColor == null && selectedBackgroundColor == null)
|
||||||
? null
|
? null
|
||||||
: _SegmentButtonDefaultColor(backgroundColor, disabledBackgroundColor, selectedBackgroundColor);
|
: _SegmentButtonDefaultColor(backgroundColor, disabledBackgroundColor, selectedBackgroundColor);
|
||||||
final MaterialStateProperty<Color?>? overlayColor = (foregroundColor == null && selectedForegroundColor == null)
|
final MaterialStateProperty<Color?>? overlayColorProp = (foregroundColor == null &&
|
||||||
? null
|
selectedForegroundColor == null && overlayColor == null)
|
||||||
: _SegmentedButtonDefaultsM3.resolveStateColor(foregroundColor, selectedForegroundColor);
|
? null
|
||||||
|
: switch (overlayColor) {
|
||||||
|
(final Color overlayColor) when overlayColor.value == 0 => const MaterialStatePropertyAll<Color?>(Colors.transparent),
|
||||||
|
_ => _SegmentedButtonDefaultsM3.resolveStateColor(foregroundColor, selectedForegroundColor, overlayColor),
|
||||||
|
};
|
||||||
return TextButton.styleFrom(
|
return TextButton.styleFrom(
|
||||||
textStyle: textStyle,
|
textStyle: textStyle,
|
||||||
shadowColor: shadowColor,
|
shadowColor: shadowColor,
|
||||||
@ -311,7 +321,7 @@ class SegmentedButton<T> extends StatefulWidget {
|
|||||||
).copyWith(
|
).copyWith(
|
||||||
foregroundColor: foregroundColorProp,
|
foregroundColor: foregroundColorProp,
|
||||||
backgroundColor: backgroundColorProp,
|
backgroundColor: backgroundColorProp,
|
||||||
overlayColor: overlayColor,
|
overlayColor: overlayColorProp,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1066,27 +1076,27 @@ class _SegmentedButtonDefaultsM3 extends SegmentedButtonThemeData {
|
|||||||
@override
|
@override
|
||||||
Widget? get selectedIcon => const Icon(Icons.check);
|
Widget? get selectedIcon => const Icon(Icons.check);
|
||||||
|
|
||||||
static MaterialStateProperty<Color?> resolveStateColor(Color? unselectedColor, Color? selectedColor){
|
static MaterialStateProperty<Color?> resolveStateColor(Color? unselectedColor, Color? selectedColor, Color? overlayColor){
|
||||||
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
if (states.contains(MaterialState.selected)) {
|
if (states.contains(MaterialState.selected)) {
|
||||||
if (states.contains(MaterialState.pressed)) {
|
if (states.contains(MaterialState.pressed)) {
|
||||||
return selectedColor?.withOpacity(0.1);
|
return (overlayColor ?? selectedColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.hovered)) {
|
if (states.contains(MaterialState.hovered)) {
|
||||||
return selectedColor?.withOpacity(0.08);
|
return (overlayColor ?? selectedColor)?.withOpacity(0.08);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.focused)) {
|
if (states.contains(MaterialState.focused)) {
|
||||||
return selectedColor?.withOpacity(0.1);
|
return (overlayColor ?? selectedColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (states.contains(MaterialState.pressed)) {
|
if (states.contains(MaterialState.pressed)) {
|
||||||
return unselectedColor?.withOpacity(0.1);
|
return (overlayColor ?? unselectedColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.hovered)) {
|
if (states.contains(MaterialState.hovered)) {
|
||||||
return unselectedColor?.withOpacity(0.08);
|
return (overlayColor ?? unselectedColor)?.withOpacity(0.08);
|
||||||
}
|
}
|
||||||
if (states.contains(MaterialState.focused)) {
|
if (states.contains(MaterialState.focused)) {
|
||||||
return unselectedColor?.withOpacity(0.1);
|
return (overlayColor ?? unselectedColor)?.withOpacity(0.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Colors.transparent;
|
return Colors.transparent;
|
||||||
|
@ -7,6 +7,7 @@ import 'dart:ui';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import '../widgets/semantics_tester.dart';
|
import '../widgets/semantics_tester.dart';
|
||||||
import 'feedback_tester.dart';
|
import 'feedback_tester.dart';
|
||||||
@ -27,6 +28,10 @@ void main() {
|
|||||||
mockOnPressedFunction = MockOnPressedFunction();
|
mockOnPressedFunction = MockOnPressedFunction();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RenderObject getOverlayColor(WidgetTester tester) {
|
||||||
|
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||||
|
}
|
||||||
|
|
||||||
testWidgets('test icon is findable by key', (WidgetTester tester) async {
|
testWidgets('test icon is findable by key', (WidgetTester tester) async {
|
||||||
const ValueKey<String> key = ValueKey<String>('icon-button');
|
const ValueKey<String> key = ValueKey<String>('icon-button');
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
@ -1222,10 +1227,6 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderObject overlayColor() {
|
|
||||||
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hovered.
|
// Hovered.
|
||||||
final Offset center = tester.getCenter(find.byType(IconButton));
|
final Offset center = tester.getCenter(find.byType(IconButton));
|
||||||
final TestGesture gesture = await tester.createGesture(
|
final TestGesture gesture = await tester.createGesture(
|
||||||
@ -1234,12 +1235,12 @@ void main() {
|
|||||||
await gesture.addPointer();
|
await gesture.addPointer();
|
||||||
await gesture.moveTo(center);
|
await gesture.moveTo(center);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.08)));
|
expect(getOverlayColor(tester), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.08)));
|
||||||
|
|
||||||
// Highlighted (pressed).
|
// Highlighted (pressed).
|
||||||
await gesture.down(center);
|
await gesture.down(center);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect()..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.1)));
|
expect(getOverlayColor(tester), paints..rect()..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.1)));
|
||||||
// Remove pressed and hovered states
|
// Remove pressed and hovered states
|
||||||
await gesture.up();
|
await gesture.up();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -1249,7 +1250,7 @@ void main() {
|
|||||||
// Focused.
|
// Focused.
|
||||||
focusNode.requestFocus();
|
focusNode.requestFocus();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.1)));
|
expect(getOverlayColor(tester), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.1)));
|
||||||
|
|
||||||
focusNode.dispose();
|
focusNode.dispose();
|
||||||
});
|
});
|
||||||
@ -1363,10 +1364,6 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderObject overlayColor() {
|
|
||||||
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hovered.
|
// Hovered.
|
||||||
final Offset center = tester.getCenter(find.byType(IconButton));
|
final Offset center = tester.getCenter(find.byType(IconButton));
|
||||||
final TestGesture gesture = await tester.createGesture(
|
final TestGesture gesture = await tester.createGesture(
|
||||||
@ -1375,12 +1372,12 @@ void main() {
|
|||||||
await gesture.addPointer();
|
await gesture.addPointer();
|
||||||
await gesture.moveTo(center);
|
await gesture.moveTo(center);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onPrimary.withOpacity(0.08)));
|
expect(getOverlayColor(tester), paints..rect(color: theme.colorScheme.onPrimary.withOpacity(0.08)));
|
||||||
|
|
||||||
// Highlighted (pressed).
|
// Highlighted (pressed).
|
||||||
await gesture.down(center);
|
await gesture.down(center);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect()..rect(color: theme.colorScheme.onPrimary.withOpacity(0.1)));
|
expect(getOverlayColor(tester), paints..rect()..rect(color: theme.colorScheme.onPrimary.withOpacity(0.1)));
|
||||||
// Remove pressed and hovered states
|
// Remove pressed and hovered states
|
||||||
await gesture.up();
|
await gesture.up();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -1390,7 +1387,7 @@ void main() {
|
|||||||
// Focused.
|
// Focused.
|
||||||
focusNode.requestFocus();
|
focusNode.requestFocus();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onPrimary.withOpacity(0.1)));
|
expect(getOverlayColor(tester), paints..rect(color: theme.colorScheme.onPrimary.withOpacity(0.1)));
|
||||||
|
|
||||||
focusNode.dispose();
|
focusNode.dispose();
|
||||||
});
|
});
|
||||||
@ -1619,10 +1616,6 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderObject overlayColor() {
|
|
||||||
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hovered.
|
// Hovered.
|
||||||
final Offset center = tester.getCenter(find.byType(IconButton));
|
final Offset center = tester.getCenter(find.byType(IconButton));
|
||||||
final TestGesture gesture = await tester.createGesture(
|
final TestGesture gesture = await tester.createGesture(
|
||||||
@ -1631,12 +1624,12 @@ void main() {
|
|||||||
await gesture.addPointer();
|
await gesture.addPointer();
|
||||||
await gesture.moveTo(center);
|
await gesture.moveTo(center);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSecondaryContainer.withOpacity(0.08)));
|
expect(getOverlayColor(tester), paints..rect(color: theme.colorScheme.onSecondaryContainer.withOpacity(0.08)));
|
||||||
|
|
||||||
// Highlighted (pressed).
|
// Highlighted (pressed).
|
||||||
await gesture.down(center);
|
await gesture.down(center);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect()..rect(color: theme.colorScheme.onSecondaryContainer.withOpacity(0.1)));
|
expect(getOverlayColor(tester), paints..rect()..rect(color: theme.colorScheme.onSecondaryContainer.withOpacity(0.1)));
|
||||||
// Remove pressed and hovered states
|
// Remove pressed and hovered states
|
||||||
await gesture.up();
|
await gesture.up();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -1646,7 +1639,7 @@ void main() {
|
|||||||
// Focused.
|
// Focused.
|
||||||
focusNode.requestFocus();
|
focusNode.requestFocus();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSecondaryContainer.withOpacity(0.1)));
|
expect(getOverlayColor(tester), paints..rect(color: theme.colorScheme.onSecondaryContainer.withOpacity(0.1)));
|
||||||
|
|
||||||
focusNode.dispose();
|
focusNode.dispose();
|
||||||
});
|
});
|
||||||
@ -1875,10 +1868,6 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderObject overlayColor() {
|
|
||||||
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hovered.
|
// Hovered.
|
||||||
final Offset center = tester.getCenter(find.byType(IconButton));
|
final Offset center = tester.getCenter(find.byType(IconButton));
|
||||||
final TestGesture gesture = await tester.createGesture(
|
final TestGesture gesture = await tester.createGesture(
|
||||||
@ -1887,12 +1876,12 @@ void main() {
|
|||||||
await gesture.addPointer();
|
await gesture.addPointer();
|
||||||
await gesture.moveTo(center);
|
await gesture.moveTo(center);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.08)));
|
expect(getOverlayColor(tester), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.08)));
|
||||||
|
|
||||||
// Highlighted (pressed).
|
// Highlighted (pressed).
|
||||||
await gesture.down(center);
|
await gesture.down(center);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect()..rect(color: theme.colorScheme.onSurface.withOpacity(0.1)));
|
expect(getOverlayColor(tester), paints..rect()..rect(color: theme.colorScheme.onSurface.withOpacity(0.1)));
|
||||||
// Remove pressed and hovered states
|
// Remove pressed and hovered states
|
||||||
await gesture.up();
|
await gesture.up();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -1902,7 +1891,7 @@ void main() {
|
|||||||
// Focused.
|
// Focused.
|
||||||
focusNode.requestFocus();
|
focusNode.requestFocus();
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.08)));
|
expect(getOverlayColor(tester), paints..rect(color: theme.colorScheme.onSurfaceVariant.withOpacity(0.08)));
|
||||||
|
|
||||||
focusNode.dispose();
|
focusNode.dispose();
|
||||||
});
|
});
|
||||||
@ -2586,6 +2575,156 @@ void main() {
|
|||||||
expect(box.size, equals(const Size(48, 48)));
|
expect(box.size, equals(const Size(48, 48)));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('IconButton.styleFrom overlayColor overrides default overlay color', (WidgetTester tester) async {
|
||||||
|
const Color overlayColor = Color(0xffff0000);
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: IconButton(
|
||||||
|
style: IconButton.styleFrom(overlayColor: overlayColor),
|
||||||
|
onPressed: () { },
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hovered.
|
||||||
|
final Offset center = tester.getCenter(find.byType(IconButton));
|
||||||
|
final TestGesture gesture = await tester.createGesture(
|
||||||
|
kind: PointerDeviceKind.mouse,
|
||||||
|
);
|
||||||
|
await gesture.addPointer();
|
||||||
|
await gesture.moveTo(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08)));
|
||||||
|
|
||||||
|
// Highlighted (pressed).
|
||||||
|
await gesture.down(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(
|
||||||
|
getOverlayColor(tester),
|
||||||
|
paints
|
||||||
|
..rect(color: overlayColor.withOpacity(0.08))
|
||||||
|
..rect(color: overlayColor.withOpacity(0.1)),
|
||||||
|
);
|
||||||
|
// Remove pressed and hovered states,
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await gesture.moveTo(const Offset(0, 50));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Focused.
|
||||||
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.1)));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('IconButton.styleFrom highlight, hover, focus colors overrides overlayColor', (WidgetTester tester) async {
|
||||||
|
const Color hoverColor = Color(0xff0000f2);
|
||||||
|
const Color highlightColor = Color(0xff0000f1);
|
||||||
|
const Color focusColor = Color(0xff0000f3);
|
||||||
|
const Color overlayColor = Color(0xffff0000);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: IconButton(
|
||||||
|
style: IconButton.styleFrom(
|
||||||
|
hoverColor: hoverColor,
|
||||||
|
highlightColor: highlightColor,
|
||||||
|
focusColor: focusColor,
|
||||||
|
overlayColor: overlayColor,
|
||||||
|
),
|
||||||
|
onPressed: () { },
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hovered.
|
||||||
|
final Offset center = tester.getCenter(find.byType(IconButton));
|
||||||
|
final TestGesture gesture = await tester.createGesture(
|
||||||
|
kind: PointerDeviceKind.mouse,
|
||||||
|
);
|
||||||
|
await gesture.addPointer();
|
||||||
|
await gesture.moveTo(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: hoverColor));
|
||||||
|
|
||||||
|
// Highlighted (pressed).
|
||||||
|
await gesture.down(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(
|
||||||
|
getOverlayColor(tester),
|
||||||
|
paints
|
||||||
|
..rect(color: hoverColor)
|
||||||
|
..rect(color: highlightColor),
|
||||||
|
);
|
||||||
|
// Remove pressed and hovered states,
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await gesture.moveTo(const Offset(0, 50));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Focused.
|
||||||
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: focusColor));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('IconButton.styleFrom with transparent overlayColor', (WidgetTester tester) async {
|
||||||
|
const Color overlayColor = Colors.transparent;
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: IconButton(
|
||||||
|
style: IconButton.styleFrom(overlayColor: overlayColor),
|
||||||
|
onPressed: () { },
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hovered.
|
||||||
|
final Offset center = tester.getCenter(find.byType(IconButton));
|
||||||
|
final TestGesture gesture = await tester.createGesture(
|
||||||
|
kind: PointerDeviceKind.mouse,
|
||||||
|
);
|
||||||
|
await gesture.addPointer();
|
||||||
|
await gesture.moveTo(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor));
|
||||||
|
|
||||||
|
// Highlighted (pressed).
|
||||||
|
await gesture.down(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(
|
||||||
|
getOverlayColor(tester),
|
||||||
|
paints
|
||||||
|
..rect(color: overlayColor)
|
||||||
|
..rect(color: overlayColor),
|
||||||
|
);
|
||||||
|
// Remove pressed and hovered states,
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await gesture.moveTo(const Offset(0, 50));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Focused.
|
||||||
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor));
|
||||||
|
});
|
||||||
|
|
||||||
group('IconTheme tests in Material 3', () {
|
group('IconTheme tests in Material 3', () {
|
||||||
testWidgets('IconTheme overrides default values in M3', (WidgetTester tester) async {
|
testWidgets('IconTheme overrides default values in M3', (WidgetTester tester) async {
|
||||||
// Theme's IconTheme
|
// Theme's IconTheme
|
||||||
|
@ -2,10 +2,16 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
RenderObject getOverlayColor(WidgetTester tester) {
|
||||||
|
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||||
|
}
|
||||||
|
|
||||||
test('IconButtonThemeData lerp special cases', () {
|
test('IconButtonThemeData lerp special cases', () {
|
||||||
expect(IconButtonThemeData.lerp(null, null, 0), null);
|
expect(IconButtonThemeData.lerp(null, null, 0), null);
|
||||||
const IconButtonThemeData data = IconButtonThemeData();
|
const IconButtonThemeData data = IconButtonThemeData();
|
||||||
@ -254,4 +260,57 @@ void main() {
|
|||||||
material = tester.widget<Material>(buttonMaterialFinder);
|
material = tester.widget<Material>(buttonMaterialFinder);
|
||||||
expect(material.shadowColor, shadowColor);
|
expect(material.shadowColor, shadowColor);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('IconButtonTheme IconButton.styleFrom overlayColor overrides default overlay color', (WidgetTester tester) async {
|
||||||
|
const Color overlayColor = Color(0xffff0000);
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: IconButtonTheme(
|
||||||
|
data: IconButtonThemeData(
|
||||||
|
style: IconButton.styleFrom(
|
||||||
|
overlayColor: overlayColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: () { },
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hovered.
|
||||||
|
final Offset center = tester.getCenter(find.byType(IconButton));
|
||||||
|
final TestGesture gesture = await tester.createGesture(
|
||||||
|
kind: PointerDeviceKind.mouse,
|
||||||
|
);
|
||||||
|
await gesture.addPointer();
|
||||||
|
await gesture.moveTo(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08)));
|
||||||
|
|
||||||
|
// Highlighted (pressed).
|
||||||
|
await gesture.down(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(
|
||||||
|
getOverlayColor(tester),
|
||||||
|
paints
|
||||||
|
..rect(color: overlayColor.withOpacity(0.08))
|
||||||
|
..rect(color: overlayColor.withOpacity(0.1)),
|
||||||
|
);
|
||||||
|
// Remove pressed and hovered states,
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await gesture.moveTo(const Offset(0, 50));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Focused.
|
||||||
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.1)));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -166,6 +166,10 @@ void main() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderObject getOverlayColor(WidgetTester tester) {
|
||||||
|
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||||
|
}
|
||||||
|
|
||||||
testWidgets('Menu responds to density changes', (WidgetTester tester) async {
|
testWidgets('Menu responds to density changes', (WidgetTester tester) async {
|
||||||
Widget buildMenu({VisualDensity? visualDensity = VisualDensity.standard}) {
|
Widget buildMenu({VisualDensity? visualDensity = VisualDensity.standard}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
@ -2494,6 +2498,40 @@ void main() {
|
|||||||
final AssertionError exception = tester.takeException() as AssertionError;
|
final AssertionError exception = tester.takeException() as AssertionError;
|
||||||
expect(exception, isAssertionError);
|
expect(exception, isAssertionError);
|
||||||
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933
|
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933
|
||||||
|
|
||||||
|
testWidgets('MenuItemButton.styleFrom overlayColor overrides default overlay color', (WidgetTester tester) async {
|
||||||
|
const Color overlayColor = Color(0xffff0000);
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: MenuItemButton(
|
||||||
|
style: MenuItemButton.styleFrom(overlayColor: overlayColor),
|
||||||
|
onPressed: () {},
|
||||||
|
child: const Text('MenuItem'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
// Hovered.
|
||||||
|
final Offset center = tester.getCenter(find.byType(MenuItemButton));
|
||||||
|
final TestGesture gesture = await tester.createGesture(
|
||||||
|
kind: PointerDeviceKind.mouse,
|
||||||
|
);
|
||||||
|
await gesture.addPointer();
|
||||||
|
await gesture.moveTo(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08)));
|
||||||
|
|
||||||
|
// Highlighted (pressed).
|
||||||
|
await gesture.down(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(
|
||||||
|
getOverlayColor(tester),
|
||||||
|
paints
|
||||||
|
..rect(color: overlayColor.withOpacity(0.08))
|
||||||
|
..rect(color: overlayColor.withOpacity(0.08))
|
||||||
|
..rect(color: overlayColor.withOpacity(0.1)),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Layout', () {
|
group('Layout', () {
|
||||||
@ -3709,6 +3747,45 @@ void main() {
|
|||||||
);
|
);
|
||||||
expect(intrinsicWidthFinder, findsOneWidget);
|
expect(intrinsicWidthFinder, findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('SubmenuButton.styleFrom overlayColor overrides default overlay color', (WidgetTester tester) async {
|
||||||
|
const Color overlayColor = Color(0xffff00ff);
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: SubmenuButton(
|
||||||
|
style: SubmenuButton.styleFrom(overlayColor: overlayColor),
|
||||||
|
menuChildren: <Widget>[
|
||||||
|
MenuItemButton(
|
||||||
|
onPressed: () {},
|
||||||
|
child: const Text('MenuItemButton'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: const Text('Submenu'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
// Hovered.
|
||||||
|
final Offset center = tester.getCenter(find.byType(SubmenuButton));
|
||||||
|
final TestGesture gesture = await tester.createGesture(
|
||||||
|
kind: PointerDeviceKind.mouse,
|
||||||
|
);
|
||||||
|
await gesture.addPointer();
|
||||||
|
await gesture.moveTo(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08)));
|
||||||
|
|
||||||
|
// Highlighted (pressed).
|
||||||
|
await gesture.down(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(
|
||||||
|
getOverlayColor(tester),
|
||||||
|
paints
|
||||||
|
..rect(color: overlayColor.withOpacity(0.08))
|
||||||
|
..rect(color: overlayColor.withOpacity(0.08))
|
||||||
|
..rect(color: overlayColor.withOpacity(0.1)),
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> createTestMenus({
|
List<Widget> createTestMenus({
|
||||||
|
@ -9,6 +9,7 @@ import 'dart:ui';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import '../widgets/semantics_tester.dart';
|
import '../widgets/semantics_tester.dart';
|
||||||
@ -21,6 +22,10 @@ Widget boilerplate({required Widget child}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
RenderObject getOverlayColor(WidgetTester tester) {
|
||||||
|
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||||
|
}
|
||||||
|
|
||||||
testWidgets('SegmentsButton when compositing does not crash', (WidgetTester tester) async {
|
testWidgets('SegmentsButton when compositing does not crash', (WidgetTester tester) async {
|
||||||
// Regression test for https://github.com/flutter/flutter/issues/135747
|
// Regression test for https://github.com/flutter/flutter/issues/135747
|
||||||
// If the render object holds on to a stale canvas reference, this will
|
// If the render object holds on to a stale canvas reference, this will
|
||||||
@ -584,10 +589,6 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderObject overlayColor() {
|
|
||||||
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
|
||||||
}
|
|
||||||
|
|
||||||
final Material material = tester.widget<Material>(find.descendant(
|
final Material material = tester.widget<Material>(find.descendant(
|
||||||
of: find.byType(TextButton),
|
of: find.byType(TextButton),
|
||||||
matching: find.byType(Material),
|
matching: find.byType(Material),
|
||||||
@ -601,13 +602,13 @@ void main() {
|
|||||||
await gesture.addPointer();
|
await gesture.addPointer();
|
||||||
await gesture.moveTo(center);
|
await gesture.moveTo(center);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect(color: theme.colorScheme.onSurface.withOpacity(0.08)));
|
expect(getOverlayColor(tester), paints..rect(color: theme.colorScheme.onSurface.withOpacity(0.08)));
|
||||||
expect(material.textStyle?.color, theme.colorScheme.onSurface);
|
expect(material.textStyle?.color, theme.colorScheme.onSurface);
|
||||||
|
|
||||||
// Highlighted (pressed).
|
// Highlighted (pressed).
|
||||||
await gesture.down(center);
|
await gesture.down(center);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect()..rect(color: theme.colorScheme.onSurface.withOpacity(0.1)));
|
expect(getOverlayColor(tester), paints..rect()..rect(color: theme.colorScheme.onSurface.withOpacity(0.1)));
|
||||||
expect(material.textStyle?.color, theme.colorScheme.onSurface);
|
expect(material.textStyle?.color, theme.colorScheme.onSurface);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -763,16 +764,13 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Test foreground color is applied to the overlay color.
|
// Test foreground color is applied to the overlay color.
|
||||||
RenderObject overlayColor() {
|
|
||||||
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
|
||||||
}
|
|
||||||
final TestGesture gesture = await tester.createGesture(
|
final TestGesture gesture = await tester.createGesture(
|
||||||
kind: PointerDeviceKind.mouse,
|
kind: PointerDeviceKind.mouse,
|
||||||
);
|
);
|
||||||
await gesture.addPointer();
|
await gesture.addPointer();
|
||||||
await gesture.down(tester.getCenter(find.text('1')));
|
await gesture.down(tester.getCenter(find.text('1')));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(overlayColor(), paints..rect(color: foregroundColor.withOpacity(0.08)));
|
expect(getOverlayColor(tester), paints..rect(color: foregroundColor.withOpacity(0.08)));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Disabled SegmentedButton has correct states when rebuilding', (WidgetTester tester) async {
|
testWidgets('Disabled SegmentedButton has correct states when rebuilding', (WidgetTester tester) async {
|
||||||
@ -909,6 +907,144 @@ void main() {
|
|||||||
// The width of the SegmentedButton must be less than the width of the parent widget.
|
// The width of the SegmentedButton must be less than the width of the parent widget.
|
||||||
expect(segmentedButtonWidth, lessThan(screenWidth));
|
expect(segmentedButtonWidth, lessThan(screenWidth));
|
||||||
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/145527
|
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/145527
|
||||||
|
|
||||||
|
testWidgets('SegmentedButton.styleFrom overlayColor overrides default overlay color', (WidgetTester tester) async {
|
||||||
|
const Color overlayColor = Color(0xffff0000);
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: SegmentedButton<int>(
|
||||||
|
style: IconButton.styleFrom(overlayColor: overlayColor),
|
||||||
|
segments: const <ButtonSegment<int>>[
|
||||||
|
ButtonSegment<int>(
|
||||||
|
value: 0,
|
||||||
|
label: Text('Option 1'),
|
||||||
|
),
|
||||||
|
ButtonSegment<int>(
|
||||||
|
value: 1,
|
||||||
|
label: Text('Option 2'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
onSelectionChanged: (Set<int> selected) {},
|
||||||
|
selected: const <int>{1},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hovered selected segment,
|
||||||
|
Offset center = tester.getCenter(find.text('Option 1'));
|
||||||
|
final TestGesture gesture = await tester.createGesture(
|
||||||
|
kind: PointerDeviceKind.mouse,
|
||||||
|
);
|
||||||
|
await gesture.addPointer();
|
||||||
|
await gesture.moveTo(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08)));
|
||||||
|
|
||||||
|
// Hovered unselected segment,
|
||||||
|
center = tester.getCenter(find.text('Option 2'));
|
||||||
|
await gesture.moveTo(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08)));
|
||||||
|
|
||||||
|
// Highlighted unselected segment (pressed).
|
||||||
|
center = tester.getCenter(find.text('Option 1'));
|
||||||
|
await gesture.down(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(
|
||||||
|
getOverlayColor(tester),
|
||||||
|
paints
|
||||||
|
..rect(color: overlayColor.withOpacity(0.08))
|
||||||
|
..rect(color: overlayColor.withOpacity(0.1)),
|
||||||
|
);
|
||||||
|
// Remove pressed and hovered states,
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await gesture.moveTo(const Offset(0, 50));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Highlighted selected segment (pressed)
|
||||||
|
center = tester.getCenter(find.text('Option 2'));
|
||||||
|
await gesture.down(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(
|
||||||
|
getOverlayColor(tester),
|
||||||
|
paints
|
||||||
|
..rect(color: overlayColor.withOpacity(0.08))
|
||||||
|
..rect(color: overlayColor.withOpacity(0.1)),
|
||||||
|
);
|
||||||
|
// Remove pressed and hovered states,
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await gesture.moveTo(const Offset(0, 50));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Focused unselected segment.
|
||||||
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.1)));
|
||||||
|
|
||||||
|
// Focused selected segment.
|
||||||
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.1)));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('SegmentedButton.styleFrom with transparent overlayColor', (WidgetTester tester) async {
|
||||||
|
const Color overlayColor = Colors.transparent;
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: SegmentedButton<int>(
|
||||||
|
style: IconButton.styleFrom(overlayColor: overlayColor),
|
||||||
|
segments: const <ButtonSegment<int>>[
|
||||||
|
ButtonSegment<int>(
|
||||||
|
value: 0,
|
||||||
|
label: Text('Option'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
onSelectionChanged: (Set<int> selected) {},
|
||||||
|
selected: const <int>{0},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hovered,
|
||||||
|
final Offset center = tester.getCenter(find.text('Option'));
|
||||||
|
final TestGesture gesture = await tester.createGesture(
|
||||||
|
kind: PointerDeviceKind.mouse,
|
||||||
|
);
|
||||||
|
await gesture.addPointer();
|
||||||
|
await gesture.moveTo(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor));
|
||||||
|
|
||||||
|
// Highlighted (pressed).
|
||||||
|
await gesture.down(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(
|
||||||
|
getOverlayColor(tester),
|
||||||
|
paints
|
||||||
|
..rect(color: overlayColor)
|
||||||
|
..rect(color: overlayColor),
|
||||||
|
);
|
||||||
|
// Remove pressed and hovered states,
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await gesture.moveTo(const Offset(0, 50));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Focused.
|
||||||
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<MaterialState> enabled = const <MaterialState>{};
|
Set<MaterialState> enabled = const <MaterialState>{};
|
||||||
|
@ -3,10 +3,15 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
RenderObject getOverlayColor(WidgetTester tester) {
|
||||||
|
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||||
|
}
|
||||||
|
|
||||||
test('SegmentedButtonThemeData copyWith, ==, hashCode basics', () {
|
test('SegmentedButtonThemeData copyWith, ==, hashCode basics', () {
|
||||||
expect(const SegmentedButtonThemeData(), const SegmentedButtonThemeData().copyWith());
|
expect(const SegmentedButtonThemeData(), const SegmentedButtonThemeData().copyWith());
|
||||||
@ -476,4 +481,93 @@ void main() {
|
|||||||
expect(selectedIcon, findsNothing);
|
expect(selectedIcon, findsNothing);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('SegmentedButtonTheme SegmentedButton.styleFrom overlayColor overrides default overlay color', (WidgetTester tester) async {
|
||||||
|
const Color overlayColor = Color(0xffff0000);
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
segmentedButtonTheme: SegmentedButtonThemeData(
|
||||||
|
style: SegmentedButton.styleFrom(overlayColor: overlayColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
home: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: SegmentedButton<int>(
|
||||||
|
segments: const <ButtonSegment<int>>[
|
||||||
|
ButtonSegment<int>(
|
||||||
|
value: 0,
|
||||||
|
label: Text('Option 1'),
|
||||||
|
),
|
||||||
|
ButtonSegment<int>(
|
||||||
|
value: 1,
|
||||||
|
label: Text('Option 2'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
onSelectionChanged: (Set<int> selected) {},
|
||||||
|
selected: const <int>{1},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hovered selected segment,
|
||||||
|
Offset center = tester.getCenter(find.text('Option 1'));
|
||||||
|
final TestGesture gesture = await tester.createGesture(
|
||||||
|
kind: PointerDeviceKind.mouse,
|
||||||
|
);
|
||||||
|
await gesture.addPointer();
|
||||||
|
await gesture.moveTo(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08)));
|
||||||
|
|
||||||
|
// Hovered unselected segment,
|
||||||
|
center = tester.getCenter(find.text('Option 2'));
|
||||||
|
await gesture.moveTo(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08)));
|
||||||
|
|
||||||
|
// Highlighted unselected segment (pressed).
|
||||||
|
center = tester.getCenter(find.text('Option 1'));
|
||||||
|
await gesture.down(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(
|
||||||
|
getOverlayColor(tester),
|
||||||
|
paints
|
||||||
|
..rect(color: overlayColor.withOpacity(0.08))
|
||||||
|
..rect(color: overlayColor.withOpacity(0.1)),
|
||||||
|
);
|
||||||
|
// Remove pressed and hovered states,
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await gesture.moveTo(const Offset(0, 50));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Highlighted selected segment (pressed)
|
||||||
|
center = tester.getCenter(find.text('Option 2'));
|
||||||
|
await gesture.down(center);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(
|
||||||
|
getOverlayColor(tester),
|
||||||
|
paints
|
||||||
|
..rect(color: overlayColor.withOpacity(0.08))
|
||||||
|
..rect(color: overlayColor.withOpacity(0.1)),
|
||||||
|
);
|
||||||
|
// Remove pressed and hovered states,
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await gesture.moveTo(const Offset(0, 50));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Focused unselected segment.
|
||||||
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.1)));
|
||||||
|
|
||||||
|
// Focused selected segment.
|
||||||
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.1)));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user