Unverified Commit 0c365bd9 authored by Hans Muller's avatar Hans Muller Committed by GitHub

M3 DatePicker landscape header text style is now TextTheme.headlineSmall (#123732)

M3 DatePicker landscape header text style is now TextTheme.headlineSmall
parent dd7d4b95
...@@ -477,21 +477,28 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix ...@@ -477,21 +477,28 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
final DatePickerThemeData defaults = DatePickerTheme.defaults(context); final DatePickerThemeData defaults = DatePickerTheme.defaults(context);
final TextTheme textTheme = theme.textTheme; final TextTheme textTheme = theme.textTheme;
// Constrain the textScaleFactor to the largest supported value to prevent // There's no M3 spec for a landscape layout input (not calendar)
// layout issues. // date picker. To ensure that the date displayed in the input
final double textScaleFactor = math.min(MediaQuery.textScaleFactorOf(context), 1.3); // date picker's header fits in landscape mode, we override the M3
// default here.
TextStyle? headlineStyle;
if (useMaterial3) {
headlineStyle = datePickerTheme.headerHeadlineStyle ?? defaults.headerHeadlineStyle;
switch (_entryMode.value) {
case DatePickerEntryMode.input:
case DatePickerEntryMode.inputOnly:
if (orientation == Orientation.landscape) {
headlineStyle = textTheme.headlineSmall;
}
case DatePickerEntryMode.calendar:
case DatePickerEntryMode.calendarOnly:
// M3 default is OK.
}
} else {
headlineStyle = orientation == Orientation.landscape ? textTheme.headlineSmall : textTheme.headlineMedium;
}
final Color? headerForegroundColor = datePickerTheme.headerForegroundColor ?? defaults.headerForegroundColor; final Color? headerForegroundColor = datePickerTheme.headerForegroundColor ?? defaults.headerForegroundColor;
final TextStyle? headlineStyle = useMaterial3 headlineStyle = headlineStyle?.copyWith(color: headerForegroundColor);
? (datePickerTheme.headerHeadlineStyle ?? defaults.headerHeadlineStyle)?.copyWith(
color: headerForegroundColor,
)
// Material2 has support for landscape and the current M3 spec doesn't
// address this layout, so handling it separately here.
: (orientation == Orientation.landscape
? textTheme.headlineSmall?.copyWith(color: headerForegroundColor)
: textTheme.headlineMedium?.copyWith(color: headerForegroundColor));
final String dateText = localizations.formatMediumDate(_selectedDate.value);
final Widget actions = Container( final Widget actions = Container(
alignment: AlignmentDirectional.centerEnd, alignment: AlignmentDirectional.centerEnd,
...@@ -599,13 +606,16 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix ...@@ -599,13 +606,16 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
? localizations.datePickerHelpText ? localizations.datePickerHelpText
: localizations.datePickerHelpText.toUpperCase() : localizations.datePickerHelpText.toUpperCase()
), ),
titleText: dateText, titleText: localizations.formatMediumDate(_selectedDate.value),
titleStyle: headlineStyle, titleStyle: headlineStyle,
orientation: orientation, orientation: orientation,
isShort: orientation == Orientation.landscape, isShort: orientation == Orientation.landscape,
entryModeButton: entryModeButton, entryModeButton: entryModeButton,
); );
// Constrain the textScaleFactor to the largest supported value to prevent
// layout issues.
final double textScaleFactor = math.min(MediaQuery.textScaleFactorOf(context), 1.3);
final Size dialogSize = _dialogSize(context) * textScaleFactor; final Size dialogSize = _dialogSize(context) * textScaleFactor;
final DialogTheme dialogTheme = theme.dialogTheme; final DialogTheme dialogTheme = theme.dialogTheme;
return Dialog( return Dialog(
...@@ -2660,10 +2670,16 @@ class _InputDateRangePickerDialog extends StatelessWidget { ...@@ -2660,10 +2670,16 @@ class _InputDateRangePickerDialog extends StatelessWidget {
final DatePickerThemeData datePickerTheme = DatePickerTheme.of(context); final DatePickerThemeData datePickerTheme = DatePickerTheme.of(context);
final DatePickerThemeData defaults = DatePickerTheme.defaults(context); final DatePickerThemeData defaults = DatePickerTheme.defaults(context);
// There's no M3 spec for a landscape layout input (not calendar)
// date range picker. To ensure that the date range displayed in the
// input date range picker's header fits in landscape mode, we override
// the M3 default here.
TextStyle? headlineStyle = (orientation == Orientation.portrait)
? datePickerTheme.headerHeadlineStyle ?? defaults.headerHeadlineStyle
: Theme.of(context).textTheme.headlineSmall;
final Color? headerForegroundColor = datePickerTheme.headerForegroundColor ?? defaults.headerForegroundColor; final Color? headerForegroundColor = datePickerTheme.headerForegroundColor ?? defaults.headerForegroundColor;
final TextStyle? headlineStyle = (datePickerTheme.headerHeadlineStyle ?? defaults.headerHeadlineStyle)?.copyWith( headlineStyle = headlineStyle?.copyWith(color: headerForegroundColor);
color: headerForegroundColor,
);
final String dateText = _formatDateRange(context, selectedStartDate, selectedEndDate, currentDate!); final String dateText = _formatDateRange(context, selectedStartDate, selectedEndDate, currentDate!);
final String semanticDateText = selectedStartDate != null && selectedEndDate != null final String semanticDateText = selectedStartDate != null && selectedEndDate != null
......
...@@ -1387,6 +1387,36 @@ void main() { ...@@ -1387,6 +1387,36 @@ void main() {
expect(find.byType(TextField), findsNothing); expect(find.byType(TextField), findsNothing);
}); });
}); });
group('Landscape input-only date picker headers use headlineSmall', () {
// Regression test for https://github.com/flutter/flutter/issues/122056
// Common screen size roughly based on a Pixel 1
const Size kCommonScreenSizePortrait = Size(1070, 1770);
const Size kCommonScreenSizeLandscape = Size(1770, 1070);
Future<void> showPicker(WidgetTester tester, Size size) async {
addTearDown(tester.view.reset);
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1.0;
initialEntryMode = DatePickerEntryMode.input;
await prepareDatePicker(tester, (Future<DateTime?> date) async { }, useMaterial3: true);
}
testWidgets('portrait', (WidgetTester tester) async {
await showPicker(tester, kCommonScreenSizePortrait);
expect(tester.widget<Text>(find.text('Fri, Jan 15')).style?.fontSize, 32);
await tester.tap(find.text('Cancel'));
await tester.pumpAndSettle();
});
testWidgets('landscape', (WidgetTester tester) async {
await showPicker(tester, kCommonScreenSizeLandscape);
expect(tester.widget<Text>(find.text('Fri, Jan 15')).style?.fontSize, 24);
await tester.tap(find.text('Cancel'));
await tester.pumpAndSettle();
});
});
} }
class _RestorableDatePickerDialogTestWidget extends StatefulWidget { class _RestorableDatePickerDialogTestWidget extends StatefulWidget {
......
...@@ -108,6 +108,36 @@ void main() { ...@@ -108,6 +108,36 @@ void main() {
await callback(range); await callback(range);
} }
group('Landscape input-only date picker headers use headlineSmall', () {
// Regression test for https://github.com/flutter/flutter/issues/122056
// Common screen size roughly based on a Pixel 1
const Size kCommonScreenSizePortrait = Size(1070, 1770);
const Size kCommonScreenSizeLandscape = Size(1770, 1070);
Future<void> showPicker(WidgetTester tester, Size size) async {
addTearDown(tester.view.reset);
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1.0;
initialEntryMode = DatePickerEntryMode.input;
await preparePicker(tester, (Future<DateTimeRange?> range) async { }, useMaterial3: true);
}
testWidgets('portrait', (WidgetTester tester) async {
await showPicker(tester, kCommonScreenSizePortrait);
expect(tester.widget<Text>(find.text('Jan 15 – Jan 25, 2016')).style?.fontSize, 32);
await tester.tap(find.text('Cancel'));
await tester.pumpAndSettle();
});
testWidgets('landscape', (WidgetTester tester) async {
await showPicker(tester, kCommonScreenSizeLandscape);
expect(tester.widget<Text>(find.text('Jan 15 – Jan 25, 2016')).style?.fontSize, 24);
await tester.tap(find.text('Cancel'));
await tester.pumpAndSettle();
});
});
testWidgets('Save and help text is used', (WidgetTester tester) async { testWidgets('Save and help text is used', (WidgetTester tester) async {
helpText = 'help'; helpText = 'help';
saveText = 'make it so'; saveText = 'make it so';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment