1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'package:flutter/foundation.dart';
6import 'package:flutter/gestures.dart';
7import 'package:flutter/material.dart';
8import 'package:flutter/services.dart';
9import 'package:flutter_test/flutter_test.dart';
10
11void main() {
12 const DatePickerThemeData datePickerTheme = DatePickerThemeData(
13 backgroundColor: Color(0xfffffff0),
14 elevation: 6,
15 shadowColor: Color(0xfffffff1),
16 surfaceTintColor: Color(0xfffffff2),
17 shape: RoundedRectangleBorder(),
18 headerBackgroundColor: Color(0xfffffff3),
19 headerForegroundColor: Color(0xfffffff4),
20 headerHeadlineStyle: TextStyle(fontSize: 10),
21 headerHelpStyle: TextStyle(fontSize: 11),
22 weekdayStyle: TextStyle(fontSize: 12),
23 dayStyle: TextStyle(fontSize: 13),
24 dayForegroundColor: MaterialStatePropertyAll<Color>(Color(0xfffffff5)),
25 dayBackgroundColor: MaterialStatePropertyAll<Color>(Color(0xfffffff6)),
26 dayOverlayColor: MaterialStatePropertyAll<Color>(Color(0xfffffff7)),
27 dayShape: MaterialStatePropertyAll<OutlinedBorder>(RoundedRectangleBorder()),
28 todayForegroundColor: MaterialStatePropertyAll<Color>(Color(0xfffffff8)),
29 todayBackgroundColor: MaterialStatePropertyAll<Color>(Color(0xfffffff9)),
30 todayBorder: BorderSide(width: 3),
31 yearStyle: TextStyle(fontSize: 13),
32 yearForegroundColor: MaterialStatePropertyAll<Color>(Color(0xfffffffa)),
33 yearBackgroundColor: MaterialStatePropertyAll<Color>(Color(0xfffffffb)),
34 yearOverlayColor: MaterialStatePropertyAll<Color>(Color(0xfffffffc)),
35 rangePickerBackgroundColor: Color(0xfffffffd),
36 rangePickerElevation: 7,
37 rangePickerShadowColor: Color(0xfffffffe),
38 rangePickerSurfaceTintColor: Color(0xffffffff),
39 rangePickerShape: RoundedRectangleBorder(),
40 rangePickerHeaderBackgroundColor: Color(0xffffff0f),
41 rangePickerHeaderForegroundColor: Color(0xffffff1f),
42 rangePickerHeaderHeadlineStyle: TextStyle(fontSize: 14),
43 rangePickerHeaderHelpStyle: TextStyle(fontSize: 15),
44 rangeSelectionBackgroundColor: Color(0xffffff2f),
45 rangeSelectionOverlayColor: MaterialStatePropertyAll<Color>(Color(0xffffff3f)),
46 dividerColor: Color(0xffffff4f),
47 inputDecorationTheme: InputDecorationTheme(
48 fillColor: Color(0xffffff5f),
49 border: UnderlineInputBorder(),
50 ),
51 cancelButtonStyle: ButtonStyle(foregroundColor: MaterialStatePropertyAll<Color>(Color(0xffffff6f))),
52 confirmButtonStyle: ButtonStyle(foregroundColor: MaterialStatePropertyAll<Color>(Color(0xffffff7f))),
53 locale: Locale('en'),
54 );
55
56 Material findDialogMaterial(WidgetTester tester) {
57 return tester.widget<Material>(
58 find.descendant(
59 of: find.byType(Dialog),
60 matching: find.byType(Material)
61 ).first
62 );
63 }
64
65 Material findHeaderMaterial(WidgetTester tester, String text) {
66 return tester.widget<Material>(
67 find.ancestor(
68 of: find.text(text),
69 matching: find.byType(Material)
70 ).first,
71 );
72 }
73
74 BoxDecoration? findTextDecoration(WidgetTester tester, String date) {
75 final Container container = tester.widget<Container>(
76 find.ancestor(
77 of: find.text(date),
78 matching: find.byType(Container)
79 ).first,
80 );
81 return container.decoration as BoxDecoration?;
82 }
83
84 ShapeDecoration? findDayDecoration(WidgetTester tester, String day) {
85 return tester.widget<DecoratedBox>(
86 find.ancestor(
87 of: find.text(day),
88 matching: find.byType(DecoratedBox)
89 ),
90 ).decoration as ShapeDecoration?;
91 }
92
93 ButtonStyle actionButtonStyle(WidgetTester tester, String text) {
94 return tester.widget<TextButton>(find.widgetWithText(TextButton, text)).style!;
95 }
96
97 const Size wideWindowSize = Size(1920.0, 1080.0);
98 const Size narrowWindowSize = Size(1070.0, 1770.0);
99
100 test('DatePickerThemeData copyWith, ==, hashCode basics', () {
101 expect(const DatePickerThemeData(), const DatePickerThemeData().copyWith());
102 expect(const DatePickerThemeData().hashCode, const DatePickerThemeData().copyWith().hashCode);
103 });
104
105 test('DatePickerThemeData lerp special cases', () {
106 const DatePickerThemeData data = DatePickerThemeData();
107 expect(identical(DatePickerThemeData.lerp(data, data, 0.5), data), true);
108 });
109
110 test('DatePickerThemeData defaults', () {
111 const DatePickerThemeData theme = DatePickerThemeData();
112 expect(theme.backgroundColor, null);
113 expect(theme.elevation, null);
114 expect(theme.shadowColor, null);
115 expect(theme.surfaceTintColor, null);
116 expect(theme.shape, null);
117 expect(theme.headerBackgroundColor, null);
118 expect(theme.headerForegroundColor, null);
119 expect(theme.headerHeadlineStyle, null);
120 expect(theme.headerHelpStyle, null);
121 expect(theme.weekdayStyle, null);
122 expect(theme.dayStyle, null);
123 expect(theme.dayForegroundColor, null);
124 expect(theme.dayBackgroundColor, null);
125 expect(theme.dayOverlayColor, null);
126 expect(theme.dayShape, null);
127 expect(theme.todayForegroundColor, null);
128 expect(theme.todayBackgroundColor, null);
129 expect(theme.todayBorder, null);
130 expect(theme.yearStyle, null);
131 expect(theme.yearForegroundColor, null);
132 expect(theme.yearBackgroundColor, null);
133 expect(theme.yearOverlayColor, null);
134 expect(theme.rangePickerBackgroundColor, null);
135 expect(theme.rangePickerElevation, null);
136 expect(theme.rangePickerShadowColor, null);
137 expect(theme.rangePickerSurfaceTintColor, null);
138 expect(theme.rangePickerShape, null);
139 expect(theme.rangePickerHeaderBackgroundColor, null);
140 expect(theme.rangePickerHeaderForegroundColor, null);
141 expect(theme.rangePickerHeaderHeadlineStyle, null);
142 expect(theme.rangePickerHeaderHelpStyle, null);
143 expect(theme.rangeSelectionBackgroundColor, null);
144 expect(theme.rangeSelectionOverlayColor, null);
145 expect(theme.dividerColor, null);
146 expect(theme.inputDecorationTheme, null);
147 expect(theme.cancelButtonStyle, null);
148 expect(theme.confirmButtonStyle, null);
149 expect(theme.locale, null);
150 });
151
152 testWidgets('DatePickerTheme.defaults M3 defaults', (WidgetTester tester) async {
153 late final DatePickerThemeData m3; // M3 Defaults
154 late final ThemeData theme;
155 late final ColorScheme colorScheme;
156 late final TextTheme textTheme;
157
158 await tester.pumpWidget(
159 MaterialApp(
160 theme: ThemeData(useMaterial3: true),
161 home: Builder(
162 builder: (BuildContext context) {
163 m3 = DatePickerTheme.defaults(context);
164 theme = Theme.of(context);
165 colorScheme = theme.colorScheme;
166 textTheme = theme.textTheme;
167 return Container();
168 },
169 ),
170 ),
171 );
172
173 expect(m3.backgroundColor, colorScheme.surfaceContainerHigh);
174 expect(m3.elevation, 6);
175 expect(m3.shadowColor, const Color(0x00000000)); // Colors.transparent
176 expect(m3.surfaceTintColor, Colors.transparent);
177 expect(m3.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)));
178 expect(m3.headerBackgroundColor, const Color(0x00000000)); // Colors.transparent
179 expect(m3.headerForegroundColor, colorScheme.onSurfaceVariant);
180 expect(m3.headerHeadlineStyle, textTheme.headlineLarge);
181 expect(m3.headerHelpStyle, textTheme.labelLarge);
182 expect(m3.weekdayStyle, textTheme.bodyLarge?.apply(color: colorScheme.onSurface));
183 expect(m3.dayStyle, textTheme.bodyLarge);
184 expect(m3.dayForegroundColor?.resolve(<MaterialState>{}), colorScheme.onSurface);
185 expect(m3.dayForegroundColor?.resolve(<MaterialState>{MaterialState.selected}), colorScheme.onPrimary);
186 expect(m3.dayForegroundColor?.resolve(<MaterialState>{MaterialState.disabled}), colorScheme.onSurface.withOpacity(0.38));
187 expect(m3.dayBackgroundColor?.resolve(<MaterialState>{}), null);
188 expect(m3.dayBackgroundColor?.resolve(<MaterialState>{MaterialState.selected}), colorScheme.primary);
189 expect(m3.dayOverlayColor?.resolve(<MaterialState>{}), null);
190 expect(m3.dayOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.hovered}), colorScheme.onPrimary.withOpacity(0.08));
191 expect(m3.dayOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.focused}), colorScheme.onPrimary.withOpacity(0.1));
192 expect(m3.dayOverlayColor?.resolve(<MaterialState>{MaterialState.hovered}), colorScheme.onSurfaceVariant.withOpacity(0.08));
193 expect(m3.dayOverlayColor?.resolve(<MaterialState>{MaterialState.focused}), colorScheme.onSurfaceVariant.withOpacity(0.1));
194 expect(m3.dayOverlayColor?.resolve(<MaterialState>{MaterialState.pressed}), colorScheme.onSurfaceVariant.withOpacity(0.1));
195 expect(m3.dayOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.hovered, MaterialState.focused}), colorScheme.onPrimary.withOpacity(0.08));
196 expect(m3.dayOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.hovered, MaterialState.pressed}), colorScheme.onPrimary.withOpacity(0.1));
197 expect(m3.dayOverlayColor?.resolve(<MaterialState>{MaterialState.hovered, MaterialState.focused}), colorScheme.onSurfaceVariant.withOpacity(0.08));
198 expect(m3.dayOverlayColor?.resolve(<MaterialState>{MaterialState.hovered, MaterialState.pressed}), colorScheme.onSurfaceVariant.withOpacity(0.1));
199 expect(m3.dayShape?.resolve(<MaterialState>{}), const CircleBorder());
200 expect(m3.todayForegroundColor?.resolve(<MaterialState>{}), colorScheme.primary);
201 expect(m3.todayForegroundColor?.resolve(<MaterialState>{MaterialState.disabled}), colorScheme.primary.withOpacity(0.38));
202 expect(m3.todayBorder, BorderSide(color: colorScheme.primary));
203 expect(m3.yearStyle, textTheme.bodyLarge);
204 expect(m3.yearForegroundColor?.resolve(<MaterialState>{}), colorScheme.onSurfaceVariant);
205 expect(m3.yearForegroundColor?.resolve(<MaterialState>{MaterialState.selected}), colorScheme.onPrimary);
206 expect(m3.yearForegroundColor?.resolve(<MaterialState>{MaterialState.disabled}), colorScheme.onSurfaceVariant.withOpacity(0.38));
207 expect(m3.yearBackgroundColor?.resolve(<MaterialState>{}), null);
208 expect(m3.yearBackgroundColor?.resolve(<MaterialState>{MaterialState.selected}), colorScheme.primary);
209 expect(m3.yearOverlayColor?.resolve(<MaterialState>{}), null);
210 expect(m3.yearOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.hovered}), colorScheme.onPrimary.withOpacity(0.08));
211 expect(m3.yearOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.focused}), colorScheme.onPrimary.withOpacity(0.1));
212 expect(m3.yearOverlayColor?.resolve(<MaterialState>{MaterialState.hovered}), colorScheme.onSurfaceVariant.withOpacity(0.08));
213 expect(m3.yearOverlayColor?.resolve(<MaterialState>{MaterialState.focused}), colorScheme.onSurfaceVariant.withOpacity(0.1));
214 expect(m3.yearOverlayColor?.resolve(<MaterialState>{MaterialState.pressed}), colorScheme.onSurfaceVariant.withOpacity(0.1));
215 expect(m3.rangePickerElevation, 0);
216 expect(m3.rangePickerShape, const RoundedRectangleBorder());
217 expect(m3.rangePickerShadowColor, Colors.transparent);
218 expect(m3.rangePickerSurfaceTintColor, Colors.transparent);
219 expect(m3.rangeSelectionOverlayColor?.resolve(<MaterialState>{}), null);
220 expect(m3.rangePickerHeaderBackgroundColor, Colors.transparent);
221 expect(m3.rangePickerHeaderForegroundColor, colorScheme.onSurfaceVariant);
222 expect(m3.rangePickerHeaderHeadlineStyle, textTheme.titleLarge);
223 expect(m3.rangePickerHeaderHelpStyle, textTheme.titleSmall);
224 expect(m3.dividerColor, null);
225 expect(m3.inputDecorationTheme, null);
226 expect(m3.cancelButtonStyle.toString(), equalsIgnoringHashCodes(TextButton.styleFrom().toString()));
227 expect(m3.confirmButtonStyle.toString(), equalsIgnoringHashCodes(TextButton.styleFrom().toString()));
228 expect(m3.locale, null);
229 });
230
231 testWidgets('DatePickerTheme.defaults M2 defaults', (WidgetTester tester) async {
232 late final DatePickerThemeData m2; // M2 defaults
233 late final ThemeData theme;
234 late final ColorScheme colorScheme;
235 late final TextTheme textTheme;
236
237 await tester.pumpWidget(
238 MaterialApp(
239 theme: ThemeData(useMaterial3: false),
240 home: Builder(
241 builder: (BuildContext context) {
242 m2 = DatePickerTheme.defaults(context);
243 theme = Theme.of(context);
244 colorScheme = theme.colorScheme;
245 textTheme = theme.textTheme;
246 return Container();
247 },
248 ),
249 ),
250 );
251
252 expect(m2.elevation, 24);
253 expect(m2.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0))));
254 expect(m2.headerBackgroundColor, colorScheme.primary);
255 expect(m2.headerForegroundColor, colorScheme.onPrimary);
256 expect(m2.headerHeadlineStyle, textTheme.headlineSmall);
257 expect(m2.headerHelpStyle, textTheme.labelSmall);
258 expect(m2.weekdayStyle, textTheme.bodySmall?.apply(color: colorScheme.onSurface.withOpacity(0.60)));
259 expect(m2.dayStyle, textTheme.bodySmall);
260 expect(m2.dayForegroundColor?.resolve(<MaterialState>{}), colorScheme.onSurface);
261 expect(m2.dayForegroundColor?.resolve(<MaterialState>{MaterialState.selected}), colorScheme.onPrimary);
262 expect(m2.dayForegroundColor?.resolve(<MaterialState>{MaterialState.disabled}), colorScheme.onSurface.withOpacity(0.38));
263 expect(m2.dayBackgroundColor?.resolve(<MaterialState>{}), null);
264 expect(m2.dayBackgroundColor?.resolve(<MaterialState>{MaterialState.selected}), colorScheme.primary);
265 expect(m2.dayOverlayColor?.resolve(<MaterialState>{}), null);
266 expect(m2.dayOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.hovered}), colorScheme.onPrimary.withOpacity(0.08));
267 expect(m2.dayOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.focused}), colorScheme.onPrimary.withOpacity(0.12));
268 expect(m2.dayOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.pressed}), colorScheme.onPrimary.withOpacity(0.38));
269 expect(m2.dayOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.hovered, MaterialState.focused}), colorScheme.onPrimary.withOpacity(0.08));
270 expect(m2.dayOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.hovered, MaterialState.pressed}), colorScheme.onPrimary.withOpacity(0.38));
271 expect(m2.dayOverlayColor?.resolve(<MaterialState>{MaterialState.hovered}), colorScheme.onSurfaceVariant.withOpacity(0.08));
272 expect(m2.dayOverlayColor?.resolve(<MaterialState>{MaterialState.focused}), colorScheme.onSurfaceVariant.withOpacity(0.12));
273 expect(m2.dayOverlayColor?.resolve(<MaterialState>{MaterialState.pressed}), colorScheme.onSurfaceVariant.withOpacity(0.12));
274 expect(m2.dayShape?.resolve(<MaterialState>{}), const CircleBorder());
275 expect(m2.todayForegroundColor?.resolve(<MaterialState>{}), colorScheme.primary);
276 expect(m2.todayForegroundColor?.resolve(<MaterialState>{MaterialState.disabled}), colorScheme.onSurface.withOpacity(0.38));
277 expect(m2.todayBorder, BorderSide(color: colorScheme.primary));
278 expect(m2.yearStyle, textTheme.bodyLarge);
279 expect(m2.rangePickerBackgroundColor, colorScheme.surface);
280 expect(m2.rangePickerElevation, 0);
281 expect(m2.rangePickerShape, const RoundedRectangleBorder());
282 expect(m2.rangePickerShadowColor, Colors.transparent);
283 expect(m2.rangePickerSurfaceTintColor, Colors.transparent);
284 expect(m2.rangeSelectionOverlayColor?.resolve(<MaterialState>{}), null);
285 expect(m2.rangeSelectionOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.hovered}), colorScheme.onPrimary.withOpacity(0.08));
286 expect(m2.rangeSelectionOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.focused}), colorScheme.onPrimary.withOpacity(0.12));
287 expect(m2.rangeSelectionOverlayColor?.resolve(<MaterialState>{MaterialState.selected, MaterialState.pressed}), colorScheme.onPrimary.withOpacity(0.38));
288 expect(m2.rangeSelectionOverlayColor?.resolve(<MaterialState>{MaterialState.hovered}), colorScheme.onSurfaceVariant.withOpacity(0.08));
289 expect(m2.rangeSelectionOverlayColor?.resolve(<MaterialState>{MaterialState.focused}), colorScheme.onSurfaceVariant.withOpacity(0.12));
290 expect(m2.rangeSelectionOverlayColor?.resolve(<MaterialState>{MaterialState.pressed}), colorScheme.onSurfaceVariant.withOpacity(0.12));
291 expect(m2.rangePickerHeaderBackgroundColor, colorScheme.primary);
292 expect(m2.rangePickerHeaderForegroundColor, colorScheme.onPrimary);
293 expect(m2.rangePickerHeaderHeadlineStyle, textTheme.headlineSmall);
294 expect(m2.rangePickerHeaderHelpStyle, textTheme.labelSmall);
295 expect(m2.dividerColor, null);
296 expect(m2.inputDecorationTheme, null);
297 expect(m2.cancelButtonStyle.toString(), equalsIgnoringHashCodes(TextButton.styleFrom().toString()));
298 expect(m2.confirmButtonStyle.toString(), equalsIgnoringHashCodes(TextButton.styleFrom().toString()));
299 expect(m2.locale, null);
300 });
301
302 testWidgets('Default DatePickerThemeData debugFillProperties', (WidgetTester tester) async {
303 final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
304 const DatePickerThemeData().debugFillProperties(builder);
305
306 final List<String> description = builder.properties
307 .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
308 .map((DiagnosticsNode node) => node.toString())
309 .toList();
310
311 expect(description, <String>[]);
312 });
313
314 testWidgets('DatePickerThemeData implements debugFillProperties', (WidgetTester tester) async {
315 final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
316
317 datePickerTheme.debugFillProperties(builder);
318
319 final List<String> description = builder.properties
320 .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
321 .map((DiagnosticsNode node) => node.toString())
322 .toList();
323
324 expect(description, equalsIgnoringHashCodes(<String>[
325 'backgroundColor: ${const Color(0xfffffff0)}',
326 'elevation: 6.0',
327 'shadowColor: ${const Color(0xfffffff1)}',
328 'surfaceTintColor: ${const Color(0xfffffff2)}',
329 'shape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.zero)',
330 'headerBackgroundColor: ${const Color(0xfffffff3)}',
331 'headerForegroundColor: ${const Color(0xfffffff4)}',
332 'headerHeadlineStyle: TextStyle(inherit: true, size: 10.0)',
333 'headerHelpStyle: TextStyle(inherit: true, size: 11.0)',
334 'weekDayStyle: TextStyle(inherit: true, size: 12.0)',
335 'dayStyle: TextStyle(inherit: true, size: 13.0)',
336 'dayForegroundColor: WidgetStatePropertyAll(${const Color(0xfffffff5)})',
337 'dayBackgroundColor: WidgetStatePropertyAll(${const Color(0xfffffff6)})',
338 'dayOverlayColor: WidgetStatePropertyAll(${const Color(0xfffffff7)})',
339 'dayShape: WidgetStatePropertyAll(RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.zero))',
340 'todayForegroundColor: WidgetStatePropertyAll(${const Color(0xfffffff8)})',
341 'todayBackgroundColor: WidgetStatePropertyAll(${const Color(0xfffffff9)})',
342 'todayBorder: BorderSide(width: 3.0)',
343 'yearStyle: TextStyle(inherit: true, size: 13.0)',
344 'yearForegroundColor: WidgetStatePropertyAll(${const Color(0xfffffffa)})',
345 'yearBackgroundColor: WidgetStatePropertyAll(${const Color(0xfffffffb)})',
346 'yearOverlayColor: WidgetStatePropertyAll(${const Color(0xfffffffc)})',
347 'rangePickerBackgroundColor: ${const Color(0xfffffffd)}',
348 'rangePickerElevation: 7.0',
349 'rangePickerShadowColor: ${const Color(0xfffffffe)}',
350 'rangePickerSurfaceTintColor: ${const Color(0xffffffff)}',
351 'rangePickerShape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.zero)',
352 'rangePickerHeaderBackgroundColor: ${const Color(0xffffff0f)}',
353 'rangePickerHeaderForegroundColor: ${const Color(0xffffff1f)}',
354 'rangePickerHeaderHeadlineStyle: TextStyle(inherit: true, size: 14.0)',
355 'rangePickerHeaderHelpStyle: TextStyle(inherit: true, size: 15.0)',
356 'rangeSelectionBackgroundColor: ${const Color(0xffffff2f)}',
357 'rangeSelectionOverlayColor: WidgetStatePropertyAll(${const Color(0xffffff3f)})',
358 'dividerColor: ${const Color(0xffffff4f)}',
359 'inputDecorationTheme: InputDecorationTheme#00000(fillColor: ${const Color(0xffffff5f)}, border: UnderlineInputBorder())',
360 'cancelButtonStyle: ButtonStyle#00000(foregroundColor: WidgetStatePropertyAll(${const Color(0xffffff6f)}))',
361 'confirmButtonStyle: ButtonStyle#00000(foregroundColor: WidgetStatePropertyAll(${const Color(0xffffff7f)}))',
362 'locale: en',
363 ]));
364 });
365
366 testWidgets('DatePickerDialog uses ThemeData datePicker theme (calendar mode)', (WidgetTester tester) async {
367 await tester.pumpWidget(
368 MaterialApp(
369 theme: ThemeData(
370 datePickerTheme: datePickerTheme,
371 useMaterial3: true,
372 ),
373 home: Directionality(
374 textDirection: TextDirection.ltr,
375 child: Material(
376 child: Center(
377 child: DatePickerDialog(
378 initialDate: DateTime(2023, DateTime.january, 25),
379 firstDate: DateTime(2022),
380 lastDate: DateTime(2024, DateTime.december, 31),
381 currentDate: DateTime(2023, DateTime.january, 24),
382 ),
383 ),
384 ),
385 ),
386 ),
387 );
388
389 final Material material = findDialogMaterial(tester);
390 expect(material.color, datePickerTheme.backgroundColor);
391 expect(material.elevation, datePickerTheme.elevation);
392 expect(material.shadowColor, datePickerTheme.shadowColor);
393 expect(material.surfaceTintColor, datePickerTheme.surfaceTintColor);
394 expect(material.shape, datePickerTheme.shape);
395
396 final Text selectDate = tester.widget<Text>(find.text('Select date'));
397 final Material headerMaterial = findHeaderMaterial(tester, 'Select date');
398 expect(selectDate.style?.color, datePickerTheme.headerForegroundColor);
399 expect(selectDate.style?.fontSize, datePickerTheme.headerHelpStyle?.fontSize);
400 expect(headerMaterial.color, datePickerTheme.headerBackgroundColor);
401
402 final Text weekday = tester.widget<Text>(find.text('W'));
403 expect(weekday.style?.color, datePickerTheme.weekdayStyle?.color);
404 expect(weekday.style?.fontSize, datePickerTheme.weekdayStyle?.fontSize);
405
406 final Text selectedDate = tester.widget<Text>(find.text('Wed, Jan 25'));
407 expect(selectedDate.style?.color, datePickerTheme.headerForegroundColor);
408 expect(selectedDate.style?.fontSize, datePickerTheme.headerHeadlineStyle?.fontSize);
409
410 final Text day31 = tester.widget<Text>(find.text('31'));
411 final ShapeDecoration day31Decoration = findDayDecoration(tester, '31')!;
412 expect(day31.style?.color, datePickerTheme.dayForegroundColor?.resolve(<MaterialState>{}));
413 expect(day31.style?.fontSize, datePickerTheme.dayStyle?.fontSize);
414 expect(day31Decoration.color, datePickerTheme.dayBackgroundColor?.resolve(<MaterialState>{}));
415 expect(day31Decoration.shape, datePickerTheme.dayShape?.resolve(<MaterialState>{}));
416
417 final Text day24 = tester.widget<Text>(find.text('24')); // DatePickerDialog.currentDate
418 final ShapeDecoration day24Decoration = findDayDecoration(tester, '24')!;
419 final OutlinedBorder day24Shape = day24Decoration.shape as OutlinedBorder;
420 expect(day24.style?.fontSize, datePickerTheme.dayStyle?.fontSize);
421 expect(day24.style?.color, datePickerTheme.todayForegroundColor?.resolve(<MaterialState>{}));
422 expect(day24Decoration.color, datePickerTheme.todayBackgroundColor?.resolve(<MaterialState>{}));
423 expect(
424 day24Decoration.shape,
425 datePickerTheme.dayShape?.resolve(<MaterialState>{})!
426 .copyWith(side: datePickerTheme.todayBorder?.copyWith(color: datePickerTheme.todayForegroundColor?.resolve(<MaterialState>{}))),
427 );
428 expect(day24Shape.side.width, datePickerTheme.todayBorder?.width);
429
430 // Test the day overlay color.
431 final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
432 final TestGesture gesture = await tester.createGesture(
433 kind: PointerDeviceKind.mouse,
434 );
435 await gesture.addPointer();
436 await gesture.moveTo(tester.getCenter(find.text('25')));
437 await tester.pumpAndSettle();
438 expect(inkFeatures, paints..circle(color: datePickerTheme.dayOverlayColor?.resolve(<MaterialState>{})));
439
440 // Show the year selector.
441
442 await tester.tap(find.text('January 2023'));
443 await tester.pumpAndSettle();
444
445 final Text year2022 = tester.widget<Text>(find.text('2022'));
446 final BoxDecoration year2022Decoration = findTextDecoration(tester, '2022')!;
447 expect(year2022.style?.fontSize, datePickerTheme.yearStyle?.fontSize);
448 expect(year2022.style?.color, datePickerTheme.yearForegroundColor?.resolve(<MaterialState>{}));
449 expect(year2022Decoration.color, datePickerTheme.yearBackgroundColor?.resolve(<MaterialState>{}));
450
451 final Text year2023 = tester.widget<Text>(find.text('2023')); // DatePickerDialog.currentDate
452 final BoxDecoration year2023Decoration = findTextDecoration(tester, '2023')!;
453 expect(year2023.style?.fontSize, datePickerTheme.yearStyle?.fontSize);
454 expect(year2023.style?.color, datePickerTheme.todayForegroundColor?.resolve(<MaterialState>{}));
455 expect(year2023Decoration.color, datePickerTheme.todayBackgroundColor?.resolve(<MaterialState>{}));
456 expect(year2023Decoration.border?.top.width, datePickerTheme.todayBorder?.width);
457 expect(year2023Decoration.border?.bottom.width, datePickerTheme.todayBorder?.width);
458 expect(year2023Decoration.border?.top.color, datePickerTheme.todayForegroundColor?.resolve(<MaterialState>{}));
459 expect(year2023Decoration.border?.bottom.color, datePickerTheme.todayForegroundColor?.resolve(<MaterialState>{}));
460
461 // Test the year overlay color.
462 await gesture.moveTo(tester.getCenter(find.text('2024')));
463 await tester.pumpAndSettle();
464 expect(inkFeatures, paints..rect(color: datePickerTheme.yearOverlayColor?.resolve(<MaterialState>{})));
465
466 final ButtonStyle cancelButtonStyle = actionButtonStyle(tester, 'Cancel');
467 expect(cancelButtonStyle.toString(), equalsIgnoringHashCodes(datePickerTheme.cancelButtonStyle.toString()));
468
469 final ButtonStyle confirmButtonStyle = actionButtonStyle(tester, 'OK');
470 expect(confirmButtonStyle.toString(), equalsIgnoringHashCodes(datePickerTheme.confirmButtonStyle.toString()));
471 });
472
473 testWidgets('DatePickerDialog uses ThemeData datePicker theme (input mode)', (WidgetTester tester) async {
474 await tester.pumpWidget(
475 MaterialApp(
476 theme: ThemeData(
477 datePickerTheme: datePickerTheme,
478 useMaterial3: true,
479 ),
480 home: Directionality(
481 textDirection: TextDirection.ltr,
482 child: Material(
483 child: Center(
484 child: DatePickerDialog(
485 initialEntryMode: DatePickerEntryMode.input,
486 initialDate: DateTime(2023, DateTime.january, 25),
487 firstDate: DateTime(2022),
488 lastDate: DateTime(2024, DateTime.december, 31),
489 currentDate: DateTime(2023, DateTime.january, 24),
490 ),
491 ),
492 ),
493 ),
494 ),
495 );
496
497 final Material material = findDialogMaterial(tester);
498 expect(material.color, datePickerTheme.backgroundColor);
499 expect(material.elevation, datePickerTheme.elevation);
500 expect(material.shadowColor, datePickerTheme.shadowColor);
501 expect(material.surfaceTintColor, datePickerTheme.surfaceTintColor);
502 expect(material.shape, datePickerTheme.shape);
503
504 final Text selectDate = tester.widget<Text>(find.text('Select date'));
505 final Material headerMaterial = findHeaderMaterial(tester, 'Select date');
506 expect(selectDate.style?.color, datePickerTheme.headerForegroundColor);
507 expect(selectDate.style?.fontSize, datePickerTheme.headerHelpStyle?.fontSize);
508 expect(headerMaterial.color, datePickerTheme.headerBackgroundColor);
509
510 final InputDecoration inputDecoration = tester.widget<TextField>(find.byType(TextField)).decoration!;
511 expect(inputDecoration.fillColor, datePickerTheme.inputDecorationTheme?.fillColor);
512
513 final ButtonStyle cancelButtonStyle = actionButtonStyle(tester, 'Cancel');
514 expect(cancelButtonStyle.toString(), equalsIgnoringHashCodes(datePickerTheme.cancelButtonStyle.toString()));
515
516 final ButtonStyle confirmButtonStyle = actionButtonStyle(tester, 'OK');
517 expect(confirmButtonStyle.toString(), equalsIgnoringHashCodes(datePickerTheme.confirmButtonStyle.toString()));
518 });
519
520 testWidgets('DateRangePickerDialog uses ThemeData datePicker theme', (WidgetTester tester) async {
521 await tester.pumpWidget(
522 MaterialApp(
523 theme: ThemeData(
524 datePickerTheme: datePickerTheme,
525 useMaterial3: true,
526 ),
527 home: Directionality(
528 textDirection: TextDirection.ltr,
529 child: Material(
530 child: Center(
531 child: DateRangePickerDialog(
532 firstDate: DateTime(2023),
533 lastDate: DateTime(2023, DateTime.january, 31),
534 initialDateRange: DateTimeRange(
535 start: DateTime(2023, DateTime.january, 17),
536 end: DateTime(2023, DateTime.january, 20),
537 ),
538 currentDate: DateTime(2023, DateTime.january, 23),
539 ),
540 ),
541 ),
542 ),
543 ),
544 );
545
546 final Material material = findDialogMaterial(tester);
547 expect(material.color, datePickerTheme.backgroundColor);
548 expect(tester.widget<Scaffold>(find.byType(Scaffold)).backgroundColor, datePickerTheme.rangePickerBackgroundColor);
549 expect(material.elevation, datePickerTheme.rangePickerElevation);
550 expect(material.shadowColor, datePickerTheme.rangePickerShadowColor);
551 expect(material.surfaceTintColor, datePickerTheme.rangePickerSurfaceTintColor);
552 expect(material.shape, datePickerTheme.rangePickerShape);
553
554 final AppBar appBar = tester.widget<AppBar>(find.byType(AppBar));
555 expect(appBar.backgroundColor, datePickerTheme.rangePickerHeaderBackgroundColor);
556
557 final Text selectRange = tester.widget<Text>(find.text('Select range'));
558 expect(selectRange.style?.color, datePickerTheme.rangePickerHeaderForegroundColor);
559 expect(selectRange.style?.fontSize, datePickerTheme.rangePickerHeaderHelpStyle?.fontSize);
560
561 final Text selectedDate = tester.widget<Text>(find.text('Jan 17'));
562 expect(selectedDate.style?.color, datePickerTheme.rangePickerHeaderForegroundColor);
563 expect(selectedDate.style?.fontSize, datePickerTheme.rangePickerHeaderHeadlineStyle?.fontSize);
564
565 // Test the day overlay color.
566 final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
567 final TestGesture gesture = await tester.createGesture(
568 kind: PointerDeviceKind.mouse,
569 );
570 await gesture.addPointer();
571 await gesture.moveTo(tester.getCenter(find.text('16')));
572 await tester.pumpAndSettle();
573 expect(inkFeatures, paints..circle(color: datePickerTheme.dayOverlayColor?.resolve(<MaterialState>{})));
574
575 // Test the range selection overlay color.
576 await gesture.moveTo(tester.getCenter(find.text('18')));
577 await tester.pumpAndSettle();
578 expect(inkFeatures, paints..circle(color: datePickerTheme.rangeSelectionOverlayColor?.resolve(<MaterialState>{})));
579 });
580
581 testWidgets('Material2 - DateRangePickerDialog uses ThemeData datePicker theme', (WidgetTester tester) async {
582 await tester.pumpWidget(
583 MaterialApp(
584 theme: ThemeData(
585 datePickerTheme: datePickerTheme,
586 useMaterial3: false,
587 ),
588 home: Directionality(
589 textDirection: TextDirection.ltr,
590 child: Material(
591 child: Center(
592 child: DateRangePickerDialog(
593 firstDate: DateTime(2023),
594 lastDate: DateTime(2023, DateTime.january, 31),
595 initialDateRange: DateTimeRange(
596 start: DateTime(2023, DateTime.january, 17),
597 end: DateTime(2023, DateTime.january, 20),
598 ),
599 currentDate: DateTime(2023, DateTime.january, 23),
600 ),
601 ),
602 ),
603 ),
604 ),
605 );
606
607 final Material material = findDialogMaterial(tester);
608 expect(material.color, datePickerTheme.backgroundColor);
609 expect(tester.widget<Scaffold>(find.byType(Scaffold)).backgroundColor, datePickerTheme.rangePickerBackgroundColor);
610 expect(material.elevation, datePickerTheme.rangePickerElevation);
611 expect(material.shadowColor, datePickerTheme.rangePickerShadowColor);
612 expect(material.surfaceTintColor, datePickerTheme.rangePickerSurfaceTintColor);
613 expect(material.shape, datePickerTheme.rangePickerShape);
614
615 final AppBar appBar = tester.widget<AppBar>(find.byType(AppBar));
616 expect(appBar.backgroundColor, datePickerTheme.rangePickerHeaderBackgroundColor);
617
618 final Text selectRange = tester.widget<Text>(find.text('SELECT RANGE'));
619 expect(selectRange.style?.color, datePickerTheme.rangePickerHeaderForegroundColor);
620 expect(selectRange.style?.fontSize, datePickerTheme.rangePickerHeaderHelpStyle?.fontSize);
621
622 final Text selectedDate = tester.widget<Text>(find.text('Jan 17'));
623 expect(selectedDate.style?.color, datePickerTheme.rangePickerHeaderForegroundColor);
624 expect(selectedDate.style?.fontSize, datePickerTheme.rangePickerHeaderHeadlineStyle?.fontSize);
625
626 // Test the day overlay color.
627 final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
628 final TestGesture gesture = await tester.createGesture(
629 kind: PointerDeviceKind.mouse,
630 );
631 await gesture.addPointer();
632 await gesture.moveTo(tester.getCenter(find.text('16')));
633 await tester.pumpAndSettle();
634 expect(inkFeatures, paints..circle(color: datePickerTheme.dayOverlayColor?.resolve(<MaterialState>{})));
635
636 // Test the range selection overlay color.
637 await gesture.moveTo(tester.getCenter(find.text('18')));
638 await tester.pumpAndSettle();
639 expect(inkFeatures, paints..circle(color: datePickerTheme.rangeSelectionOverlayColor?.resolve(<MaterialState>{})));
640 });
641
642 testWidgets('Dividers use DatePickerThemeData.dividerColor', (WidgetTester tester) async {
643 Future<void> showPicker(WidgetTester tester, Size size) async {
644 tester.view.physicalSize = size;
645 tester.view.devicePixelRatio = 1.0;
646 addTearDown(tester.view.reset);
647 await tester.pumpWidget(
648 MaterialApp(
649 theme: ThemeData(
650 datePickerTheme: datePickerTheme,
651 useMaterial3: true,
652 ),
653 home: Directionality(
654 textDirection: TextDirection.ltr,
655 child: Material(
656 child: Center(
657 child: DatePickerDialog(
658 initialDate: DateTime(2023, DateTime.january, 25),
659 firstDate: DateTime(2022),
660 lastDate: DateTime(2024, DateTime.december, 31),
661 currentDate: DateTime(2023, DateTime.january, 24),
662 ),
663 ),
664 ),
665 ),
666 ),
667 );
668 }
669 await showPicker(tester, wideWindowSize);
670
671 // Test vertical divider.
672 final VerticalDivider verticalDivider = tester.widget(find.byType(VerticalDivider));
673 expect(verticalDivider.color, datePickerTheme.dividerColor);
674
675 // Test portrait layout.
676 await showPicker(tester, narrowWindowSize);
677
678 // Test horizontal divider.
679 final Divider horizontalDivider = tester.widget(find.byType(Divider));
680 expect(horizontalDivider.color, datePickerTheme.dividerColor);
681 });
682
683 testWidgets(
684 'DatePicker uses ThemeData.inputDecorationTheme properties '
685 'which are null in DatePickerThemeData.inputDecorationTheme',
686 (WidgetTester tester) async {
687
688 Widget buildWidget({
689 InputDecorationTheme? inputDecorationTheme,
690 DatePickerThemeData? datePickerTheme,
691 }) {
692 return MaterialApp(
693 theme: ThemeData(
694 useMaterial3: true,
695 inputDecorationTheme: inputDecorationTheme,
696 datePickerTheme: datePickerTheme,
697 ),
698 home: Directionality(
699 textDirection: TextDirection.ltr,
700 child: Material(
701 child: Center(
702 child: DatePickerDialog(
703 initialEntryMode: DatePickerEntryMode.input,
704 initialDate: DateTime(2023, DateTime.january, 25),
705 firstDate: DateTime(2022),
706 lastDate: DateTime(2024, DateTime.december, 31),
707 currentDate: DateTime(2023, DateTime.january, 24),
708 ),
709 ),
710 ),
711 ),
712 );
713 }
714
715 // Test DatePicker with DatePickerThemeData.inputDecorationTheme.
716 await tester.pumpWidget(buildWidget(
717 inputDecorationTheme: const InputDecorationTheme(filled: true),
718 datePickerTheme: datePickerTheme,
719 ));
720 InputDecoration inputDecoration = tester.widget<TextField>(find.byType(TextField)).decoration!;
721 expect(inputDecoration.fillColor, datePickerTheme.inputDecorationTheme!.fillColor);
722 expect(inputDecoration.border , datePickerTheme.inputDecorationTheme!.border);
723
724 // Test DatePicker with ThemeData.inputDecorationTheme.
725 await tester.pumpWidget(buildWidget(
726 inputDecorationTheme: const InputDecorationTheme(
727 filled: true,
728 fillColor: Color(0xFF00FF00),
729 border: OutlineInputBorder(),
730 ),
731 ));
732 await tester.pumpAndSettle();
733
734 inputDecoration = tester.widget<TextField>(find.byType(TextField)).decoration!;
735 expect(inputDecoration.fillColor, const Color(0xFF00FF00));
736 expect(inputDecoration.border , const OutlineInputBorder());
737 });
738
739 testWidgets('DatePickerDialog resolves DatePickerTheme.dayOverlayColor states', (WidgetTester tester) async {
740 final MaterialStateProperty<Color> dayOverlayColor = MaterialStateProperty.resolveWith<Color>((Set<MaterialState> states) {
741 if (states.contains(MaterialState.hovered)) {
742 return const Color(0xff00ff00);
743 }
744 if (states.contains(MaterialState.focused)) {
745 return const Color(0xffff00ff);
746 }
747 if (states.contains(MaterialState.pressed)) {
748 return const Color(0xffffff00);
749 }
750 return Colors.transparent;
751 });
752
753 await tester.pumpWidget(
754 MaterialApp(
755 theme: ThemeData(
756 datePickerTheme: DatePickerThemeData(
757 dayOverlayColor: dayOverlayColor,
758 ),
759 useMaterial3: true,
760 ),
761 home: Directionality(
762 textDirection: TextDirection.ltr,
763 child: Material(
764 child: Center(
765 child: Focus(
766 child: DatePickerDialog(
767 initialDate: DateTime(2023, DateTime.january, 25),
768 firstDate: DateTime(2022),
769 lastDate: DateTime(2024, DateTime.december, 31),
770 currentDate: DateTime(2023, DateTime.january, 24),
771 ),
772 ),
773 ),
774 ),
775 ),
776 ),
777 );
778
779 // Test the hover overlay color.
780 final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
781 final TestGesture gesture = await tester.createGesture(
782 kind: PointerDeviceKind.mouse,
783 );
784 await gesture.addPointer();
785 await gesture.moveTo(tester.getCenter(find.text('20')));
786 await tester.pumpAndSettle();
787 expect(
788 inkFeatures,
789 paints
790 ..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.hovered})),
791 );
792
793 // Test the pressed overlay color.
794 await gesture.down(tester.getCenter(find.text('20')));
795 await tester.pumpAndSettle();
796 if (kIsWeb) {
797 // An extra circle is painted on the web for the hovered state.
798 expect(
799 inkFeatures,
800 paints
801 ..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
802 ..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
803 ..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.pressed})),
804 );
805 } else {
806 expect(
807 inkFeatures,
808 paints
809 ..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
810 ..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.pressed})),
811 );
812 }
813
814 await gesture.removePointer();
815 await tester.pumpAndSettle();
816
817 // Focus day selection.
818 for (int i = 0; i < 5; i++) {
819 await tester.sendKeyEvent(LogicalKeyboardKey.tab);
820 await tester.pumpAndSettle();
821 }
822
823 // Test the focused overlay color.
824 expect(
825 inkFeatures,
826 paints
827 ..circle(color: dayOverlayColor.resolve(<MaterialState>{MaterialState.focused})),
828 );
829 });
830
831 testWidgets('DatePickerDialog resolves DatePickerTheme.yearOverlayColor states', (WidgetTester tester) async {
832 final MaterialStateProperty<Color> yearOverlayColor = MaterialStateProperty.resolveWith<Color>((Set<MaterialState> states) {
833 if (states.contains(MaterialState.hovered)) {
834 return const Color(0xff00ff00);
835 }
836 if (states.contains(MaterialState.focused)) {
837 return const Color(0xffff00ff);
838 }
839 if (states.contains(MaterialState.pressed)) {
840 return const Color(0xffffff00);
841 }
842 return Colors.transparent;
843 });
844
845 await tester.pumpWidget(
846 MaterialApp(
847 theme: ThemeData(
848 datePickerTheme: DatePickerThemeData(
849 yearOverlayColor: yearOverlayColor,
850 ),
851 useMaterial3: true,
852 ),
853 home: Directionality(
854 textDirection: TextDirection.ltr,
855 child: Material(
856 child: Center(
857 child: Focus(
858 child: DatePickerDialog(
859 initialDate: DateTime(2023, DateTime.january, 25),
860 firstDate: DateTime(2022),
861 lastDate: DateTime(2024, DateTime.december, 31),
862 currentDate: DateTime(2023, DateTime.january, 24),
863 initialCalendarMode: DatePickerMode.year,
864 ),
865 ),
866 ),
867 ),
868 ),
869 ),
870 );
871
872 // Test the hover overlay color.
873 final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
874 final TestGesture gesture = await tester.createGesture(
875 kind: PointerDeviceKind.mouse,
876 );
877 await gesture.addPointer();
878 await gesture.moveTo(tester.getCenter(find.text('2022')));
879 await tester.pumpAndSettle();
880 expect(
881 inkFeatures,
882 paints
883 ..rect(color: yearOverlayColor.resolve(<MaterialState>{MaterialState.hovered})),
884 );
885
886 // Test the pressed overlay color.
887 await gesture.down(tester.getCenter(find.text('2022')));
888 await tester.pumpAndSettle();
889 expect(
890 inkFeatures,
891 paints
892 ..rect(color: yearOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
893 ..rect(color: yearOverlayColor.resolve(<MaterialState>{MaterialState.pressed})),
894 );
895
896 await gesture.removePointer();
897 await tester.pumpAndSettle();
898
899 // Focus year selection.
900 for (int i = 0; i < 3; i++) {
901 await tester.sendKeyEvent(LogicalKeyboardKey.tab);
902 await tester.pumpAndSettle();
903 }
904
905 // Test the focused overlay color.
906 expect(
907 inkFeatures,
908 paints
909 ..rect(color: yearOverlayColor.resolve(<MaterialState>{MaterialState.focused})),
910 );
911 });
912
913 testWidgets('DateRangePickerDialog resolves DatePickerTheme.rangeSelectionOverlayColor states', (WidgetTester tester) async {
914 final MaterialStateProperty<Color> rangeSelectionOverlayColor = MaterialStateProperty.resolveWith<Color>((Set<MaterialState> states) {
915 if (states.contains(MaterialState.hovered)) {
916 return const Color(0xff00ff00);
917 }
918 if (states.contains(MaterialState.pressed)) {
919 return const Color(0xffffff00);
920 }
921 return Colors.transparent;
922 });
923
924 await tester.pumpWidget(
925 MaterialApp(
926 theme: ThemeData(
927 datePickerTheme: DatePickerThemeData(
928 rangeSelectionOverlayColor: rangeSelectionOverlayColor,
929 ),
930 useMaterial3: true,
931 ),
932 home: Directionality(
933 textDirection: TextDirection.ltr,
934 child: Material(
935 child: Center(
936 child: DateRangePickerDialog(
937 firstDate: DateTime(2023),
938 lastDate: DateTime(2023, DateTime.january, 31),
939 initialDateRange: DateTimeRange(
940 start: DateTime(2023, DateTime.january, 17),
941 end: DateTime(2023, DateTime.january, 20),
942 ),
943 currentDate: DateTime(2023, DateTime.january, 23),
944 ),
945 ),
946 ),
947 ),
948 ),
949 );
950
951 // Test the hover overlay color.
952 final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
953 final TestGesture gesture = await tester.createGesture(
954 kind: PointerDeviceKind.mouse,
955 );
956 await gesture.addPointer();
957 await gesture.moveTo(tester.getCenter(find.text('18')));
958 await tester.pumpAndSettle();
959 expect(
960 inkFeatures,
961 paints
962 ..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.hovered})),
963 );
964
965 // Test the pressed overlay color.
966 await gesture.down(tester.getCenter(find.text('18')));
967 await tester.pumpAndSettle();
968 if (kIsWeb) {
969 // An extra circle is painted on the web for the hovered state.
970 expect(
971 inkFeatures,
972 paints
973 ..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
974 ..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
975 ..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.pressed})),
976 );
977 } else {
978 expect(
979 inkFeatures,
980 paints
981 ..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.hovered}))
982 ..circle(color: rangeSelectionOverlayColor.resolve(<MaterialState>{MaterialState.pressed})),
983 );
984 }
985 });
986}
987

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com