Unverified Commit a6187d9a authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Fix `DatePicker` uses incorrect overlay color from `DatePickerTheme` and add...

Fix `DatePicker` uses incorrect overlay color from `DatePickerTheme` and add missing tests (#130584)

fixes [YearPickerState in calendar_date_picker is using dayOverlayColor instead of yearOverlayColor](https://github.com/flutter/flutter/issues/130051)

### Description

- Fix year selection uses incorrect overlay color from `DatePickerTheme`
- Update defaults tests to check for overlay color for different modes
- Add tests to check overlay color is resolved.

### Code sample

<details> 
<summary>expand to view the code sample</summary> 

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

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        datePickerTheme: const DatePickerThemeData(
          yearOverlayColor: MaterialStatePropertyAll<Color>(Colors.green),
          dayOverlayColor: MaterialStatePropertyAll<Color>(Colors.amber),
        ),
        useMaterial3: true,
      ),
      home: Directionality(
        textDirection: TextDirection.ltr,
        child: Material(
          child: Center(
            child: DatePickerDialog(
              initialDate: DateTime(2023, DateTime.january, 25),
              firstDate: DateTime(2022),
              lastDate: DateTime(2024, DateTime.december, 31),
              currentDate: DateTime(2023, DateTime.january, 24),
            ),
          ),
        ),
      ),
    );
  }
}

``` 
	
</details>

```dart
          yearOverlayColor: MaterialStatePropertyAll<Color>(Colors.green),
          dayOverlayColor: MaterialStatePropertyAll<Color>(Colors.red),
```

### Before
![Screenshot 2023-07-14 at 18 39 51](https://github.com/flutter/flutter/assets/48603081/52ec5096-bad6-4753-9e9a-15b6d5ce767e)

### After
![Screenshot 2023-07-14 at 18 38 32](https://github.com/flutter/flutter/assets/48603081/a51aeca8-a5c2-42b4-8c05-b55f9955e860)
parent f4da0962
......@@ -1191,7 +1191,7 @@ class _YearPickerState extends State<YearPicker> {
final Color? background = resolve<Color?>((DatePickerThemeData? theme) => isCurrentYear ? theme?.todayBackgroundColor : theme?.yearBackgroundColor, states);
final MaterialStateProperty<Color?> overlayColor =
MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) =>
effectiveValue((DatePickerThemeData? theme) => theme?.dayOverlayColor?.resolve(states)),
effectiveValue((DatePickerThemeData? theme) => theme?.yearOverlayColor?.resolve(states)),
);
BoxBorder? border;
......
......@@ -3,9 +3,13 @@
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart';
void main() {
const DatePickerThemeData datePickerTheme = DatePickerThemeData(
backgroundColor: Color(0xfffffff0),
......@@ -389,6 +393,16 @@ void main() {
expect(day24Decoration.border?.top.width, datePickerTheme.todayBorder?.width);
expect(day24Decoration.border?.bottom.width, datePickerTheme.todayBorder?.width);
// Test the day overlay color.
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
final TestGesture gesture = await tester.createGesture(
kind: PointerDeviceKind.mouse,
);
await gesture.addPointer();
await gesture.moveTo(tester.getCenter(find.text('25')));
await tester.pumpAndSettle();
expect(inkFeatures, paints..circle(color: datePickerTheme.dayOverlayColor?.resolve(<MaterialState>{})));
// Show the year selector.
await tester.tap(find.text('January 2023'));
......@@ -409,6 +423,11 @@ void main() {
expect(year2023Decoration.border?.bottom.width, datePickerTheme.todayBorder?.width);
expect(year2023Decoration.border?.top.color, datePickerTheme.todayForegroundColor?.resolve(<MaterialState>{}));
expect(year2023Decoration.border?.bottom.color, datePickerTheme.todayForegroundColor?.resolve(<MaterialState>{}));
// Test the year overlay color.
await gesture.moveTo(tester.getCenter(find.text('2024')));
await tester.pumpAndSettle();
expect(inkFeatures, paints..rect(color: datePickerTheme.yearOverlayColor?.resolve(<MaterialState>{})));
});
testWidgets('DatePickerDialog uses ThemeData datePicker theme (input mode)', (WidgetTester tester) async {
......@@ -496,6 +515,21 @@ void main() {
final Text selectedDate = tester.widget<Text>(find.text('Jan 17'));
expect(selectedDate.style?.color, datePickerTheme.rangePickerHeaderForegroundColor);
expect(selectedDate.style?.fontSize, datePickerTheme.rangePickerHeaderHeadlineStyle?.fontSize);
// Test the day overlay color.
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
final TestGesture gesture = await tester.createGesture(
kind: PointerDeviceKind.mouse,
);
await gesture.addPointer();
await gesture.moveTo(tester.getCenter(find.text('16')));
await tester.pumpAndSettle();
expect(inkFeatures, paints..circle(color: datePickerTheme.dayOverlayColor?.resolve(<MaterialState>{})));
// Test the range selection overlay color.
await gesture.moveTo(tester.getCenter(find.text('18')));
await tester.pumpAndSettle();
expect(inkFeatures, paints..circle(color: datePickerTheme.rangeSelectionOverlayColor?.resolve(<MaterialState>{})));
});
testWidgets('Dividers use DatePickerThemeData.dividerColor', (WidgetTester tester) async {
......@@ -594,4 +628,252 @@ void main() {
expect(inputDecoration.fillColor, const Color(0xFF00FF00));
expect(inputDecoration.border , const OutlineInputBorder());
});
testWidgets('DatePickerDialog resolves DatePickerTheme.dayOverlayColor states', (WidgetTester tester) async {
final MaterialStateProperty<Color> dayOverlayColor = MaterialStateProperty.resolveWith<Color>((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered)) {
return const Color(0xff00ff00);
}
if (states.contains(MaterialState.focused)) {
return const Color(0xffff00ff);
}
if (states.contains(MaterialState.pressed)) {
return const Color(0xffffff00);
}
return Colors.transparent;
});
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
datePickerTheme: DatePickerThemeData(
dayOverlayColor: dayOverlayColor,
),
useMaterial3: true,
),
home: Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: Focus(
child: DatePickerDialog(
initialDate: DateTime(2023, DateTime.january, 25),
firstDate: DateTime(2022),
lastDate: DateTime(2024, DateTime.december, 31),
currentDate: DateTime(2023, DateTime.january, 24),
),
),
),
),
),
),
);
// Test the hover overlay color.
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
final TestGesture gesture = await tester.createGesture(
kind: PointerDeviceKind.mouse,
);
await gesture.addPointer();
await gesture.moveTo(tester.getCenter(find.text('20')));
await tester.pumpAndSettle();
expect(
inkFeatures,
paints
..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.hovered})),
);
// Test the pressed overlay color.
await gesture.down(tester.getCenter(find.text('20')));
await tester.pumpAndSettle();
if (kIsWeb) {
// An extra circle is painted on the web for the hovered state.
expect(
inkFeatures,
paints
..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.pressed})),
);
} else {
expect(
inkFeatures,
paints
..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.pressed})),
);
}
await gesture.removePointer();
await tester.pumpAndSettle();
// Focus day selection.
for (int i = 0; i < 5; i++) {
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.pumpAndSettle();
}
// Test the focused overlay color.
expect(
inkFeatures,
paints
..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.focused})),
);
});
testWidgets('DatePickerDialog resolves DatePickerTheme.yearOverlayColor states', (WidgetTester tester) async {
final MaterialStateProperty<Color> yearOverlayColor = MaterialStateProperty.resolveWith<Color>((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered)) {
return const Color(0xff00ff00);
}
if (states.contains(MaterialState.focused)) {
return const Color(0xffff00ff);
}
if (states.contains(MaterialState.pressed)) {
return const Color(0xffffff00);
}
return Colors.transparent;
});
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
datePickerTheme: DatePickerThemeData(
yearOverlayColor: yearOverlayColor,
),
useMaterial3: true,
),
home: Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: Focus(
child: DatePickerDialog(
initialDate: DateTime(2023, DateTime.january, 25),
firstDate: DateTime(2022),
lastDate: DateTime(2024, DateTime.december, 31),
currentDate: DateTime(2023, DateTime.january, 24),
initialCalendarMode: DatePickerMode.year,
),
),
),
),
),
),
);
// Test the hover overlay color.
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
final TestGesture gesture = await tester.createGesture(
kind: PointerDeviceKind.mouse,
);
await gesture.addPointer();
await gesture.moveTo(tester.getCenter(find.text('2022')));
await tester.pumpAndSettle();
expect(
inkFeatures,
paints
..rect(color: yearOverlayColor.resolve(<MaterialState>{MaterialState.hovered})),
);
// Test the pressed overlay color.
await gesture.down(tester.getCenter(find.text('2022')));
await tester.pumpAndSettle();
expect(
inkFeatures,
paints
..rect(color: yearOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
..rect(color: yearOverlayColor.resolve(<MaterialState>{MaterialState.pressed})),
);
await gesture.removePointer();
await tester.pumpAndSettle();
// Focus year selection.
for (int i = 0; i < 3; i++) {
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.pumpAndSettle();
}
// Test the focused overlay color.
expect(
inkFeatures,
paints
..rect(color: yearOverlayColor.resolve(<MaterialState>{MaterialState.focused})),
);
});
testWidgets('DateRangePickerDialog resolves DatePickerTheme.rangeSelectionOverlayColor states', (WidgetTester tester) async {
final MaterialStateProperty<Color> rangeSelectionOverlayColor = MaterialStateProperty.resolveWith<Color>((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered)) {
return const Color(0xff00ff00);
}
if (states.contains(MaterialState.pressed)) {
return const Color(0xffffff00);
}
return Colors.transparent;
});
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
datePickerTheme: DatePickerThemeData(
rangeSelectionOverlayColor: rangeSelectionOverlayColor,
),
useMaterial3: true,
),
home: Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: DateRangePickerDialog(
firstDate: DateTime(2023),
lastDate: DateTime(2023, DateTime.january, 31),
initialDateRange: DateTimeRange(
start: DateTime(2023, DateTime.january, 17),
end: DateTime(2023, DateTime.january, 20),
),
currentDate: DateTime(2023, DateTime.january, 23),
),
),
),
),
),
);
// Test the hover overlay color.
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
final TestGesture gesture = await tester.createGesture(
kind: PointerDeviceKind.mouse,
);
await gesture.addPointer();
await gesture.moveTo(tester.getCenter(find.text('18')));
await tester.pumpAndSettle();
expect(
inkFeatures,
paints
..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.hovered})),
);
// Test the pressed overlay color.
await gesture.down(tester.getCenter(find.text('18')));
await tester.pumpAndSettle();
if (kIsWeb) {
// An extra circle is painted on the web for the hovered state.
expect(
inkFeatures,
paints
..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.pressed})),
);
} else {
expect(
inkFeatures,
paints
..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.pressed})),
);
}
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment