Unverified Commit 700de09f authored by Tae Hyung Kim's avatar Tae Hyung Kim Committed by GitHub

Change button and label text to sentence case for Material 3 (#115187)

* init

* upper case only when material 2

* fix test

* fix test

* fix tests again

* Add all tests

* analyze"

* fix stepper
parent 136b46ba
......@@ -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),
],
),
),
......@@ -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,
......@@ -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);
},
......
......@@ -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,
......@@ -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,
......@@ -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;
......@@ -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;
......@@ -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,
......@@ -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,
......
......@@ -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';
......@@ -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';
......@@ -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';
......@@ -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';
......
......@@ -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),
......@@ -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()
),
),
),
],
......
......@@ -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,
......@@ -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,
......@@ -1495,6 +1499,10 @@ 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),
......@@ -1502,7 +1510,7 @@ class _TimePickerInputState extends State<_TimePickerInput> with RestorationMixi
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),
......@@ -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,
......
......@@ -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();
......
......@@ -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) {
......@@ -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';
......
......@@ -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) {
......@@ -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'));
......
......@@ -7,6 +7,37 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Material3 has sentence case labels', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(useMaterial3: true),
home: Material(
child: Stepper(
onStepTapped: (int i) {},
steps: const <Step>[
Step(
title: Text('Step 1'),
content: SizedBox(
width: 100.0,
height: 100.0,
),
),
Step(
title: Text('Step 2'),
content: SizedBox(
width: 100.0,
height: 100.0,
),
),
],
),
),
),
);
expect(find.text('Continue'), findsWidgets);
expect(find.text('Cancel'), findsWidgets);
});
testWidgets('Stepper tap callback test', (WidgetTester tester) async {
int index = 0;
......
......@@ -106,8 +106,10 @@ Future<Offset?> startPicker(
ValueChanged<TimeOfDay?> onChanged, {
TimePickerEntryMode entryMode = TimePickerEntryMode.dial,
String? restorationId,
bool useMaterial3 = false,
}) async {
await tester.pumpWidget(MaterialApp(
theme: ThemeData(useMaterial3: useMaterial3),
restorationScopeId: 'app',
locale: const Locale('en', 'US'),
home: _TimePickerLauncher(
......@@ -138,6 +140,14 @@ void main() {
}
void _tests() {
testWidgets('Material3 has sentence case labels', (WidgetTester tester) async {
await startPicker(tester, (TimeOfDay? time) {
expect(find.text('Select time'), findsOneWidget);
expect(find.text('Enter time'), findsOneWidget);
expect(find.text('Cancel'), findsOneWidget);
}, useMaterial3: true);
});
testWidgets('tap-select an hour', (WidgetTester tester) async {
TimeOfDay? result;
......
......@@ -151,17 +151,17 @@
"plural": "selectedRowCount"
},
"cancelButtonLabel": "CANCEL",
"cancelButtonLabel": "Cancel",
"@cancelButtonLabel": {
"description": "The label for cancel buttons and menu items."
},
"closeButtonLabel": "CLOSE",
"closeButtonLabel": "Close",
"@closeButtonLabel": {
"description": "The label for close buttons and menu items."
},
"continueButtonLabel": "CONTINUE",
"continueButtonLabel": "Continue",
"@continueButtonLabel": {
"description": "The label for continue buttons and menu items."
},
......@@ -191,7 +191,7 @@
"description": "The label for select-all buttons and menu items."
},
"viewLicensesButtonLabel": "VIEW LICENSES",
"viewLicensesButtonLabel": "View licenses",
"@viewLicensesButtonLabel": {
"description": "The label for the button in the about box that leads the user to a list of all licenses that apply to the application."
},
......@@ -288,17 +288,17 @@
"description": "Error message displayed to the user when they have entered a date that is outside the valid range for the date picker."
},
"saveButtonLabel": "SAVE",
"saveButtonLabel": "Save",
"@saveButtonLabel": {
"description": "Label for a 'SAVE' button used in full screen dialogs."
"description": "Label for a 'Save' button used in full screen dialogs."
},
"datePickerHelpText": "SELECT DATE",
"datePickerHelpText": "Select date",
"@datePickerHelpText": {
"description": "Label used in the header of the date picker dialog"
},
"dateRangePickerHelpText": "SELECT RANGE",
"dateRangePickerHelpText": "Select range",
"@dateRangePickerHelpText": {
"description": "Label used in the header of the date range picker dialog."
},
......@@ -313,12 +313,12 @@
"description": "Tooltip used for the text input mode button of the date pickers."
},
"timePickerDialHelpText": "SELECT TIME",
"timePickerDialHelpText": "Select time",
"@timePickerDialHelpText": {
"description": "Label used in the header of the time picker dialog when using the clock dial to select a time."
},
"timePickerInputHelpText": "ENTER TIME",
"timePickerInputHelpText": "Enter time",
"@timePickerInputHelpText": {
"description": "Label used in the header of the time picker dialog when using the text input to enter a time."
},
......
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