Skip to content

Commit 4d7792e

Browse files
HansMullerexaby73
authored andcommitted
M3 DatePicker landscape header text style is now TextTheme.headlineSmall (flutter#123732)
M3 DatePicker landscape header text style is now TextTheme.headlineSmall
1 parent 8792606 commit 4d7792e

File tree

3 files changed

+94
-18
lines changed

3 files changed

+94
-18
lines changed

packages/flutter/lib/src/material/date_picker.dart

+34-18
Original file line numberDiff line numberDiff line change
@@ -477,21 +477,28 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
477477
final DatePickerThemeData defaults = DatePickerTheme.defaults(context);
478478
final TextTheme textTheme = theme.textTheme;
479479

480-
// Constrain the textScaleFactor to the largest supported value to prevent
481-
// layout issues.
482-
final double textScaleFactor = math.min(MediaQuery.textScaleFactorOf(context), 1.3);
480+
// There's no M3 spec for a landscape layout input (not calendar)
481+
// date picker. To ensure that the date displayed in the input
482+
// date picker's header fits in landscape mode, we override the M3
483+
// default here.
484+
TextStyle? headlineStyle;
485+
if (useMaterial3) {
486+
headlineStyle = datePickerTheme.headerHeadlineStyle ?? defaults.headerHeadlineStyle;
487+
switch (_entryMode.value) {
488+
case DatePickerEntryMode.input:
489+
case DatePickerEntryMode.inputOnly:
490+
if (orientation == Orientation.landscape) {
491+
headlineStyle = textTheme.headlineSmall;
492+
}
493+
case DatePickerEntryMode.calendar:
494+
case DatePickerEntryMode.calendarOnly:
495+
// M3 default is OK.
496+
}
497+
} else {
498+
headlineStyle = orientation == Orientation.landscape ? textTheme.headlineSmall : textTheme.headlineMedium;
499+
}
483500
final Color? headerForegroundColor = datePickerTheme.headerForegroundColor ?? defaults.headerForegroundColor;
484-
final TextStyle? headlineStyle = useMaterial3
485-
? (datePickerTheme.headerHeadlineStyle ?? defaults.headerHeadlineStyle)?.copyWith(
486-
color: headerForegroundColor,
487-
)
488-
// Material2 has support for landscape and the current M3 spec doesn't
489-
// address this layout, so handling it separately here.
490-
: (orientation == Orientation.landscape
491-
? textTheme.headlineSmall?.copyWith(color: headerForegroundColor)
492-
: textTheme.headlineMedium?.copyWith(color: headerForegroundColor));
493-
494-
final String dateText = localizations.formatMediumDate(_selectedDate.value);
501+
headlineStyle = headlineStyle?.copyWith(color: headerForegroundColor);
495502

496503
final Widget actions = Container(
497504
alignment: AlignmentDirectional.centerEnd,
@@ -599,13 +606,16 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
599606
? localizations.datePickerHelpText
600607
: localizations.datePickerHelpText.toUpperCase()
601608
),
602-
titleText: dateText,
609+
titleText: localizations.formatMediumDate(_selectedDate.value),
603610
titleStyle: headlineStyle,
604611
orientation: orientation,
605612
isShort: orientation == Orientation.landscape,
606613
entryModeButton: entryModeButton,
607614
);
608615

616+
// Constrain the textScaleFactor to the largest supported value to prevent
617+
// layout issues.
618+
final double textScaleFactor = math.min(MediaQuery.textScaleFactorOf(context), 1.3);
609619
final Size dialogSize = _dialogSize(context) * textScaleFactor;
610620
final DialogTheme dialogTheme = theme.dialogTheme;
611621
return Dialog(
@@ -2660,10 +2670,16 @@ class _InputDateRangePickerDialog extends StatelessWidget {
26602670
final DatePickerThemeData datePickerTheme = DatePickerTheme.of(context);
26612671
final DatePickerThemeData defaults = DatePickerTheme.defaults(context);
26622672

2673+
// There's no M3 spec for a landscape layout input (not calendar)
2674+
// date range picker. To ensure that the date range displayed in the
2675+
// input date range picker's header fits in landscape mode, we override
2676+
// the M3 default here.
2677+
TextStyle? headlineStyle = (orientation == Orientation.portrait)
2678+
? datePickerTheme.headerHeadlineStyle ?? defaults.headerHeadlineStyle
2679+
: Theme.of(context).textTheme.headlineSmall;
2680+
26632681
final Color? headerForegroundColor = datePickerTheme.headerForegroundColor ?? defaults.headerForegroundColor;
2664-
final TextStyle? headlineStyle = (datePickerTheme.headerHeadlineStyle ?? defaults.headerHeadlineStyle)?.copyWith(
2665-
color: headerForegroundColor,
2666-
);
2682+
headlineStyle = headlineStyle?.copyWith(color: headerForegroundColor);
26672683

26682684
final String dateText = _formatDateRange(context, selectedStartDate, selectedEndDate, currentDate!);
26692685
final String semanticDateText = selectedStartDate != null && selectedEndDate != null

packages/flutter/test/material/date_picker_test.dart

+30
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,36 @@ void main() {
13871387
expect(find.byType(TextField), findsNothing);
13881388
});
13891389
});
1390+
1391+
group('Landscape input-only date picker headers use headlineSmall', () {
1392+
// Regression test for https://github.com/flutter/flutter/issues/122056
1393+
1394+
// Common screen size roughly based on a Pixel 1
1395+
const Size kCommonScreenSizePortrait = Size(1070, 1770);
1396+
const Size kCommonScreenSizeLandscape = Size(1770, 1070);
1397+
1398+
Future<void> showPicker(WidgetTester tester, Size size) async {
1399+
addTearDown(tester.view.reset);
1400+
tester.view.physicalSize = size;
1401+
tester.view.devicePixelRatio = 1.0;
1402+
initialEntryMode = DatePickerEntryMode.input;
1403+
await prepareDatePicker(tester, (Future<DateTime?> date) async { }, useMaterial3: true);
1404+
}
1405+
1406+
testWidgets('portrait', (WidgetTester tester) async {
1407+
await showPicker(tester, kCommonScreenSizePortrait);
1408+
expect(tester.widget<Text>(find.text('Fri, Jan 15')).style?.fontSize, 32);
1409+
await tester.tap(find.text('Cancel'));
1410+
await tester.pumpAndSettle();
1411+
});
1412+
1413+
testWidgets('landscape', (WidgetTester tester) async {
1414+
await showPicker(tester, kCommonScreenSizeLandscape);
1415+
expect(tester.widget<Text>(find.text('Fri, Jan 15')).style?.fontSize, 24);
1416+
await tester.tap(find.text('Cancel'));
1417+
await tester.pumpAndSettle();
1418+
});
1419+
});
13901420
}
13911421

13921422
class _RestorableDatePickerDialogTestWidget extends StatefulWidget {

packages/flutter/test/material/date_range_picker_test.dart

+30
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,36 @@ void main() {
108108
await callback(range);
109109
}
110110

111+
group('Landscape input-only date picker headers use headlineSmall', () {
112+
// Regression test for https://github.com/flutter/flutter/issues/122056
113+
114+
// Common screen size roughly based on a Pixel 1
115+
const Size kCommonScreenSizePortrait = Size(1070, 1770);
116+
const Size kCommonScreenSizeLandscape = Size(1770, 1070);
117+
118+
Future<void> showPicker(WidgetTester tester, Size size) async {
119+
addTearDown(tester.view.reset);
120+
tester.view.physicalSize = size;
121+
tester.view.devicePixelRatio = 1.0;
122+
initialEntryMode = DatePickerEntryMode.input;
123+
await preparePicker(tester, (Future<DateTimeRange?> range) async { }, useMaterial3: true);
124+
}
125+
126+
testWidgets('portrait', (WidgetTester tester) async {
127+
await showPicker(tester, kCommonScreenSizePortrait);
128+
expect(tester.widget<Text>(find.text('Jan 15 – Jan 25, 2016')).style?.fontSize, 32);
129+
await tester.tap(find.text('Cancel'));
130+
await tester.pumpAndSettle();
131+
});
132+
133+
testWidgets('landscape', (WidgetTester tester) async {
134+
await showPicker(tester, kCommonScreenSizeLandscape);
135+
expect(tester.widget<Text>(find.text('Jan 15 – Jan 25, 2016')).style?.fontSize, 24);
136+
await tester.tap(find.text('Cancel'));
137+
await tester.pumpAndSettle();
138+
});
139+
});
140+
111141
testWidgets('Save and help text is used', (WidgetTester tester) async {
112142
helpText = 'help';
113143
saveText = 'make it so';

0 commit comments

Comments
 (0)