Unverified Commit 32fe4d7f authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Add `DatePickerTheme.inputDecorationTheme` for the DatePicker with input mode. (#128950)

parent 9c963572
......@@ -9,6 +9,7 @@ import 'package:flutter/widgets.dart';
import 'color_scheme.dart';
import 'colors.dart';
import 'input_decorator.dart';
import 'material_state.dart';
import 'text_theme.dart';
import 'theme.dart';
......@@ -68,6 +69,7 @@ class DatePickerThemeData with Diagnosticable {
this.rangeSelectionBackgroundColor,
this.rangeSelectionOverlayColor,
this.dividerColor,
this.inputDecorationTheme,
});
/// Overrides the default value of [Dialog.backgroundColor].
......@@ -288,6 +290,10 @@ class DatePickerThemeData with Diagnosticable {
/// and vertical divider when the dialog is in landscape orientation.
final Color? dividerColor;
/// Overrides the [InputDatePickerFormField]'s input decoration theme.
/// If this is null, [ThemeData.inputDecorationTheme] is used instead.
final InputDecorationTheme? inputDecorationTheme;
/// Creates a copy of this object with the given fields replaced with the
/// new values.
DatePickerThemeData copyWith({
......@@ -324,6 +330,7 @@ class DatePickerThemeData with Diagnosticable {
Color? rangeSelectionBackgroundColor,
MaterialStateProperty<Color?>? rangeSelectionOverlayColor,
Color? dividerColor,
InputDecorationTheme? inputDecorationTheme,
}) {
return DatePickerThemeData(
backgroundColor: backgroundColor ?? this.backgroundColor,
......@@ -359,6 +366,7 @@ class DatePickerThemeData with Diagnosticable {
rangeSelectionBackgroundColor: rangeSelectionBackgroundColor ?? this.rangeSelectionBackgroundColor,
rangeSelectionOverlayColor: rangeSelectionOverlayColor ?? this.rangeSelectionOverlayColor,
dividerColor: dividerColor ?? this.dividerColor,
inputDecorationTheme: inputDecorationTheme ?? this.inputDecorationTheme,
);
}
......@@ -401,6 +409,7 @@ class DatePickerThemeData with Diagnosticable {
rangeSelectionBackgroundColor: Color.lerp(a?.rangeSelectionBackgroundColor, b?.rangeSelectionBackgroundColor, t),
rangeSelectionOverlayColor: MaterialStateProperty.lerp<Color?>(a?.rangeSelectionOverlayColor, b?.rangeSelectionOverlayColor, t, Color.lerp),
dividerColor: Color.lerp(a?.dividerColor, b?.dividerColor, t),
inputDecorationTheme: t < 0.5 ? a?.inputDecorationTheme : b?.inputDecorationTheme,
);
}
......@@ -449,6 +458,7 @@ class DatePickerThemeData with Diagnosticable {
rangeSelectionBackgroundColor,
rangeSelectionOverlayColor,
dividerColor,
inputDecorationTheme,
]);
@override
......@@ -489,7 +499,8 @@ class DatePickerThemeData with Diagnosticable {
&& other.rangePickerHeaderHelpStyle == rangePickerHeaderHelpStyle
&& other.rangeSelectionBackgroundColor == rangeSelectionBackgroundColor
&& other.rangeSelectionOverlayColor == rangeSelectionOverlayColor
&& other.dividerColor == dividerColor;
&& other.dividerColor == dividerColor
&& other.inputDecorationTheme == inputDecorationTheme;
}
@override
......@@ -528,6 +539,7 @@ class DatePickerThemeData with Diagnosticable {
properties.add(ColorProperty('rangeSelectionBackgroundColor', rangeSelectionBackgroundColor, defaultValue: null));
properties.add(DiagnosticsProperty<MaterialStateProperty<Color?>>('rangeSelectionOverlayColor', rangeSelectionOverlayColor, defaultValue: null));
properties.add(ColorProperty('dividerColor', dividerColor, defaultValue: null));
properties.add(DiagnosticsProperty<InputDecorationTheme>('inputDecorationTheme', inputDecorationTheme, defaultValue: null));
}
}
......
......@@ -5,6 +5,7 @@
import 'package:flutter/widgets.dart';
import 'date.dart';
import 'date_picker_theme.dart';
import 'input_border.dart';
import 'input_decorator.dart';
import 'material_localizations.dart';
......@@ -248,16 +249,19 @@ class _InputDatePickerFormFieldState extends State<InputDatePickerFormField> {
final ThemeData theme = Theme.of(context);
final bool useMaterial3 = theme.useMaterial3;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final DatePickerThemeData datePickerTheme = theme.datePickerTheme;
final InputDecorationTheme inputTheme = theme.inputDecorationTheme;
final InputBorder inputBorder = inputTheme.border
final InputBorder effectiveInputBorder = datePickerTheme.inputDecorationTheme?.border
?? theme.inputDecorationTheme.border
?? (useMaterial3 ? const OutlineInputBorder() : const UnderlineInputBorder());
return TextFormField(
decoration: InputDecoration(
border: inputBorder,
filled: inputTheme.filled,
hintText: widget.fieldHintText ?? localizations.dateHelpText,
labelText: widget.fieldLabelText ?? localizations.dateInputLabel,
).applyDefaults(inputTheme
.merge(datePickerTheme.inputDecorationTheme)
.copyWith(border: effectiveInputBorder),
),
validator: _validateDate,
keyboardType: widget.keyboardType ?? TextInputType.datetime,
......
......@@ -40,7 +40,11 @@ void main() {
rangePickerHeaderHelpStyle: TextStyle(fontSize: 15),
rangeSelectionBackgroundColor: Color(0xffffff2f),
rangeSelectionOverlayColor: MaterialStatePropertyAll<Color>(Color(0xffffff3f)),
dividerColor: Color(0xffffff3f),
dividerColor: Color(0xffffff4f),
inputDecorationTheme: InputDecorationTheme(
fillColor: Color(0xffffff5f),
border: UnderlineInputBorder(),
)
);
Material findDialogMaterial(WidgetTester tester) {
......@@ -119,6 +123,7 @@ void main() {
expect(theme.rangeSelectionBackgroundColor, null);
expect(theme.rangeSelectionOverlayColor, null);
expect(theme.dividerColor, null);
expect(theme.inputDecorationTheme, null);
});
testWidgets('DatePickerTheme.defaults M3 defaults', (WidgetTester tester) async {
......@@ -129,7 +134,7 @@ void main() {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(useMaterial3: true),
theme: ThemeData(useMaterial3: true),
home: Builder(
builder: (BuildContext context) {
m3 = DatePickerTheme.defaults(context);
......@@ -193,6 +198,7 @@ void main() {
expect(m3.rangePickerHeaderHeadlineStyle, textTheme.titleLarge);
expect(m3.rangePickerHeaderHelpStyle, textTheme.titleSmall);
expect(m3.dividerColor, null);
expect(m3.inputDecorationTheme, null);
});
testWidgets('DatePickerTheme.defaults M2 defaults', (WidgetTester tester) async {
......@@ -203,7 +209,7 @@ void main() {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(useMaterial3: false),
theme: ThemeData(useMaterial3: false),
home: Builder(
builder: (BuildContext context) {
m2 = DatePickerTheme.defaults(context);
......@@ -258,6 +264,8 @@ void main() {
expect(m2.rangePickerHeaderForegroundColor, colorScheme.onPrimary);
expect(m2.rangePickerHeaderHeadlineStyle, textTheme.headlineSmall);
expect(m2.rangePickerHeaderHelpStyle, textTheme.labelSmall);
expect(m2.dividerColor, null);
expect(m2.inputDecorationTheme, null);
});
testWidgets('Default DatePickerThemeData debugFillProperties', (WidgetTester tester) async {
......@@ -282,7 +290,9 @@ void main() {
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, <String>[
expect(
description,
equalsIgnoringHashCodes(<String>[
'backgroundColor: Color(0xfffffff0)',
'elevation: 6.0',
'shadowColor: Color(0xfffffff1)',
......@@ -315,15 +325,18 @@ void main() {
'rangePickerHeaderHelpStyle: TextStyle(inherit: true, size: 15.0)',
'rangeSelectionBackgroundColor: Color(0xffffff2f)',
'rangeSelectionOverlayColor: MaterialStatePropertyAll(Color(0xffffff3f))',
'dividerColor: Color(0xffffff3f)',
]);
'dividerColor: Color(0xffffff4f)',
'inputDecorationTheme: InputDecorationTheme#00000(fillColor: Color(0xffffff5f), border: UnderlineInputBorder())'
]),
);
});
testWidgets('DatePickerDialog uses ThemeData datePicker theme', (WidgetTester tester) async {
testWidgets('DatePickerDialog uses ThemeData datePicker theme (calendar mode)', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(useMaterial3: true).copyWith(
theme: ThemeData(
datePickerTheme: datePickerTheme,
useMaterial3: true,
),
home: Directionality(
textDirection: TextDirection.ltr,
......@@ -398,11 +411,53 @@ void main() {
expect(year2023Decoration.border?.bottom.color, datePickerTheme.todayForegroundColor?.resolve(<MaterialState>{}));
});
testWidgets('DatePickerDialog uses ThemeData datePicker theme (input mode)', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
datePickerTheme: datePickerTheme,
useMaterial3: true,
),
home: Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: DatePickerDialog(
initialEntryMode: DatePickerEntryMode.input,
initialDate: DateTime(2023, DateTime.january, 25),
firstDate: DateTime(2022),
lastDate: DateTime(2024, DateTime.december, 31),
currentDate: DateTime(2023, DateTime.january, 24),
),
),
),
),
),
);
final Material material = findDialogMaterial(tester);
expect(material.color, datePickerTheme.backgroundColor);
expect(material.elevation, datePickerTheme.elevation);
expect(material.shadowColor, datePickerTheme.shadowColor);
expect(material.surfaceTintColor, datePickerTheme.surfaceTintColor);
expect(material.shape, datePickerTheme.shape);
final Text selectDate = tester.widget<Text>(find.text('Select date'));
final Material headerMaterial = findHeaderMaterial(tester, 'Select date');
expect(selectDate.style?.color, datePickerTheme.headerForegroundColor);
expect(selectDate.style?.fontSize, datePickerTheme.headerHelpStyle?.fontSize);
expect(headerMaterial.color, datePickerTheme.headerBackgroundColor);
final InputDecoration inputDecoration = tester.widget<TextField>(find.byType(TextField)).decoration!;
expect(inputDecoration.fillColor, datePickerTheme.inputDecorationTheme?.fillColor);
});
testWidgets('DateRangePickerDialog uses ThemeData datePicker theme', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(useMaterial3: true).copyWith(
theme: ThemeData(
datePickerTheme: datePickerTheme,
useMaterial3: true,
),
home: Directionality(
textDirection: TextDirection.ltr,
......@@ -450,8 +505,9 @@ void main() {
addTearDown(tester.view.reset);
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(useMaterial3: true).copyWith(
theme: ThemeData(
datePickerTheme: datePickerTheme,
useMaterial3: true,
),
home: Directionality(
textDirection: TextDirection.ltr,
......@@ -482,4 +538,60 @@ void main() {
final Divider horizontalDivider = tester.widget(find.byType(Divider));
expect(horizontalDivider.color, datePickerTheme.dividerColor);
});
testWidgets(
'DatePicker uses ThemeData.inputDecorationTheme properties '
'which are null in DatePickerThemeData.inputDecorationTheme',
(WidgetTester tester) async {
Widget buildWidget({
InputDecorationTheme? inputDecorationTheme,
DatePickerThemeData? datePickerTheme,
}) {
return MaterialApp(
theme: ThemeData(
useMaterial3: true,
inputDecorationTheme: inputDecorationTheme,
datePickerTheme: datePickerTheme,
),
home: Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: DatePickerDialog(
initialEntryMode: DatePickerEntryMode.input,
initialDate: DateTime(2023, DateTime.january, 25),
firstDate: DateTime(2022),
lastDate: DateTime(2024, DateTime.december, 31),
currentDate: DateTime(2023, DateTime.january, 24),
),
),
),
),
);
}
// Test DatePicker with DatePickerThemeData.inputDecorationTheme.
await tester.pumpWidget(buildWidget(
inputDecorationTheme: const InputDecorationTheme(filled: true),
datePickerTheme: datePickerTheme,
));
InputDecoration inputDecoration = tester.widget<TextField>(find.byType(TextField)).decoration!;
expect(inputDecoration.fillColor, datePickerTheme.inputDecorationTheme!.fillColor);
expect(inputDecoration.border , datePickerTheme.inputDecorationTheme!.border);
// Test DatePicker with ThemeData.inputDecorationTheme.
await tester.pumpWidget(buildWidget(
inputDecorationTheme: const InputDecorationTheme(
filled: true,
fillColor: Color(0xFF00FF00),
border: OutlineInputBorder(),
),
));
await tester.pumpAndSettle();
inputDecoration = tester.widget<TextField>(find.byType(TextField)).decoration!;
expect(inputDecoration.fillColor, const Color(0xFF00FF00));
expect(inputDecoration.border , const OutlineInputBorder());
});
}
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