Add mouse region for InputDecorationIcons in the textfield (#112543)
* Update mouse region
* Update text_field_test.dart
* lint
diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart
index d9f118e..f93a352 100644
--- a/packages/flutter/lib/src/material/input_decorator.dart
+++ b/packages/flutter/lib/src/material/input_decorator.dart
@@ -2209,14 +2209,17 @@
final double iconSize = decorationIsDense ? 18.0 : 24.0;
final Widget? icon = decoration.icon == null ? null :
- Padding(
- padding: const EdgeInsetsDirectional.only(end: 16.0),
- child: IconTheme.merge(
- data: IconThemeData(
- color: _getIconColor(themeData, defaults),
- size: iconSize,
+ MouseRegion(
+ cursor: SystemMouseCursors.basic,
+ child: Padding(
+ padding: const EdgeInsetsDirectional.only(end: 16.0),
+ child: IconTheme.merge(
+ data: IconThemeData(
+ color: _getIconColor(themeData, defaults),
+ size: iconSize,
+ ),
+ child: decoration.icon!,
),
- child: decoration.icon!,
),
);
@@ -2224,20 +2227,24 @@
Center(
widthFactor: 1.0,
heightFactor: 1.0,
- child: ConstrainedBox(
- constraints: decoration.prefixIconConstraints ?? themeData.visualDensity.effectiveConstraints(
- const BoxConstraints(
- minWidth: kMinInteractiveDimension,
- minHeight: kMinInteractiveDimension,
+ child: MouseRegion(
+ cursor: SystemMouseCursors.basic,
+ child: ConstrainedBox(
+ constraints: decoration.prefixIconConstraints ??
+ themeData.visualDensity.effectiveConstraints(
+ const BoxConstraints(
+ minWidth: kMinInteractiveDimension,
+ minHeight: kMinInteractiveDimension,
+ ),
+ ),
+ child: IconTheme.merge(
+ data: IconThemeData(
+ color: _getPrefixIconColor(themeData, defaults),
+ size: iconSize,
+ ),
+ child: decoration.prefixIcon!,
),
),
- child: IconTheme.merge(
- data: IconThemeData(
- color: _getPrefixIconColor(themeData, defaults),
- size: iconSize,
- ),
- child: decoration.prefixIcon!,
- ),
),
);
@@ -2245,20 +2252,24 @@
Center(
widthFactor: 1.0,
heightFactor: 1.0,
- child: ConstrainedBox(
- constraints: decoration.suffixIconConstraints ?? themeData.visualDensity.effectiveConstraints(
- const BoxConstraints(
- minWidth: kMinInteractiveDimension,
- minHeight: kMinInteractiveDimension,
+ child: MouseRegion(
+ cursor: SystemMouseCursors.basic,
+ child: ConstrainedBox(
+ constraints: decoration.suffixIconConstraints ??
+ themeData.visualDensity.effectiveConstraints(
+ const BoxConstraints(
+ minWidth: kMinInteractiveDimension,
+ minHeight: kMinInteractiveDimension,
+ ),
+ ),
+ child: IconTheme.merge(
+ data: IconThemeData(
+ color: _getSuffixIconColor(themeData, defaults),
+ size: iconSize,
+ ),
+ child: decoration.suffixIcon!,
),
),
- child: IconTheme.merge(
- data: IconThemeData(
- color: _getSuffixIconColor(themeData, defaults),
- size: iconSize,
- ),
- child: decoration.suffixIcon!,
- ),
),
);
diff --git a/packages/flutter/test/material/text_field_test.dart b/packages/flutter/test/material/text_field_test.dart
index 731a76b..e3afd17 100644
--- a/packages/flutter/test/material/text_field_test.dart
+++ b/packages/flutter/test/material/text_field_test.dart
@@ -10678,6 +10678,94 @@
await gesture.moveTo(center);
});
+ testWidgets('TextField icons change mouse cursor when hovered', (WidgetTester tester) async {
+ // Test default cursor in icons area.
+ await tester.pumpWidget(
+ const MaterialApp(
+ home: Material(
+ child: MouseRegion(
+ cursor: SystemMouseCursors.forbidden,
+ child: TextField(
+ decoration: InputDecoration(
+ icon: Icon(Icons.label),
+ prefixIcon: Icon(Icons.cabin),
+ suffixIcon: Icon(Icons.person),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ // Center, which is within the text area
+ final Offset center = tester.getCenter(find.byType(TextField));
+ // The Icon area
+ final Offset iconArea = tester.getCenter(find.byIcon(Icons.label));
+ // The prefix Icon area
+ final Offset prefixIconArea = tester.getCenter(find.byIcon(Icons.cabin));
+ // The suffix Icon area
+ final Offset suffixIconArea = tester.getCenter(find.byIcon(Icons.person));
+
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
+ await gesture.addPointer(location: center);
+
+ await tester.pump();
+
+ await gesture.moveTo(center);
+ expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
+
+ await gesture.moveTo(iconArea);
+ expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
+
+ await gesture.moveTo(prefixIconArea);
+ expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
+
+ await gesture.moveTo(suffixIconArea);
+ expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
+ await gesture.moveTo(center);
+
+ // Test click cursor in icons area for buttons.
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Material(
+ child: MouseRegion(
+ cursor: SystemMouseCursors.forbidden,
+ child: TextField(
+ decoration: InputDecoration(
+ icon: IconButton(
+ icon: const Icon(Icons.label),
+ onPressed: () {},
+ ),
+ prefixIcon: IconButton(
+ icon: const Icon(Icons.cabin),
+ onPressed: () {},
+ ),
+ suffixIcon: IconButton(
+ icon: const Icon(Icons.person),
+ onPressed: () {},
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ await tester.pump();
+
+ await gesture.moveTo(center);
+ expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
+
+ await gesture.moveTo(iconArea);
+ expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
+
+ await gesture.moveTo(prefixIconArea);
+ expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
+
+ await gesture.moveTo(suffixIconArea);
+ expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
+ });
+
testWidgets('Text selection menu does not change mouse cursor when hovered', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',