Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 198a51a

Browse files
authored
Migrate the Material Date pickers to M3 Reprise (#119033)
1 parent 3884381 commit 198a51a

11 files changed

+1934
-158
lines changed

dev/tools/gen_defaults/bin/gen_defaults.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import 'package:gen_defaults/button_template.dart';
2727
import 'package:gen_defaults/card_template.dart';
2828
import 'package:gen_defaults/checkbox_template.dart';
2929
import 'package:gen_defaults/color_scheme_template.dart';
30+
import 'package:gen_defaults/date_picker_template.dart';
3031
import 'package:gen_defaults/dialog_template.dart';
3132
import 'package:gen_defaults/divider_template.dart';
3233
import 'package:gen_defaults/drawer_template.dart';
@@ -147,6 +148,7 @@ Future<void> main(List<String> args) async {
147148
CardTemplate('Card', '$materialLib/card.dart', tokens).updateFile();
148149
CheckboxTemplate('Checkbox', '$materialLib/checkbox.dart', tokens).updateFile();
149150
ColorSchemeTemplate('ColorScheme', '$materialLib/theme_data.dart', tokens).updateFile();
151+
DatePickerTemplate('DatePicker', '$materialLib/date_picker_theme.dart', tokens).updateFile();
150152
DialogFullscreenTemplate('DialogFullscreen', '$materialLib/dialog.dart', tokens).updateFile();
151153
DialogTemplate('Dialog', '$materialLib/dialog.dart', tokens).updateFile();
152154
DividerTemplate('Divider', '$materialLib/divider.dart', tokens).updateFile();
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
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 'template.dart';
6+
7+
class DatePickerTemplate extends TokenTemplate {
8+
const DatePickerTemplate(super.blockName, super.fileName, super.tokens, {
9+
super.colorSchemePrefix = '_colors.',
10+
super.textThemePrefix = '_textTheme.'
11+
});
12+
13+
String _layerOpacity(String layerToken) {
14+
if (tokens.containsKey(layerToken)) {
15+
final String? layerValue = tokens[layerToken] as String?;
16+
if (tokens.containsKey(layerValue)) {
17+
final String? opacityValue = opacity(layerValue!);
18+
if (opacityValue != null) {
19+
return '.withOpacity($opacityValue)';
20+
}
21+
}
22+
}
23+
return '';
24+
}
25+
26+
String _stateColor(String componentToken, String? type, String state) {
27+
final String baseColor = color(
28+
type != null
29+
? '$componentToken.$type.$state.state-layer.color'
30+
: '$componentToken.$state.state-layer.color',
31+
''
32+
);
33+
if (baseColor.isEmpty) {
34+
return 'null';
35+
}
36+
final String opacity = _layerOpacity('$componentToken.$state.state-layer.opacity');
37+
return '$baseColor$opacity';
38+
}
39+
40+
@override
41+
String generate() => '''
42+
class _${blockName}DefaultsM3 extends DatePickerThemeData {
43+
_${blockName}DefaultsM3(this.context)
44+
: super(
45+
elevation: ${elevation("md.comp.date-picker.modal.container")},
46+
shape: ${shape("md.comp.date-picker.modal.container")},
47+
rangePickerElevation: ${elevation("md.comp.date-picker.modal.range-selection.container")},
48+
rangePickerShape: ${shape("md.comp.date-picker.modal.range-selection.container")},
49+
);
50+
51+
final BuildContext context;
52+
late final ThemeData _theme = Theme.of(context);
53+
late final ColorScheme _colors = _theme.colorScheme;
54+
late final TextTheme _textTheme = _theme.textTheme;
55+
56+
@override
57+
Color? get backgroundColor => ${componentColor("md.comp.date-picker.modal.container")};
58+
59+
@override
60+
Color? get shadowColor => ${colorOrTransparent("md.comp.date-picker.modal.container.shadow-color")};
61+
62+
@override
63+
Color? get surfaceTintColor => ${colorOrTransparent("md.comp.date-picker.modal.container.surface-tint-layer.color")};
64+
65+
@override
66+
Color? get headerBackgroundColor => ${colorOrTransparent("md.comp.date-picker.modal.header.container.color")};
67+
68+
@override
69+
Color? get headerForegroundColor => ${colorOrTransparent("md.comp.date-picker.modal.header.headline.color")};
70+
71+
@override
72+
TextStyle? get headerHeadlineStyle => ${textStyle("md.comp.date-picker.modal.header.headline")};
73+
74+
@override
75+
TextStyle? get headerHelpStyle => ${textStyle("md.comp.date-picker.modal.header.supporting-text")};
76+
77+
@override
78+
TextStyle? get weekdayStyle => ${textStyle("md.comp.date-picker.modal.weekdays.label-text")}?.apply(
79+
color: ${componentColor("md.comp.date-picker.modal.weekdays.label-text")},
80+
);
81+
82+
@override
83+
TextStyle? get dayStyle => ${textStyle("md.comp.date-picker.modal.date.label-text")};
84+
85+
@override
86+
MaterialStateProperty<Color?>? get dayForegroundColor =>
87+
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
88+
if (states.contains(MaterialState.selected)) {
89+
return ${componentColor('md.comp.date-picker.modal.date.selected.label-text')};
90+
} else if (states.contains(MaterialState.disabled)) {
91+
return ${componentColor('md.comp.date-picker.modal.date.unselected.label-text')}.withOpacity(0.38);
92+
}
93+
return ${componentColor('md.comp.date-picker.modal.date.unselected.label-text')};
94+
});
95+
96+
@override
97+
MaterialStateProperty<Color?>? get dayBackgroundColor =>
98+
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
99+
if (states.contains(MaterialState.selected)) {
100+
return ${componentColor('md.comp.date-picker.modal.date.selected.container')};
101+
}
102+
return ${componentColor('md.comp.date-picker.modal.date.unselected.container')};
103+
});
104+
105+
@override
106+
MaterialStateProperty<Color?>? get dayOverlayColor =>
107+
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
108+
if (states.contains(MaterialState.selected)) {
109+
if (states.contains(MaterialState.hovered)) {
110+
return ${_stateColor('md.comp.date-picker.modal.date', 'selected', 'hover')};
111+
}
112+
if (states.contains(MaterialState.focused)) {
113+
return ${_stateColor('md.comp.date-picker.modal.date', 'selected', 'focus')};
114+
}
115+
if (states.contains(MaterialState.pressed)) {
116+
return ${_stateColor('md.comp.date-picker.modal.date', 'selected', 'pressed')};
117+
}
118+
} else {
119+
if (states.contains(MaterialState.hovered)) {
120+
return ${_stateColor('md.comp.date-picker.modal.date', 'unselected', 'hover')};
121+
}
122+
if (states.contains(MaterialState.focused)) {
123+
return ${_stateColor('md.comp.date-picker.modal.date', 'unselected', 'focus')};
124+
}
125+
if (states.contains(MaterialState.pressed)) {
126+
return ${_stateColor('md.comp.date-picker.modal.date', 'unselected', 'pressed')};
127+
}
128+
}
129+
return null;
130+
});
131+
132+
@override
133+
MaterialStateProperty<Color?>? get todayForegroundColor =>
134+
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
135+
if (states.contains(MaterialState.selected)) {
136+
return ${componentColor('md.comp.date-picker.modal.date.selected.label-text')};
137+
} else if (states.contains(MaterialState.disabled)) {
138+
return ${componentColor('md.comp.date-picker.modal.date.today.label-text')}.withOpacity(0.38);
139+
}
140+
return ${componentColor('md.comp.date-picker.modal.date.today.label-text')};
141+
});
142+
143+
@override
144+
MaterialStateProperty<Color?>? get todayBackgroundColor => dayBackgroundColor;
145+
146+
@override
147+
BorderSide? get todayBorder => ${border('md.comp.date-picker.modal.date.today.container.outline')};
148+
149+
@override
150+
TextStyle? get yearStyle => ${textStyle("md.comp.date-picker.modal.year-selection.year.label-text")};
151+
152+
@override
153+
MaterialStateProperty<Color?>? get yearForegroundColor =>
154+
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
155+
if (states.contains(MaterialState.selected)) {
156+
return ${componentColor('md.comp.date-picker.modal.year-selection.year.selected.label-text')};
157+
} else if (states.contains(MaterialState.disabled)) {
158+
return ${componentColor('md.comp.date-picker.modal.year-selection.year.unselected.label-text')}.withOpacity(0.38);
159+
}
160+
return ${componentColor('md.comp.date-picker.modal.year-selection.year.unselected.label-text')};
161+
});
162+
163+
@override
164+
MaterialStateProperty<Color?>? get yearBackgroundColor =>
165+
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
166+
if (states.contains(MaterialState.selected)) {
167+
return ${componentColor('md.comp.date-picker.modal.year-selection.year.selected.container')};
168+
}
169+
return ${componentColor('md.comp.date-picker.modal.year-selection.year.unselected.container')};
170+
});
171+
172+
@override
173+
MaterialStateProperty<Color?>? get yearOverlayColor =>
174+
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
175+
if (states.contains(MaterialState.selected)) {
176+
if (states.contains(MaterialState.hovered)) {
177+
return ${_stateColor('md.comp.date-picker.modal.year-selection.year', 'selected', 'hover')};
178+
}
179+
if (states.contains(MaterialState.focused)) {
180+
return ${_stateColor('md.comp.date-picker.modal.year-selection.year', 'selected', 'focus')};
181+
}
182+
if (states.contains(MaterialState.pressed)) {
183+
return ${_stateColor('md.comp.date-picker.modal.year-selection.year', 'selected', 'pressed')};
184+
}
185+
} else {
186+
if (states.contains(MaterialState.hovered)) {
187+
return ${_stateColor('md.comp.date-picker.modal.year-selection.year', 'unselected', 'hover')};
188+
}
189+
if (states.contains(MaterialState.focused)) {
190+
return ${_stateColor('md.comp.date-picker.modal.year-selection.year', 'unselected', 'focus')};
191+
}
192+
if (states.contains(MaterialState.pressed)) {
193+
return ${_stateColor('md.comp.date-picker.modal.year-selection.year', 'unselected', 'pressed')};
194+
}
195+
}
196+
return null;
197+
});
198+
199+
@override
200+
Color? get rangePickerShadowColor => ${colorOrTransparent("md.comp.date-picker.modal.range-selection.container.shadow-color")};
201+
202+
@override
203+
Color? get rangePickerSurfaceTintColor => ${colorOrTransparent("md.comp.date-picker.modal.range-selection.container.surface-tint-layer.color")};
204+
205+
@override
206+
Color? get rangeSelectionBackgroundColor => ${colorOrTransparent("md.comp.date-picker.modal.range-selection.active-indicator.container.color")};
207+
208+
@override
209+
MaterialStateProperty<Color?>? get rangeSelectionOverlayColor =>
210+
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
211+
if (states.contains(MaterialState.hovered)) {
212+
return ${_stateColor('md.comp.date-picker.modal.range-selection.date.in-range.', null, 'hover')};
213+
}
214+
if (states.contains(MaterialState.focused)) {
215+
return ${_stateColor('md.comp.date-picker.modal.range-selection.date.in-range.', null, 'focus')};
216+
}
217+
if (states.contains(MaterialState.pressed)) {
218+
return ${_stateColor('md.comp.date-picker.modal.range-selection.date.in-range.', null, 'pressed')};
219+
}
220+
return null;
221+
});
222+
223+
@override
224+
Color? get rangePickerHeaderBackgroundColor => ${colorOrTransparent("md.comp.date-picker.modal.header.container.color")};
225+
226+
@override
227+
Color? get rangePickerHeaderForegroundColor => ${colorOrTransparent("md.comp.date-picker.modal.header.headline.color")};
228+
229+
@override
230+
TextStyle? get rangePickerHeaderHeadlineStyle => ${textStyle("md.comp.date-picker.modal.range-selection.header.headline")};
231+
232+
@override
233+
TextStyle? get rangePickerHeaderHelpStyle => ${textStyle("md.comp.date-picker.modal.range-selection.month.subhead")};
234+
235+
236+
}
237+
''';
238+
}

packages/flutter/lib/material.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export 'src/material/data_table_source.dart';
6565
export 'src/material/data_table_theme.dart';
6666
export 'src/material/date.dart';
6767
export 'src/material/date_picker.dart';
68+
export 'src/material/date_picker_theme.dart';
6869
export 'src/material/debug.dart';
6970
export 'src/material/desktop_text_selection.dart';
7071
export 'src/material/desktop_text_selection_toolbar.dart';

0 commit comments

Comments
 (0)