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 | |
5 | import 'package:flutter/foundation.dart'; |
6 | import 'package:flutter/gestures.dart'; |
7 | import 'package:flutter/material.dart'; |
8 | import 'package:flutter/services.dart'; |
9 | import 'package:flutter_test/flutter_test.dart'; |
10 | |
11 | void 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 | |