Unverified Commit 95cdebed authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Add `timeSelectorSeparatorColor` and `timeSelectorSeparatorTextStyle` for...

Add `timeSelectorSeparatorColor` and `timeSelectorSeparatorTextStyle`  for Material 3 Time Picker (#143739)

fixes [`Time selector separator` in TimePicker is not centered vertically](https://github.com/flutter/flutter/issues/143691)

Separator currently `hourMinuteTextStyle` to style itself.

This introduces `timeSelectorSeparatorColor` and `timeSelectorSeparatorTextStyle` from Material 3 specs to correctly style  the separator. This also adds ability to change separator color without changing `hourMinuteTextColor`.

### Specs for the time selector separator
https://m3.material.io/components/time-pickers/specs
![image](https://github.com/flutter/flutter/assets/48603081/0c84f649-545d-441b-adbf-2b9ec872b14c)

### Code sample

<details>
<summary>expand to view the code sample</summary> 

```dart
import 'package:flutter/material.dart';

void main() {
  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        // timePickerTheme: TimePickerThemeData(
        //   hourMinuteTextColor: Colors.amber,
        // )
      ),
      home: Scaffold(
        body: Center(
          child: Builder(builder: (context) {
            return ElevatedButton(
              onPressed: () async {
                await showTimePicker(
                  context: context,
                  initialTime: TimeOfDay.now(),
                );
              },
              child: const Text('Pick Time'),
            );
          }),
        ),
      ),
    );
  }
}

```

</details>

| Before | After |
| --------------- | --------------- |
| <img src="https://github.com/flutter/flutter/assets/48603081/20beeba4-5cc2-49ee-bba8-1c552c0d1e44" /> | <img src="https://github.com/flutter/flutter/assets/48603081/24927187-aff7-4191-930c-bceab6a4b4c2" /> |
parent f9233756
...@@ -333,6 +333,20 @@ class _${blockName}DefaultsM3 extends _TimePickerDefaults { ...@@ -333,6 +333,20 @@ class _${blockName}DefaultsM3 extends _TimePickerDefaults {
ShapeBorder get shape { ShapeBorder get shape {
return ${shape("$tokenGroup.container")}; return ${shape("$tokenGroup.container")};
} }
@override
MaterialStateProperty<Color?>? get timeSelectorSeparatorColor {
// TODO(tahatesser): Update this when tokens are available.
// This is taken from https://m3.material.io/components/time-pickers/specs.
return MaterialStatePropertyAll<Color>(_colors.onSurface);
}
@override
MaterialStateProperty<TextStyle?>? get timeSelectorSeparatorTextStyle {
// TODO(tahatesser): Update this when tokens are available.
// This is taken from https://m3.material.io/components/time-pickers/specs.
return MaterialStatePropertyAll<TextStyle?>(_textTheme.displayLarge);
}
} }
'''; ''';
} }
...@@ -242,7 +242,7 @@ class _TimePickerHeader extends StatelessWidget { ...@@ -242,7 +242,7 @@ class _TimePickerHeader extends StatelessWidget {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
const Expanded(child: _HourControl()), const Expanded(child: _HourControl()),
_StringFragment(timeOfDayFormat: timeOfDayFormat), _TimeSelectorSeparator(timeOfDayFormat: timeOfDayFormat),
const Expanded(child: _MinuteControl()), const Expanded(child: _MinuteControl()),
], ],
), ),
...@@ -278,7 +278,7 @@ class _TimePickerHeader extends StatelessWidget { ...@@ -278,7 +278,7 @@ class _TimePickerHeader extends StatelessWidget {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
const Expanded(child: _HourControl()), const Expanded(child: _HourControl()),
_StringFragment(timeOfDayFormat: timeOfDayFormat), _TimeSelectorSeparator(timeOfDayFormat: timeOfDayFormat),
const Expanded(child: _MinuteControl()), const Expanded(child: _MinuteControl()),
], ],
), ),
...@@ -428,12 +428,12 @@ class _HourControl extends StatelessWidget { ...@@ -428,12 +428,12 @@ class _HourControl extends StatelessWidget {
/// A passive fragment showing a string value. /// A passive fragment showing a string value.
/// ///
/// Used to display the appropriate separator between the input fields. /// Used to display the appropriate separator between the input fields.
class _StringFragment extends StatelessWidget { class _TimeSelectorSeparator extends StatelessWidget {
const _StringFragment({ required this.timeOfDayFormat }); const _TimeSelectorSeparator({ required this.timeOfDayFormat });
final TimeOfDayFormat timeOfDayFormat; final TimeOfDayFormat timeOfDayFormat;
String _stringFragmentValue(TimeOfDayFormat timeOfDayFormat) { String _timeSelectorSeparatorValue(TimeOfDayFormat timeOfDayFormat) {
switch (timeOfDayFormat) { switch (timeOfDayFormat) {
case TimeOfDayFormat.h_colon_mm_space_a: case TimeOfDayFormat.h_colon_mm_space_a:
case TimeOfDayFormat.a_space_h_colon_mm: case TimeOfDayFormat.a_space_h_colon_mm:
...@@ -455,11 +455,17 @@ class _StringFragment extends StatelessWidget { ...@@ -455,11 +455,17 @@ class _StringFragment extends StatelessWidget {
final Set<MaterialState> states = <MaterialState>{}; final Set<MaterialState> states = <MaterialState>{};
final Color effectiveTextColor = MaterialStateProperty.resolveAs<Color>( final Color effectiveTextColor = MaterialStateProperty.resolveAs<Color>(
timePickerTheme.hourMinuteTextColor ?? defaultTheme.hourMinuteTextColor, timePickerTheme.timeSelectorSeparatorColor?.resolve(states)
?? timePickerTheme.hourMinuteTextColor
?? defaultTheme.timeSelectorSeparatorColor?.resolve(states)
?? defaultTheme.hourMinuteTextColor,
states, states,
); );
final TextStyle effectiveStyle = MaterialStateProperty.resolveAs<TextStyle>( final TextStyle effectiveStyle = MaterialStateProperty.resolveAs<TextStyle>(
timePickerTheme.hourMinuteTextStyle ?? defaultTheme.hourMinuteTextStyle, timePickerTheme.timeSelectorSeparatorTextStyle?.resolve(states)
?? timePickerTheme.hourMinuteTextStyle
?? defaultTheme.timeSelectorSeparatorTextStyle?.resolve(states)
?? defaultTheme.hourMinuteTextStyle,
states, states,
).copyWith(color: effectiveTextColor); ).copyWith(color: effectiveTextColor);
...@@ -478,7 +484,7 @@ class _StringFragment extends StatelessWidget { ...@@ -478,7 +484,7 @@ class _StringFragment extends StatelessWidget {
width: timeOfDayFormat == TimeOfDayFormat.frenchCanadian ? 36 : 24, width: timeOfDayFormat == TimeOfDayFormat.frenchCanadian ? 36 : 24,
height: height, height: height,
child: Text( child: Text(
_stringFragmentValue(timeOfDayFormat), _timeSelectorSeparatorValue(timeOfDayFormat),
style: effectiveStyle, style: effectiveStyle,
textScaler: TextScaler.noScaling, textScaler: TextScaler.noScaling,
textAlign: TextAlign.center, textAlign: TextAlign.center,
...@@ -1801,7 +1807,7 @@ class _TimePickerInputState extends State<_TimePickerInput> with RestorationMixi ...@@ -1801,7 +1807,7 @@ class _TimePickerInputState extends State<_TimePickerInput> with RestorationMixi
], ],
), ),
), ),
_StringFragment(timeOfDayFormat: timeOfDayFormat), _TimeSelectorSeparator(timeOfDayFormat: timeOfDayFormat),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
...@@ -3655,6 +3661,20 @@ class _TimePickerDefaultsM3 extends _TimePickerDefaults { ...@@ -3655,6 +3661,20 @@ class _TimePickerDefaultsM3 extends _TimePickerDefaults {
ShapeBorder get shape { ShapeBorder get shape {
return const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(28.0))); return const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(28.0)));
} }
@override
MaterialStateProperty<Color?>? get timeSelectorSeparatorColor {
// TODO(tahatesser): Update this when tokens are available.
// This is taken from https://m3.material.io/components/time-pickers/specs.
return MaterialStatePropertyAll<Color>(_colors.onSurface);
}
@override
MaterialStateProperty<TextStyle?>? get timeSelectorSeparatorTextStyle {
// TODO(tahatesser): Update this when tokens are available.
// This is taken from https://m3.material.io/components/time-pickers/specs.
return MaterialStatePropertyAll<TextStyle?>(_textTheme.displayLarge);
}
} }
// END GENERATED TOKEN PROPERTIES - TimePicker // END GENERATED TOKEN PROPERTIES - TimePicker
...@@ -62,6 +62,8 @@ class TimePickerThemeData with Diagnosticable { ...@@ -62,6 +62,8 @@ class TimePickerThemeData with Diagnosticable {
this.inputDecorationTheme, this.inputDecorationTheme,
this.padding, this.padding,
this.shape, this.shape,
this.timeSelectorSeparatorColor,
this.timeSelectorSeparatorTextStyle,
}) : _dayPeriodColor = dayPeriodColor; }) : _dayPeriodColor = dayPeriodColor;
/// The background color of a time picker. /// The background color of a time picker.
...@@ -261,6 +263,25 @@ class TimePickerThemeData with Diagnosticable { ...@@ -261,6 +263,25 @@ class TimePickerThemeData with Diagnosticable {
/// `RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)))`. /// `RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)))`.
final ShapeBorder? shape; final ShapeBorder? shape;
/// The color of the time selector seperator between the hour and minute controls.
///
/// if this is null, the time picker defaults to the overall theme's
/// [ColorScheme.onSurface].
///
/// If this is null and [ThemeData.useMaterial3] is false, then defaults to the value of
/// [hourMinuteTextColor].
final MaterialStateProperty<Color?>? timeSelectorSeparatorColor;
/// Used to configure the text style for the time selector seperator between the hour
/// and minute controls.
///
/// If this is null, the time picker defaults to the overall theme's
/// [TextTheme.displayLarge].
///
/// If this is null and [ThemeData.useMaterial3] is false, then defaults to the value of
/// [hourMinuteTextStyle].
final MaterialStateProperty<TextStyle?>? timeSelectorSeparatorTextStyle;
/// Creates a copy of this object with the given fields replaced with the /// Creates a copy of this object with the given fields replaced with the
/// new values. /// new values.
TimePickerThemeData copyWith({ TimePickerThemeData copyWith({
...@@ -287,6 +308,8 @@ class TimePickerThemeData with Diagnosticable { ...@@ -287,6 +308,8 @@ class TimePickerThemeData with Diagnosticable {
InputDecorationTheme? inputDecorationTheme, InputDecorationTheme? inputDecorationTheme,
EdgeInsetsGeometry? padding, EdgeInsetsGeometry? padding,
ShapeBorder? shape, ShapeBorder? shape,
MaterialStateProperty<Color?>? timeSelectorSeparatorColor,
MaterialStateProperty<TextStyle?>? timeSelectorSeparatorTextStyle,
}) { }) {
return TimePickerThemeData( return TimePickerThemeData(
backgroundColor: backgroundColor ?? this.backgroundColor, backgroundColor: backgroundColor ?? this.backgroundColor,
...@@ -311,6 +334,8 @@ class TimePickerThemeData with Diagnosticable { ...@@ -311,6 +334,8 @@ class TimePickerThemeData with Diagnosticable {
inputDecorationTheme: inputDecorationTheme ?? this.inputDecorationTheme, inputDecorationTheme: inputDecorationTheme ?? this.inputDecorationTheme,
padding: padding ?? this.padding, padding: padding ?? this.padding,
shape: shape ?? this.shape, shape: shape ?? this.shape,
timeSelectorSeparatorColor: timeSelectorSeparatorColor ?? this.timeSelectorSeparatorColor,
timeSelectorSeparatorTextStyle: timeSelectorSeparatorTextStyle ?? this.timeSelectorSeparatorTextStyle,
); );
} }
...@@ -355,6 +380,8 @@ class TimePickerThemeData with Diagnosticable { ...@@ -355,6 +380,8 @@ class TimePickerThemeData with Diagnosticable {
inputDecorationTheme: t < 0.5 ? a?.inputDecorationTheme : b?.inputDecorationTheme, inputDecorationTheme: t < 0.5 ? a?.inputDecorationTheme : b?.inputDecorationTheme,
padding: EdgeInsetsGeometry.lerp(a?.padding, b?.padding, t), padding: EdgeInsetsGeometry.lerp(a?.padding, b?.padding, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t), shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
timeSelectorSeparatorColor: MaterialStateProperty.lerp<Color?>(a?.timeSelectorSeparatorColor, b?.timeSelectorSeparatorColor, t, Color.lerp),
timeSelectorSeparatorTextStyle: MaterialStateProperty.lerp<TextStyle?>(a?.timeSelectorSeparatorTextStyle, b?.timeSelectorSeparatorTextStyle, t, TextStyle.lerp),
); );
} }
...@@ -382,6 +409,8 @@ class TimePickerThemeData with Diagnosticable { ...@@ -382,6 +409,8 @@ class TimePickerThemeData with Diagnosticable {
inputDecorationTheme, inputDecorationTheme,
padding, padding,
shape, shape,
timeSelectorSeparatorColor,
timeSelectorSeparatorTextStyle,
]); ]);
@override @override
...@@ -414,7 +443,9 @@ class TimePickerThemeData with Diagnosticable { ...@@ -414,7 +443,9 @@ class TimePickerThemeData with Diagnosticable {
&& other.hourMinuteTextStyle == hourMinuteTextStyle && other.hourMinuteTextStyle == hourMinuteTextStyle
&& other.inputDecorationTheme == inputDecorationTheme && other.inputDecorationTheme == inputDecorationTheme
&& other.padding == padding && other.padding == padding
&& other.shape == shape; && other.shape == shape
&& other.timeSelectorSeparatorColor == timeSelectorSeparatorColor
&& other.timeSelectorSeparatorTextStyle == timeSelectorSeparatorTextStyle;
} }
@override @override
...@@ -442,6 +473,8 @@ class TimePickerThemeData with Diagnosticable { ...@@ -442,6 +473,8 @@ class TimePickerThemeData with Diagnosticable {
properties.add(DiagnosticsProperty<InputDecorationTheme>('inputDecorationTheme', inputDecorationTheme, defaultValue: null)); properties.add(DiagnosticsProperty<InputDecorationTheme>('inputDecorationTheme', inputDecorationTheme, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null)); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null)); properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
properties.add(DiagnosticsProperty<MaterialStateProperty<Color?>>('timeSelectorSeparatorColor', timeSelectorSeparatorColor, defaultValue: null));
properties.add(DiagnosticsProperty<MaterialStateProperty<TextStyle?>>('timeSelectorSeparatorTextStyle', timeSelectorSeparatorTextStyle, defaultValue: null));
} }
} }
......
...@@ -1831,7 +1831,7 @@ void main() { ...@@ -1831,7 +1831,7 @@ void main() {
final double minuteFieldTop = final double minuteFieldTop =
tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_MinuteTextField')).dy; tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_MinuteTextField')).dy;
final double separatorTop = final double separatorTop =
tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment')).dy; tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_TimeSelectorSeparator')).dy;
expect(hourFieldTop, separatorTop); expect(hourFieldTop, separatorTop);
expect(minuteFieldTop, separatorTop); expect(minuteFieldTop, separatorTop);
}); });
...@@ -1965,6 +1965,32 @@ void main() { ...@@ -1965,6 +1965,32 @@ void main() {
}); });
}); });
} }
testWidgets('Material3 - Time selector separator default text style', (WidgetTester tester) async {
final ThemeData theme = ThemeData();
await startPicker(
tester,
(TimeOfDay? value) { },
theme: theme,
);
final RenderParagraph paragraph = tester.renderObject(find.text(':'));
expect(paragraph.text.style!.color, theme.colorScheme.onSurface);
expect(paragraph.text.style!.fontSize, 57.0);
});
testWidgets('Material2 - Time selector separator default text style', (WidgetTester tester) async {
final ThemeData theme = ThemeData(useMaterial3: false);
await startPicker(
tester,
(TimeOfDay? value) { },
theme: theme,
);
final RenderParagraph paragraph = tester.renderObject(find.text(':'));
expect(paragraph.text.style!.color, theme.colorScheme.onSurface);
expect(paragraph.text.style!.fontSize, 56.0);
});
} }
final Finder findDialPaint = find.descendant( final Finder findDialPaint = find.descendant(
...@@ -2175,10 +2201,11 @@ Future<Offset?> startPicker( ...@@ -2175,10 +2201,11 @@ Future<Offset?> startPicker(
ValueChanged<TimeOfDay?> onChanged, { ValueChanged<TimeOfDay?> onChanged, {
TimePickerEntryMode entryMode = TimePickerEntryMode.dial, TimePickerEntryMode entryMode = TimePickerEntryMode.dial,
String? restorationId, String? restorationId,
required MaterialType materialType, ThemeData? theme,
MaterialType? materialType,
}) async { }) async {
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
theme: ThemeData(useMaterial3: materialType == MaterialType.material3), theme: theme ?? ThemeData(useMaterial3: materialType == MaterialType.material3),
restorationScopeId: 'app', restorationScopeId: 'app',
locale: const Locale('en', 'US'), locale: const Locale('en', 'US'),
home: _TimePickerLauncher( home: _TimePickerLauncher(
......
...@@ -42,6 +42,8 @@ void main() { ...@@ -42,6 +42,8 @@ void main() {
expect(timePickerTheme.entryModeIconColor, null); expect(timePickerTheme.entryModeIconColor, null);
expect(timePickerTheme.padding, null); expect(timePickerTheme.padding, null);
expect(timePickerTheme.shape, null); expect(timePickerTheme.shape, null);
expect(timePickerTheme.timeSelectorSeparatorColor, null);
expect(timePickerTheme.timeSelectorSeparatorTextStyle, null);
}); });
testWidgets('Default TimePickerThemeData debugFillProperties', (WidgetTester tester) async { testWidgets('Default TimePickerThemeData debugFillProperties', (WidgetTester tester) async {
...@@ -89,6 +91,8 @@ void main() { ...@@ -89,6 +91,8 @@ void main() {
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
side: BorderSide(color: Color(0xfffffff3)), side: BorderSide(color: Color(0xfffffff3)),
), ),
timeSelectorSeparatorColor: MaterialStatePropertyAll<Color>(Color(0xfffffff4)),
timeSelectorSeparatorTextStyle: MaterialStatePropertyAll<TextStyle>(TextStyle(color: Color(0xfffffff5))),
).debugFillProperties(builder); ).debugFillProperties(builder);
final List<String> description = builder.properties final List<String> description = builder.properties
...@@ -118,7 +122,9 @@ void main() { ...@@ -118,7 +122,9 @@ void main() {
'hourMinuteTextStyle: TextStyle(inherit: true, color: Color(0xfffffff1))', 'hourMinuteTextStyle: TextStyle(inherit: true, color: Color(0xfffffff1))',
'inputDecorationTheme: InputDecorationTheme#ff861(labelStyle: TextStyle(inherit: true, color: Color(0xfffffff2)))', 'inputDecorationTheme: InputDecorationTheme#ff861(labelStyle: TextStyle(inherit: true, color: Color(0xfffffff2)))',
'padding: EdgeInsets.all(1.0)', 'padding: EdgeInsets.all(1.0)',
'shape: RoundedRectangleBorder(BorderSide(color: Color(0xfffffff3)), BorderRadius.zero)' 'shape: RoundedRectangleBorder(BorderSide(color: Color(0xfffffff3)), BorderRadius.zero)',
'timeSelectorSeparatorColor: MaterialStatePropertyAll(Color(0xfffffff4))',
'timeSelectorSeparatorTextStyle: MaterialStatePropertyAll(TextStyle(inherit: true, color: Color(0xfffffff5)))'
])); ]));
}); });
...@@ -798,6 +804,38 @@ void main() { ...@@ -798,6 +804,38 @@ void main() {
final Material pmMaterial = _textMaterial(tester, 'PM'); final Material pmMaterial = _textMaterial(tester, 'PM');
expect(pmMaterial.color, Colors.blue); expect(pmMaterial.color, Colors.blue);
}); });
testWidgets('Time selector separator color uses the timeSelectorSeparatorColor value', (WidgetTester tester) async {
final TimePickerThemeData timePickerTheme = _timePickerTheme().copyWith(
timeSelectorSeparatorColor: const MaterialStatePropertyAll<Color>(Color(0xff00ff00))
);
final ThemeData theme = ThemeData(timePickerTheme: timePickerTheme);
await tester.pumpWidget(_TimePickerLauncher(themeData: theme, entryMode: TimePickerEntryMode.input));
await tester.tap(find.text('X'));
await tester.pumpAndSettle(const Duration(seconds: 1));
final RenderParagraph paragraph = tester.renderObject(find.text(':'));
expect(paragraph.text.style!.color, const Color(0xff00ff00));
});
testWidgets('Time selector separator text style uses the timeSelectorSeparatorTextStyle value', (WidgetTester tester) async {
final TimePickerThemeData timePickerTheme = _timePickerTheme().copyWith(
timeSelectorSeparatorTextStyle: const MaterialStatePropertyAll<TextStyle>(
TextStyle(
fontSize: 35.0,
fontStyle: FontStyle.italic,
),
),
);
final ThemeData theme = ThemeData(timePickerTheme: timePickerTheme);
await tester.pumpWidget(_TimePickerLauncher(themeData: theme, entryMode: TimePickerEntryMode.input));
await tester.tap(find.text('X'));
await tester.pumpAndSettle(const Duration(seconds: 1));
final RenderParagraph paragraph = tester.renderObject(find.text(':'));
expect(paragraph.text.style!.fontSize, 35.0);
expect(paragraph.text.style!.fontStyle, FontStyle.italic);
});
} }
final Color _selectedColor = Colors.green[100]!; final Color _selectedColor = Colors.green[100]!;
......
...@@ -13,8 +13,8 @@ void main() { ...@@ -13,8 +13,8 @@ void main() {
tester.view.devicePixelRatio = 1; tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset); addTearDown(tester.view.reset);
final Finder stringFragmentTextFinder = find.descendant( final Finder timeSelectorSeparatorFinder = find.descendant(
of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment'), of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_TimeSelectorSeparator'),
matching: find.byType(Text), matching: find.byType(Text),
).first; ).first;
final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourControl'); final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourControl');
...@@ -33,10 +33,10 @@ void main() { ...@@ -33,10 +33,10 @@ void main() {
for (final Locale locale in locales) { for (final Locale locale in locales) {
final Offset center = await startPicker(tester, (TimeOfDay? time) { }, locale: locale, useMaterial3: false); final Offset center = await startPicker(tester, (TimeOfDay? time) { }, locale: locale, useMaterial3: false);
final Text stringFragmentText = tester.widget(stringFragmentTextFinder); final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx; final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx; final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
final double stringFragmentLeftOffset = tester.getTopLeft(stringFragmentTextFinder).dx; final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
if (locale == const Locale('en', 'US')) { if (locale == const Locale('en', 'US')) {
final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx; final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx;
...@@ -83,8 +83,8 @@ void main() { ...@@ -83,8 +83,8 @@ void main() {
tester.view.devicePixelRatio = 1; tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset); addTearDown(tester.view.reset);
final Finder stringFragmentTextFinder = find.descendant( final Finder timeSelectorSeparatorFinder = find.descendant(
of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment'), of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_TimeSelectorSeparator'),
matching: find.byType(Text), matching: find.byType(Text),
).first; ).first;
final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourControl'); final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourControl');
...@@ -103,10 +103,10 @@ void main() { ...@@ -103,10 +103,10 @@ void main() {
for (final Locale locale in locales) { for (final Locale locale in locales) {
final Offset center = await startPicker(tester, (TimeOfDay? time) { }, locale: locale, useMaterial3: true); final Offset center = await startPicker(tester, (TimeOfDay? time) { }, locale: locale, useMaterial3: true);
final Text stringFragmentText = tester.widget(stringFragmentTextFinder); final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx; final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx; final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
final double stringFragmentLeftOffset = tester.getTopLeft(stringFragmentTextFinder).dx; final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
if (locale == const Locale('en', 'US')) { if (locale == const Locale('en', 'US')) {
final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx; final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx;
...@@ -153,8 +153,8 @@ void main() { ...@@ -153,8 +153,8 @@ void main() {
tester.view.devicePixelRatio = 1; tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset); addTearDown(tester.view.reset);
final Finder stringFragmentTextFinder = find.descendant( final Finder timeSelectorSeparatorFinder = find.descendant(
of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment'), of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_TimeSelectorSeparator'),
matching: find.byType(Text), matching: find.byType(Text),
).first; ).first;
final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourControl'); final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourControl');
...@@ -173,11 +173,11 @@ void main() { ...@@ -173,11 +173,11 @@ void main() {
for (final Locale locale in locales) { for (final Locale locale in locales) {
final Offset center = await startPicker(tester, (TimeOfDay? time) { }, locale: locale, useMaterial3: false); final Offset center = await startPicker(tester, (TimeOfDay? time) { }, locale: locale, useMaterial3: false);
final Text stringFragmentText = tester.widget(stringFragmentTextFinder); final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx; final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
final double hourTopOffset = tester.getTopLeft(hourControlFinder).dy; final double hourTopOffset = tester.getTopLeft(hourControlFinder).dy;
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx; final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
final double stringFragmentLeftOffset = tester.getTopLeft(stringFragmentTextFinder).dx; final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
if (locale == const Locale('en', 'US')) { if (locale == const Locale('en', 'US')) {
final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx; final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx;
...@@ -228,8 +228,8 @@ void main() { ...@@ -228,8 +228,8 @@ void main() {
tester.view.devicePixelRatio = 1; tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset); addTearDown(tester.view.reset);
final Finder stringFragmentTextFinder = find.descendant( final Finder timeSelectorSeparatorFinder = find.descendant(
of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment'), of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_TimeSelectorSeparator'),
matching: find.byType(Text), matching: find.byType(Text),
).first; ).first;
final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourControl'); final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourControl');
...@@ -248,11 +248,11 @@ void main() { ...@@ -248,11 +248,11 @@ void main() {
for (final Locale locale in locales) { for (final Locale locale in locales) {
final Offset center = await startPicker(tester, (TimeOfDay? time) { }, locale: locale, useMaterial3: true); final Offset center = await startPicker(tester, (TimeOfDay? time) { }, locale: locale, useMaterial3: true);
final Text stringFragmentText = tester.widget(stringFragmentTextFinder); final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx; final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
final double hourTopOffset = tester.getTopLeft(hourControlFinder).dy; final double hourTopOffset = tester.getTopLeft(hourControlFinder).dy;
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx; final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
final double stringFragmentLeftOffset = tester.getTopLeft(stringFragmentTextFinder).dx; final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
if (locale == const Locale('en', 'US')) { if (locale == const Locale('en', 'US')) {
final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx; final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx;
...@@ -301,8 +301,8 @@ void main() { ...@@ -301,8 +301,8 @@ void main() {
final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourTextField'); final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourTextField');
final Finder minuteControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_MinuteTextField'); final Finder minuteControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_MinuteTextField');
final Finder dayPeriodControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_DayPeriodControl'); final Finder dayPeriodControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_DayPeriodControl');
final Finder stringFragmentTextFinder = find.descendant( final Finder timeSelectorSeparatorFinder = find.descendant(
of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment'), of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_TimeSelectorSeparator'),
matching: find.byType(Text), matching: find.byType(Text),
).first; ).first;
...@@ -321,10 +321,10 @@ void main() { ...@@ -321,10 +321,10 @@ void main() {
await tester.tap(find.text('X')); await tester.tap(find.text('X'));
await tester.pumpAndSettle(const Duration(seconds: 1)); await tester.pumpAndSettle(const Duration(seconds: 1));
final Text stringFragmentText = tester.widget(stringFragmentTextFinder); final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx; final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx; final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
final double stringFragmentLeftOffset = tester.getTopLeft(stringFragmentTextFinder).dx; final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
if (locale == const Locale('en', 'US')) { if (locale == const Locale('en', 'US')) {
final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx; final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx;
...@@ -369,8 +369,8 @@ void main() { ...@@ -369,8 +369,8 @@ void main() {
final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourTextField'); final Finder hourControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourTextField');
final Finder minuteControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_MinuteTextField'); final Finder minuteControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_MinuteTextField');
final Finder dayPeriodControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_DayPeriodControl'); final Finder dayPeriodControlFinder = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_DayPeriodControl');
final Finder stringFragmentTextFinder = find.descendant( final Finder timeSelectorSeparatorFinder = find.descendant(
of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment'), of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_TimeSelectorSeparator'),
matching: find.byType(Text), matching: find.byType(Text),
).first; ).first;
...@@ -389,10 +389,10 @@ void main() { ...@@ -389,10 +389,10 @@ void main() {
await tester.tap(find.text('X')); await tester.tap(find.text('X'));
await tester.pumpAndSettle(const Duration(seconds: 1)); await tester.pumpAndSettle(const Duration(seconds: 1));
final Text stringFragmentText = tester.widget(stringFragmentTextFinder); final Text stringFragmentText = tester.widget(timeSelectorSeparatorFinder);
final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx; final double hourLeftOffset = tester.getTopLeft(hourControlFinder).dx;
final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx; final double minuteLeftOffset = tester.getTopLeft(minuteControlFinder).dx;
final double stringFragmentLeftOffset = tester.getTopLeft(stringFragmentTextFinder).dx; final double stringFragmentLeftOffset = tester.getTopLeft(timeSelectorSeparatorFinder).dx;
if (locale == const Locale('en', 'US')) { if (locale == const Locale('en', 'US')) {
final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx; final double dayPeriodLeftOffset = tester.getTopLeft(dayPeriodControlFinder).dx;
......
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