Skip to content

Commit

Permalink
Change button and label text to sentence case for Material 3 (#115187)
Browse files Browse the repository at this point in the history
* init

* upper case only when material 2

* fix test

* fix test

* fix tests again

* Add all tests

* analyze"

* fix stepper
  • Loading branch information
thkim1011 authored Nov 15, 2022
1 parent 136b46b commit 700de09
Show file tree
Hide file tree
Showing 12 changed files with 398 additions and 47 deletions.
22 changes: 16 additions & 6 deletions packages/flutter/lib/src/material/about.dart
Original file line number Diff line number Diff line change
Expand Up @@ -318,22 +318,24 @@ class AboutDialog extends StatelessWidget {
final String name = applicationName ?? _defaultApplicationName(context);
final String version = applicationVersion ?? _defaultApplicationVersion(context);
final Widget? icon = applicationIcon ?? _defaultApplicationIcon(context);
final ThemeData themeData = Theme.of(context);
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
return AlertDialog(
content: ListBody(
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
if (icon != null) IconTheme(data: Theme.of(context).iconTheme, child: icon),
if (icon != null) IconTheme(data: themeData.iconTheme, child: icon),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: ListBody(
children: <Widget>[
Text(name, style: Theme.of(context).textTheme.headlineSmall),
Text(version, style: Theme.of(context).textTheme.bodyMedium),
Text(name, style: themeData.textTheme.headlineSmall),
Text(version, style: themeData.textTheme.bodyMedium),
const SizedBox(height: _textVerticalSeparation),
Text(applicationLegalese ?? '', style: Theme.of(context).textTheme.bodySmall),
Text(applicationLegalese ?? '', style: themeData.textTheme.bodySmall),
],
),
),
Expand All @@ -345,7 +347,11 @@ class AboutDialog extends StatelessWidget {
),
actions: <Widget>[
TextButton(
child: Text(MaterialLocalizations.of(context).viewLicensesButtonLabel),
child: Text(
themeData.useMaterial3
? localizations.viewLicensesButtonLabel
: localizations.viewLicensesButtonLabel.toUpperCase()
),
onPressed: () {
showLicensePage(
context: context,
Expand All @@ -357,7 +363,11 @@ class AboutDialog extends StatelessWidget {
},
),
TextButton(
child: Text(MaterialLocalizations.of(context).closeButtonLabel),
child: Text(
themeData.useMaterial3
? localizations.closeButtonLabel
: localizations.closeButtonLabel.toUpperCase()
),
onPressed: () {
Navigator.pop(context);
},
Expand Down
48 changes: 40 additions & 8 deletions packages/flutter/lib/src/material/date_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,11 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
children: <Widget>[
TextButton(
onPressed: _handleCancel,
child: Text(widget.cancelText ?? localizations.cancelButtonLabel),
child: Text(widget.cancelText ?? (
theme.useMaterial3
? localizations.cancelButtonLabel
: localizations.cancelButtonLabel.toUpperCase()
)),
),
TextButton(
onPressed: _handleOk,
Expand Down Expand Up @@ -571,7 +575,11 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
}

final Widget header = _DatePickerHeader(
helpText: widget.helpText ?? localizations.datePickerHelpText,
helpText: widget.helpText ?? (
Theme.of(context).useMaterial3
? localizations.datePickerHelpText
: localizations.datePickerHelpText.toUpperCase()
),
titleText: dateText,
titleStyle: dateStyle,
orientation: orientation,
Expand Down Expand Up @@ -1348,8 +1356,16 @@ class _DateRangePickerDialogState extends State<DateRangePickerDialog> with Rest
onPressed: _handleEntryModeToggle,
)
: null,
confirmText: widget.saveText ?? localizations.saveButtonLabel,
helpText: widget.helpText ?? localizations.dateRangePickerHelpText,
confirmText: widget.saveText ?? (
Theme.of(context).useMaterial3
? localizations.saveButtonLabel
: localizations.saveButtonLabel.toUpperCase()
),
helpText: widget.helpText ?? (
Theme.of(context).useMaterial3
? localizations.dateRangePickerHelpText
: localizations.dateRangePickerHelpText.toUpperCase()
),
);
size = mediaQuery.size;
insetPadding = EdgeInsets.zero;
Expand Down Expand Up @@ -1406,8 +1422,16 @@ class _DateRangePickerDialogState extends State<DateRangePickerDialog> with Rest
)
: null,
confirmText: widget.confirmText ?? localizations.okButtonLabel,
cancelText: widget.cancelText ?? localizations.cancelButtonLabel,
helpText: widget.helpText ?? localizations.dateRangePickerHelpText,
cancelText: widget.cancelText ?? (
Theme.of(context).useMaterial3
? localizations.cancelButtonLabel
: localizations.cancelButtonLabel.toUpperCase()
),
helpText: widget.helpText ?? (
Theme.of(context).useMaterial3
? localizations.dateRangePickerHelpText
: localizations.dateRangePickerHelpText.toUpperCase()
),
);
final DialogTheme dialogTheme = Theme.of(context).dialogTheme;
size = orientation == Orientation.portrait ? _inputPortraitDialogSize : _inputRangeLandscapeDialogSize;
Expand Down Expand Up @@ -2613,7 +2637,11 @@ class _InputDateRangePickerDialog extends StatelessWidget {
: '';

final Widget header = _DatePickerHeader(
helpText: helpText ?? localizations.dateRangePickerHelpText,
helpText: helpText ?? (
Theme.of(context).useMaterial3
? localizations.dateRangePickerHelpText
: localizations.dateRangePickerHelpText.toUpperCase()
),
titleText: dateText,
titleSemanticsLabel: semanticDateText,
titleStyle: dateStyle,
Expand All @@ -2631,7 +2659,11 @@ class _InputDateRangePickerDialog extends StatelessWidget {
children: <Widget>[
TextButton(
onPressed: onCancel,
child: Text(cancelText ?? localizations.cancelButtonLabel),
child: Text(cancelText ?? (
theme.useMaterial3
? localizations.cancelButtonLabel
: localizations.cancelButtonLabel.toUpperCase()
)),
),
TextButton(
onPressed: onConfirm,
Expand Down
18 changes: 9 additions & 9 deletions packages/flutter/lib/src/material/material_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -925,13 +925,13 @@ class DefaultMaterialLocalizations implements MaterialLocalizations {
String get dateOutOfRangeLabel => 'Out of range.';

@override
String get saveButtonLabel => 'SAVE';
String get saveButtonLabel => 'Save';

@override
String get datePickerHelpText => 'SELECT DATE';
String get datePickerHelpText => 'Select date';

@override
String get dateRangePickerHelpText => 'SELECT RANGE';
String get dateRangePickerHelpText => 'Select range';

@override
String get calendarModeButtonLabel => 'Switch to calendar';
Expand All @@ -940,10 +940,10 @@ class DefaultMaterialLocalizations implements MaterialLocalizations {
String get inputDateModeButtonLabel => 'Switch to input';

@override
String get timePickerDialHelpText => 'SELECT TIME';
String get timePickerDialHelpText => 'Select time';

@override
String get timePickerInputHelpText => 'ENTER TIME';
String get timePickerInputHelpText => 'Enter time';

@override
String get timePickerHourLabel => 'Hour';
Expand Down Expand Up @@ -1120,13 +1120,13 @@ class DefaultMaterialLocalizations implements MaterialLocalizations {
}

@override
String get cancelButtonLabel => 'CANCEL';
String get cancelButtonLabel => 'Cancel';

@override
String get closeButtonLabel => 'CLOSE';
String get closeButtonLabel => 'Close';

@override
String get continueButtonLabel => 'CONTINUE';
String get continueButtonLabel => 'Continue';

@override
String get copyButtonLabel => 'Copy';
Expand All @@ -1144,7 +1144,7 @@ class DefaultMaterialLocalizations implements MaterialLocalizations {
String get selectAllButtonLabel => 'Select all';

@override
String get viewLicensesButtonLabel => 'VIEW LICENSES';
String get viewLicensesButtonLabel => 'View licenses';

@override
String get anteMeridiemAbbreviation => 'AM';
Expand Down
12 changes: 10 additions & 2 deletions packages/flutter/lib/src/material/stepper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,11 @@ class _StepperState extends State<Stepper> with TickerProviderStateMixin {
padding: const MaterialStatePropertyAll<EdgeInsetsGeometry>(buttonPadding),
shape: const MaterialStatePropertyAll<OutlinedBorder>(buttonShape),
),
child: Text(localizations.continueButtonLabel),
child: Text(
themeData.useMaterial3
? localizations.continueButtonLabel
: localizations.continueButtonLabel.toUpperCase()
),
),
Container(
margin: const EdgeInsetsDirectional.only(start: 8.0),
Expand All @@ -536,7 +540,11 @@ class _StepperState extends State<Stepper> with TickerProviderStateMixin {
padding: buttonPadding,
shape: buttonShape,
),
child: Text(localizations.cancelButtonLabel),
child: Text(
themeData.useMaterial3
? localizations.cancelButtonLabel
: localizations.cancelButtonLabel.toUpperCase()
),
),
),
],
Expand Down
18 changes: 15 additions & 3 deletions packages/flutter/lib/src/material/time_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ class _TimePickerHeader extends StatelessWidget {
final TimeOfDayFormat timeOfDayFormat = MaterialLocalizations.of(context).timeOfDayFormat(
alwaysUse24HourFormat: MediaQuery.of(context).alwaysUse24HourFormat,
);
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final String timePickerDialHelpText = themeData.useMaterial3
? localizations.timePickerDialHelpText
: localizations.timePickerDialHelpText.toUpperCase();

final _TimePickerFragmentContext fragmentContext = _TimePickerFragmentContext(
selectedTime: selectedTime,
Expand Down Expand Up @@ -255,7 +259,7 @@ class _TimePickerHeader extends StatelessWidget {
children: <Widget>[
const SizedBox(height: 16.0),
Text(
helpText ?? MaterialLocalizations.of(context).timePickerDialHelpText,
helpText ?? timePickerDialHelpText,
style: TimePickerTheme.of(context).helpTextStyle ?? themeData.textTheme.labelSmall,
),
controls,
Expand Down Expand Up @@ -1495,14 +1499,18 @@ class _TimePickerInputState extends State<_TimePickerInput> with RestorationMixi
final bool use24HourDials = hourFormat(of: timeOfDayFormat) != HourFormat.h;
final ThemeData theme = Theme.of(context);
final TextStyle hourMinuteStyle = TimePickerTheme.of(context).hourMinuteTextStyle ?? theme.textTheme.displayMedium!;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final String timePickerInputHelpText = theme.useMaterial3
? localizations.timePickerInputHelpText
: localizations.timePickerInputHelpText.toUpperCase();

return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
widget.helpText ?? MaterialLocalizations.of(context).timePickerInputHelpText,
widget.helpText ?? timePickerInputHelpText,
style: TimePickerTheme.of(context).helpTextStyle ?? theme.textTheme.labelSmall,
),
const SizedBox(height: 16.0),
Expand Down Expand Up @@ -2258,7 +2266,11 @@ class _TimePickerDialogState extends State<TimePickerDialog> with RestorationMix
children: <Widget>[
TextButton(
onPressed: _handleCancel,
child: Text(widget.cancelText ?? localizations.cancelButtonLabel),
child: Text(widget.cancelText ?? (
theme.useMaterial3
? localizations.cancelButtonLabel
: localizations.cancelButtonLabel.toUpperCase()
)),
),
TextButton(
onPressed: _handleOk,
Expand Down
40 changes: 40 additions & 0 deletions packages/flutter/test/material/about_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,46 @@ void main() {
LicenseRegistry.reset();
});

testWidgets('Material3 has sentence case labels', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
theme: ThemeData(useMaterial3: true),
builder: (BuildContext context, Widget? child) {
return MediaQuery(
// Display has a vertical hinge down the middle
data: const MediaQueryData(
size: Size(800, 600),
displayFeatures: <DisplayFeature>[
DisplayFeature(
bounds: Rect.fromLTRB(390, 0, 410, 600),
type: DisplayFeatureType.hinge,
state: DisplayFeatureState.unknown,
),
],
),
child: child!,
);
},
home: Builder(
builder: (BuildContext context) => ElevatedButton(
onPressed: () {
showAboutDialog(
context: context,
useRootNavigator: false,
applicationName: 'A',
);
},
child: const Text('Show About Dialog'),
),
),
));

// Open the dialog.
await tester.tap(find.byType(ElevatedButton));
await tester.pumpAndSettle();
expect(find.text('Close'), findsOneWidget);
expect(find.text('View licenses'), findsOneWidget);
});

testWidgets('AboutListTile control test', (WidgetTester tester) async {
const FlutterLogo logo = FlutterLogo();

Expand Down
7 changes: 7 additions & 0 deletions packages/flutter/test/material/date_picker_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ void main() {
WidgetTester tester,
Future<void> Function(Future<DateTime?> date) callback, {
TextDirection textDirection = TextDirection.ltr,
bool useMaterial3 = false,
}) async {
late BuildContext buttonContext;
await tester.pumpWidget(MaterialApp(
theme: ThemeData(useMaterial3: useMaterial3),
home: Material(
child: Builder(
builder: (BuildContext context) {
Expand Down Expand Up @@ -112,6 +114,11 @@ void main() {
}

group('showDatePicker Dialog', () {
testWidgets('Material3 uses sentence case labels', (WidgetTester tester) async {
await prepareDatePicker(tester, (Future<DateTime?> date) async {
expect(find.text('Select date'), findsOneWidget);
}, useMaterial3: true);
});
testWidgets('Cancel, confirm, and help text is used', (WidgetTester tester) async {
cancelText = 'nope';
confirmText = 'yep';
Expand Down
9 changes: 9 additions & 0 deletions packages/flutter/test/material/date_range_picker_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@ void main() {
WidgetTester tester,
Future<void> Function(Future<DateTimeRange?> date) callback, {
TextDirection textDirection = TextDirection.ltr,
bool useMaterial3 = false,
}) async {
late BuildContext buttonContext;
await tester.pumpWidget(MaterialApp(
theme: ThemeData(useMaterial3: useMaterial3),
home: Material(
child: Builder(
builder: (BuildContext context) {
Expand Down Expand Up @@ -115,6 +117,13 @@ void main() {
});
});

testWidgets('Material3 has sentence case labels', (WidgetTester tester) async {
await preparePicker(tester, (Future<DateTimeRange?> range) async {
expect(find.text('Save'), findsOneWidget);
expect(find.text('Select range'), findsOneWidget);
}, useMaterial3: true);
});

testWidgets('Initial date is the default', (WidgetTester tester) async {
await preparePicker(tester, (Future<DateTimeRange?> range) async {
await tester.tap(find.text('SAVE'));
Expand Down
Loading

0 comments on commit 700de09

Please sign in to comment.