Commit b9e1be9a authored by Yegor's avatar Yegor Committed by GitHub

introduce localized text geometry in MaterialLocalizations (#11829)

* introduce localized text geometry in MaterialLocalizations

* remove geometry from color text themes

* fix merge conflict

* optional Localizations

* fix fallback; test; docs
parent f4f20c29
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
/// This variable is used by [MaterialLocalizations]. /// This variable is used by [MaterialLocalizations].
const Map<String, Map<String, String>> localizations = const <String, Map<String, String>> { const Map<String, Map<String, String>> localizations = const <String, Map<String, String>> {
"ar": const <String, String>{ "ar": const <String, String>{
"scriptCategory": r"tall",
"timeOfDayFormat": r"h:mm a", "timeOfDayFormat": r"h:mm a",
"openAppDrawerTooltip": r"افتح قائمة التنقل", "openAppDrawerTooltip": r"افتح قائمة التنقل",
"backButtonTooltip": r"الى الخلف", "backButtonTooltip": r"الى الخلف",
...@@ -40,6 +41,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -40,6 +41,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"postMeridiemAbbreviation": r"م", "postMeridiemAbbreviation": r"م",
}, },
"de": const <String, String>{ "de": const <String, String>{
"scriptCategory": r"English-like",
"timeOfDayFormat": r"HH:mm", "timeOfDayFormat": r"HH:mm",
"openAppDrawerTooltip": r"Navigationsmenü öffnen", "openAppDrawerTooltip": r"Navigationsmenü öffnen",
"backButtonTooltip": r"Zurück", "backButtonTooltip": r"Zurück",
...@@ -68,6 +70,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -68,6 +70,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"viewLicensesButtonLabel": r"LIZENZEN ANZEIGEN", "viewLicensesButtonLabel": r"LIZENZEN ANZEIGEN",
}, },
"en": const <String, String>{ "en": const <String, String>{
"scriptCategory": r"English-like",
"timeOfDayFormat": r"h:mm a", "timeOfDayFormat": r"h:mm a",
"openAppDrawerTooltip": r"Open navigation menu", "openAppDrawerTooltip": r"Open navigation menu",
"backButtonTooltip": r"Back", "backButtonTooltip": r"Back",
...@@ -107,6 +110,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -107,6 +110,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"timeOfDayFormat": r"HH:mm", "timeOfDayFormat": r"HH:mm",
}, },
"es": const <String, String>{ "es": const <String, String>{
"scriptCategory": r"English-like",
"timeOfDayFormat": r"H:mm", "timeOfDayFormat": r"H:mm",
"openAppDrawerTooltip": r"Abrir el menú de navegación", "openAppDrawerTooltip": r"Abrir el menú de navegación",
"backButtonTooltip": r"Espalda", "backButtonTooltip": r"Espalda",
...@@ -140,6 +144,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -140,6 +144,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"postMeridiemAbbreviation": r"PM", "postMeridiemAbbreviation": r"PM",
}, },
"fa": const <String, String>{ "fa": const <String, String>{
"scriptCategory": r"tall",
"timeOfDayFormat": r"H:mm", "timeOfDayFormat": r"H:mm",
"openAppDrawerTooltip": r"منوی ناوبری را باز کنید", "openAppDrawerTooltip": r"منوی ناوبری را باز کنید",
"backButtonTooltip": r"بازگشت", "backButtonTooltip": r"بازگشت",
...@@ -166,6 +171,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -166,6 +171,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"viewLicensesButtonLabel": r"مشاهده مجوز", "viewLicensesButtonLabel": r"مشاهده مجوز",
}, },
"fr": const <String, String>{ "fr": const <String, String>{
"scriptCategory": r"English-like",
"timeOfDayFormat": r"HH:mm", "timeOfDayFormat": r"HH:mm",
"openAppDrawerTooltip": r"Ouvrir le menu de navigation", "openAppDrawerTooltip": r"Ouvrir le menu de navigation",
"backButtonTooltip": r"Retour", "backButtonTooltip": r"Retour",
...@@ -197,6 +203,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -197,6 +203,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"timeOfDayFormat": r"HH 'h' mm", "timeOfDayFormat": r"HH 'h' mm",
}, },
"he": const <String, String>{ "he": const <String, String>{
"scriptCategory": r"English-like",
"timeOfDayFormat": r"H:mm", "timeOfDayFormat": r"H:mm",
"openAppDrawerTooltip": r"פתח תפריט ניווט", "openAppDrawerTooltip": r"פתח תפריט ניווט",
"backButtonTooltip": r"אחורה", "backButtonTooltip": r"אחורה",
...@@ -223,6 +230,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -223,6 +230,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"viewLicensesButtonLabel": r"ראה רישיונות", "viewLicensesButtonLabel": r"ראה רישיונות",
}, },
"it": const <String, String>{ "it": const <String, String>{
"scriptCategory": r"English-like",
"timeOfDayFormat": r"HH:mm", "timeOfDayFormat": r"HH:mm",
"openAppDrawerTooltip": r"Apri il menu di navigazione", "openAppDrawerTooltip": r"Apri il menu di navigazione",
"backButtonTooltip": r"Indietro", "backButtonTooltip": r"Indietro",
...@@ -249,6 +257,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -249,6 +257,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"viewLicensesButtonLabel": r"VEDI LE LICENZE", "viewLicensesButtonLabel": r"VEDI LE LICENZE",
}, },
"ja": const <String, String>{ "ja": const <String, String>{
"scriptCategory": r"dense",
"timeOfDayFormat": r"H:mm", "timeOfDayFormat": r"H:mm",
"openAppDrawerTooltip": r"ナビゲーションメニューを開く", "openAppDrawerTooltip": r"ナビゲーションメニューを開く",
"backButtonTooltip": r"戻る", "backButtonTooltip": r"戻る",
...@@ -275,6 +284,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -275,6 +284,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"viewLicensesButtonLabel": r"ライセンス表記", "viewLicensesButtonLabel": r"ライセンス表記",
}, },
"ps": const <String, String>{ "ps": const <String, String>{
"scriptCategory": r"tall",
"timeOfDayFormat": r"HH:mm", "timeOfDayFormat": r"HH:mm",
"openAppDrawerTooltip": r"د پرانیستی نیینګ مینو", "openAppDrawerTooltip": r"د پرانیستی نیینګ مینو",
"backButtonTooltip": r"شاته", "backButtonTooltip": r"شاته",
...@@ -301,6 +311,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -301,6 +311,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"viewLicensesButtonLabel": r"لیدلس وګورئ", "viewLicensesButtonLabel": r"لیدلس وګورئ",
}, },
"pt": const <String, String>{ "pt": const <String, String>{
"scriptCategory": r"English-like",
"timeOfDayFormat": r"HH:mm", "timeOfDayFormat": r"HH:mm",
"openAppDrawerTooltip": r"Abrir menu de navegação", "openAppDrawerTooltip": r"Abrir menu de navegação",
"backButtonTooltip": r"Costas", "backButtonTooltip": r"Costas",
...@@ -327,6 +338,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -327,6 +338,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"viewLicensesButtonLabel": r"VER LICENÇAS", "viewLicensesButtonLabel": r"VER LICENÇAS",
}, },
"ru": const <String, String>{ "ru": const <String, String>{
"scriptCategory": r"English-like",
"timeOfDayFormat": r"H:mm", "timeOfDayFormat": r"H:mm",
"openAppDrawerTooltip": r"Открыть меню навигации", "openAppDrawerTooltip": r"Открыть меню навигации",
"backButtonTooltip": r"Назад", "backButtonTooltip": r"Назад",
...@@ -355,6 +367,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -355,6 +367,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"viewLicensesButtonLabel": r"ПРОСМОТРЕТЬ ЛИЦЕНЗИИ", "viewLicensesButtonLabel": r"ПРОСМОТРЕТЬ ЛИЦЕНЗИИ",
}, },
"sd": const <String, String>{ "sd": const <String, String>{
"scriptCategory": r"tall",
"timeOfDayFormat": r"HH:mm", "timeOfDayFormat": r"HH:mm",
"openAppDrawerTooltip": r"اوپن جي مينڊيٽ مينيو", "openAppDrawerTooltip": r"اوپن جي مينڊيٽ مينيو",
"backButtonTooltip": r"پوئتي", "backButtonTooltip": r"پوئتي",
...@@ -381,6 +394,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -381,6 +394,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"viewLicensesButtonLabel": r"لائسنس ڏسو", "viewLicensesButtonLabel": r"لائسنس ڏسو",
}, },
"ur": const <String, String>{ "ur": const <String, String>{
"scriptCategory": r"tall",
"timeOfDayFormat": r"h:mm a", "timeOfDayFormat": r"h:mm a",
"openAppDrawerTooltip": r"کھولیں نیویگیشن مینو", "openAppDrawerTooltip": r"کھولیں نیویگیشن مینو",
"backButtonTooltip": r"واپس", "backButtonTooltip": r"واپس",
...@@ -409,6 +423,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String ...@@ -409,6 +423,7 @@ const Map<String, Map<String, String>> localizations = const <String, Map<String
"postMeridiemAbbreviation": r"PM", "postMeridiemAbbreviation": r"PM",
}, },
"zh": const <String, String>{ "zh": const <String, String>{
"scriptCategory": r"dense",
"timeOfDayFormat": r"ah:mm", "timeOfDayFormat": r"ah:mm",
"openAppDrawerTooltip": r"打开导航菜单", "openAppDrawerTooltip": r"打开导航菜单",
"backButtonTooltip": r"返回", "backButtonTooltip": r"返回",
......
{ {
"scriptCategory": "tall",
"timeOfDayFormat": "h:mm a", "timeOfDayFormat": "h:mm a",
"openAppDrawerTooltip": "افتح قائمة التنقل", "openAppDrawerTooltip": "افتح قائمة التنقل",
"backButtonTooltip": "الى الخلف", "backButtonTooltip": "الى الخلف",
......
{ {
"scriptCategory": "English-like",
"timeOfDayFormat": "HH:mm", "timeOfDayFormat": "HH:mm",
"@anteMeridiemAbbreviation": { "notUsed": "German time format does not use a.m. indicator" }, "@anteMeridiemAbbreviation": { "notUsed": "German time format does not use a.m. indicator" },
"@postMeridiemAbbreviation": { "notUsed": "German time format does not use p.m. indicator" }, "@postMeridiemAbbreviation": { "notUsed": "German time format does not use p.m. indicator" },
......
{ {
"scriptCategory": "English-like",
"@scriptCategory": {
"description": "The name of the language's script category (see https://material.io/guidelines/style/typography.html#typography-language-categories-reference)",
"type": "text"
},
"timeOfDayFormat": "h:mm a", "timeOfDayFormat": "h:mm a",
"@timeOfDayFormat": { "@timeOfDayFormat": {
"description": "The ICU 'Short Time' pattern, such as 'HH:mm', 'h:mm a', 'H:mm'. See: http://demo.icu-project.org/icu-bin/locexp?d_=en&_=en_US", "description": "The ICU 'Short Time' pattern, such as 'HH:mm', 'h:mm a', 'H:mm'. See: http://demo.icu-project.org/icu-bin/locexp?d_=en&_=en_US",
......
{ {
"scriptCategory": "English-like",
"timeOfDayFormat": "H:mm", "timeOfDayFormat": "H:mm",
"@anteMeridiemAbbreviation": { "notUsed": "Standard Spanish time format does not use a.m. indicator" }, "@anteMeridiemAbbreviation": { "notUsed": "Standard Spanish time format does not use a.m. indicator" },
"@postMeridiemAbbreviation": { "notUsed": "Standard Spanish time format does not use p.m. indicator" }, "@postMeridiemAbbreviation": { "notUsed": "Standard Spanish time format does not use p.m. indicator" },
......
{ {
"scriptCategory": "tall",
"timeOfDayFormat": "H:mm", "timeOfDayFormat": "H:mm",
"@anteMeridiemAbbreviation": { "notUsed": "Farsi time format does not use a.m. indicator" }, "@anteMeridiemAbbreviation": { "notUsed": "Farsi time format does not use a.m. indicator" },
"@postMeridiemAbbreviation": { "notUsed": "Farsi time format does not use p.m. indicator" }, "@postMeridiemAbbreviation": { "notUsed": "Farsi time format does not use p.m. indicator" },
......
{ {
"scriptCategory": "English-like",
"timeOfDayFormat": "HH:mm", "timeOfDayFormat": "HH:mm",
"@anteMeridiemAbbreviation": { "notUsed": "French time format does not use a.m. indicator" }, "@anteMeridiemAbbreviation": { "notUsed": "French time format does not use a.m. indicator" },
"@postMeridiemAbbreviation": { "notUsed": "French time format does not use p.m. indicator" }, "@postMeridiemAbbreviation": { "notUsed": "French time format does not use p.m. indicator" },
......
{ {
"scriptCategory": "English-like",
"timeOfDayFormat": "H:mm", "timeOfDayFormat": "H:mm",
"@anteMeridiemAbbreviation": { "notUsed": "Hebrew time format does not use a.m. indicator" }, "@anteMeridiemAbbreviation": { "notUsed": "Hebrew time format does not use a.m. indicator" },
"@postMeridiemAbbreviation": { "notUsed": "Hebrew time format does not use p.m. indicator" }, "@postMeridiemAbbreviation": { "notUsed": "Hebrew time format does not use p.m. indicator" },
......
{ {
"scriptCategory": "English-like",
"timeOfDayFormat": "HH:mm", "timeOfDayFormat": "HH:mm",
"@anteMeridiemAbbreviation": { "notUsed": "Italian time format does not use a.m. indicator" }, "@anteMeridiemAbbreviation": { "notUsed": "Italian time format does not use a.m. indicator" },
"@postMeridiemAbbreviation": { "notUsed": "Italian time format does not use p.m. indicator" }, "@postMeridiemAbbreviation": { "notUsed": "Italian time format does not use p.m. indicator" },
......
{ {
"scriptCategory": "dense",
"timeOfDayFormat": "H:mm", "timeOfDayFormat": "H:mm",
"@anteMeridiemAbbreviation": { "notUsed": "Japanese time format does not use a.m. indicator" }, "@anteMeridiemAbbreviation": { "notUsed": "Japanese time format does not use a.m. indicator" },
"@postMeridiemAbbreviation": { "notUsed": "Japanese time format does not use p.m. indicator" }, "@postMeridiemAbbreviation": { "notUsed": "Japanese time format does not use p.m. indicator" },
......
{ {
"scriptCategory": "tall",
"timeOfDayFormat": "HH:mm", "timeOfDayFormat": "HH:mm",
"@anteMeridiemAbbreviation": { "notUsed": "Pashto time format does not use a.m. indicator" }, "@anteMeridiemAbbreviation": { "notUsed": "Pashto time format does not use a.m. indicator" },
"@postMeridiemAbbreviation": { "notUsed": "Pashto time format does not use p.m. indicator" }, "@postMeridiemAbbreviation": { "notUsed": "Pashto time format does not use p.m. indicator" },
......
{ {
"scriptCategory": "English-like",
"timeOfDayFormat": "HH:mm", "timeOfDayFormat": "HH:mm",
"@anteMeridiemAbbreviation": { "notUsed": "Portuguese time format does not use a.m. indicator" }, "@anteMeridiemAbbreviation": { "notUsed": "Portuguese time format does not use a.m. indicator" },
"@postMeridiemAbbreviation": { "notUsed": "Portuguese time format does not use p.m. indicator" }, "@postMeridiemAbbreviation": { "notUsed": "Portuguese time format does not use p.m. indicator" },
......
{ {
"scriptCategory": "English-like",
"timeOfDayFormat": "H:mm", "timeOfDayFormat": "H:mm",
"@anteMeridiemAbbreviation": { "notUsed": "Russian time format does not use a.m. indicator" }, "@anteMeridiemAbbreviation": { "notUsed": "Russian time format does not use a.m. indicator" },
"@postMeridiemAbbreviation": { "notUsed": "Russian time format does not use p.m. indicator" }, "@postMeridiemAbbreviation": { "notUsed": "Russian time format does not use p.m. indicator" },
......
{ {
"scriptCategory": "tall",
"timeOfDayFormat": "HH:mm", "timeOfDayFormat": "HH:mm",
"@anteMeridiemAbbreviation": { "notUsed": "Sindhi time format does not use a.m. indicator" }, "@anteMeridiemAbbreviation": { "notUsed": "Sindhi time format does not use a.m. indicator" },
"@postMeridiemAbbreviation": { "notUsed": "Sindhi time format does not use p.m. indicator" }, "@postMeridiemAbbreviation": { "notUsed": "Sindhi time format does not use p.m. indicator" },
......
{ {
"scriptCategory": "tall",
"timeOfDayFormat": "h:mm a", "timeOfDayFormat": "h:mm a",
"openAppDrawerTooltip": "کھولیں نیویگیشن مینو", "openAppDrawerTooltip": "کھولیں نیویگیشن مینو",
"backButtonTooltip": "واپس", "backButtonTooltip": "واپس",
......
{ {
"scriptCategory": "dense",
"timeOfDayFormat": "ah:mm", "timeOfDayFormat": "ah:mm",
"openAppDrawerTooltip": "打开导航菜单", "openAppDrawerTooltip": "打开导航菜单",
"backButtonTooltip": "返回", "backButtonTooltip": "返回",
......
...@@ -9,6 +9,7 @@ import 'package:flutter/widgets.dart'; ...@@ -9,6 +9,7 @@ import 'package:flutter/widgets.dart';
import 'package:intl/intl.dart' as intl; import 'package:intl/intl.dart' as intl;
import 'i18n/localizations.dart'; import 'i18n/localizations.dart';
import 'typography.dart';
/// Defines the localized resource values used by the Material widgets. /// Defines the localized resource values used by the Material widgets.
/// ///
...@@ -95,6 +96,19 @@ abstract class MaterialLocalizations { ...@@ -95,6 +96,19 @@ abstract class MaterialLocalizations {
/// each supported layout. /// each supported layout.
TimeOfDayFormat get timeOfDayFormat; TimeOfDayFormat get timeOfDayFormat;
/// Provides geometric text preferences for the current locale.
///
/// This text theme is incomplete. For example, it lacks text color
/// information. This theme must be merged with another text theme that
/// provides the missing values. The text styles provided by this theme have
/// their [TextStyle.inherit] property set to `true`.
///
/// Typically a complete theme is obtained via [Theme.of], which can be
/// localized using the [Localizations] widget.
///
/// See also: https://material.io/guidelines/style/typography.html
TextTheme get localTextGeometry;
/// The `MaterialLocalizations` from the closest [Localizations] instance /// The `MaterialLocalizations` from the closest [Localizations] instance
/// that encloses the given context. /// that encloses the given context.
/// ///
...@@ -287,6 +301,10 @@ class DefaultMaterialLocalizations implements MaterialLocalizations { ...@@ -287,6 +301,10 @@ class DefaultMaterialLocalizations implements MaterialLocalizations {
return _icuTimeOfDayToEnum[icuShortTimePattern]; return _icuTimeOfDayToEnum[icuShortTimePattern];
} }
/// Looks up text geometry defined in [MaterialTextGeometry].
@override
TextTheme get localTextGeometry => MaterialTextGeometry.forScriptCategory(_nameToValue["scriptCategory"]);
/// Creates an object that provides localized resource values for the /// Creates an object that provides localized resource values for the
/// for the widgets of the material library. /// for the widgets of the material library.
/// ///
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'material_localizations.dart';
import 'theme_data.dart'; import 'theme_data.dart';
import 'typography.dart';
export 'theme_data.dart' show Brightness, ThemeData; export 'theme_data.dart' show Brightness, ThemeData;
...@@ -65,6 +67,10 @@ class Theme extends StatelessWidget { ...@@ -65,6 +67,10 @@ class Theme extends StatelessWidget {
/// The data from the closest [Theme] instance that encloses the given /// The data from the closest [Theme] instance that encloses the given
/// context. /// context.
/// ///
/// If the given context is enclosed in a [Localizations] widget providing
/// [MaterialLocalizations], the returned data is localized according to the
/// nearest available [MaterialLocalizations].
///
/// Defaults to [new ThemeData.fallback] if there is no [Theme] in the given /// Defaults to [new ThemeData.fallback] if there is no [Theme] in the given
/// build context. /// build context.
/// ///
...@@ -123,7 +129,11 @@ class Theme extends StatelessWidget { ...@@ -123,7 +129,11 @@ class Theme extends StatelessWidget {
return null; return null;
return inheritedTheme.theme.data; return inheritedTheme.theme.data;
} }
return (inheritedTheme != null) ? inheritedTheme.theme.data : _kFallbackTheme;
final ThemeData colorTheme = (inheritedTheme != null) ? inheritedTheme.theme.data : _kFallbackTheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final TextTheme geometryTheme = localizations?.localTextGeometry ?? MaterialTextGeometry.englishLike;
return ThemeData.localize(colorTheme, geometryTheme);
} }
@override @override
......
...@@ -401,10 +401,13 @@ class Localizations extends StatefulWidget { ...@@ -401,10 +401,13 @@ class Localizations extends StatefulWidget {
return new List<LocalizationsDelegate<dynamic>>.from(scope.localizationsState.widget.delegates); return new List<LocalizationsDelegate<dynamic>>.from(scope.localizationsState.widget.delegates);
} }
/// Returns the 'type' localized resources for the widget tree that /// Returns the localized resources object of the given `type` for the widget
/// corresponds to [BuildContext] `context`. /// tree that corresponds to the given `context`.
///
/// Returns `null` if no resources object of the given `type` exists within
/// the given `context`.
/// ///
/// This method is typically used by a static factory method on the 'type' /// This method is typically used by a static factory method on the `type`
/// class. For example Flutter's MaterialLocalizations class looks up Material /// class. For example Flutter's MaterialLocalizations class looks up Material
/// resources with a method defined like this: /// resources with a method defined like this:
/// ///
...@@ -417,8 +420,7 @@ class Localizations extends StatefulWidget { ...@@ -417,8 +420,7 @@ class Localizations extends StatefulWidget {
assert(context != null); assert(context != null);
assert(type != null); assert(type != null);
final _LocalizationsScope scope = context.inheritFromWidgetOfExactType(_LocalizationsScope); final _LocalizationsScope scope = context.inheritFromWidgetOfExactType(_LocalizationsScope);
assert(scope != null, 'a Localizations ancestor was not found'); return scope?.localizationsState?.resourcesFor<T>(type);
return scope.localizationsState.resourcesFor<T>(type);
} }
@override @override
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
void main() {
testWidgets('$MaterialLocalizations localizes text inside the tree', (WidgetTester tester) async {
await tester.pumpWidget(new MaterialApp(
home: new ListView(
children: <Widget>[
new LocalizationTracker(key: const ValueKey<String>('outer')),
new Localizations(
locale: const Locale('zh', 'CN'),
delegates: <LocalizationsDelegate<dynamic>>[
new _MaterialLocalizationsDelegate(
new DefaultMaterialLocalizations(const Locale('zh', 'CN')),
),
const DefaultWidgetsLocalizationsDelegate(),
],
child: new LocalizationTracker(key: const ValueKey<String>('inner')),
),
],
),
));
final LocalizationTrackerState outerTracker = tester.state(find.byKey(const ValueKey<String>('outer')));
expect(outerTracker.captionFontSize, 12.0);
final LocalizationTrackerState innerTracker = tester.state(find.byKey(const ValueKey<String>('inner')));
expect(innerTracker.captionFontSize, 13.0);
});
}
class LocalizationTracker extends StatefulWidget {
LocalizationTracker({Key key}) : super(key: key);
@override
State<StatefulWidget> createState() => new LocalizationTrackerState();
}
class LocalizationTrackerState extends State<LocalizationTracker> {
double captionFontSize;
@override
Widget build(BuildContext context) {
captionFontSize = Theme.of(context).textTheme.caption.fontSize;
return new Container();
}
}
// Same as _MaterialLocalizationsDelegate in widgets/app.dart
class _MaterialLocalizationsDelegate extends LocalizationsDelegate<MaterialLocalizations> {
const _MaterialLocalizationsDelegate(this.localizations);
final MaterialLocalizations localizations;
@override
Future<MaterialLocalizations> load(Locale locale) {
return new SynchronousFuture<MaterialLocalizations>(localizations);
}
@override
bool shouldReload(_MaterialLocalizationsDelegate old) => false;
}
// Same as _WidgetsLocalizationsDelegate in widgets/app.dart
class DefaultWidgetsLocalizationsDelegate extends LocalizationsDelegate<WidgetsLocalizations> {
const DefaultWidgetsLocalizationsDelegate();
@override
Future<WidgetsLocalizations> load(Locale locale) {
return new SynchronousFuture<WidgetsLocalizations>(new DefaultWidgetsLocalizations(locale));
}
@override
bool shouldReload(DefaultWidgetsLocalizationsDelegate old) => false;
}
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
...@@ -789,8 +789,11 @@ void main() { ...@@ -789,8 +789,11 @@ void main() {
}); });
testWidgets('TextField with default helperStyle', (WidgetTester tester) async { testWidgets('TextField with default helperStyle', (WidgetTester tester) async {
final ThemeData themeData = new ThemeData( final ThemeData themeData = ThemeData.localize(
hintColor: Colors.blue[500], new ThemeData(
hintColor: Colors.blue[500],
),
MaterialTextGeometry.forScriptCategory(MaterialTextGeometry.englishLikeCategory),
); );
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -53,7 +53,9 @@ void main() { ...@@ -53,7 +53,9 @@ void main() {
) )
); );
expect(Theme.of(capturedContext), equals(new ThemeData.fallback())); final dynamic localizedTheme = Theme.of(capturedContext);
expect('${localizedTheme.runtimeType}', '_LocalizedThemeData');
expect(localizedTheme.delegate, equals(new ThemeData.fallback()));
expect(Theme.of(capturedContext, shadowThemeOnly: true), isNull); expect(Theme.of(capturedContext, shadowThemeOnly: true), isNull);
}); });
......
...@@ -30,23 +30,27 @@ void main() { ...@@ -30,23 +30,27 @@ void main() {
test('Typography on iOS defaults to the correct SF font family based on size', () { test('Typography on iOS defaults to the correct SF font family based on size', () {
// Ref: https://developer.apple.com/ios/human-interface-guidelines/visual-design/typography/ // Ref: https://developer.apple.com/ios/human-interface-guidelines/visual-design/typography/
final Matcher hasCorrectFont = predicate((TextStyle s) { final Matcher isDisplayFont = predicate((TextStyle s) {
return s.fontFamily == (s.fontSize <= 19.0 ? '.SF UI Text' : '.SF UI Display'); return s.fontFamily == '.SF UI Display';
}, 'Uses SF Display font for font sizes over 19.0, otherwise SF Text font'); }, 'Uses SF Display font');
final Matcher isTextFont = predicate((TextStyle s) {
return s.fontFamily == '.SF UI Text';
}, 'Uses SF Text font');
final Typography typography = new Typography(platform: TargetPlatform.iOS); final Typography typography = new Typography(platform: TargetPlatform.iOS);
for (TextTheme textTheme in <TextTheme>[typography.black, typography.white]) { for (TextTheme textTheme in <TextTheme>[typography.black, typography.white]) {
expect(textTheme.display4, hasCorrectFont); expect(textTheme.display4, isDisplayFont);
expect(textTheme.display3, hasCorrectFont); expect(textTheme.display3, isDisplayFont);
expect(textTheme.display2, hasCorrectFont); expect(textTheme.display2, isDisplayFont);
expect(textTheme.display1, hasCorrectFont); expect(textTheme.display1, isDisplayFont);
expect(textTheme.headline, hasCorrectFont); expect(textTheme.headline, isDisplayFont);
expect(textTheme.title, hasCorrectFont); expect(textTheme.title, isDisplayFont);
expect(textTheme.subhead, hasCorrectFont); expect(textTheme.subhead, isTextFont);
expect(textTheme.body2, hasCorrectFont); expect(textTheme.body2, isTextFont);
expect(textTheme.body1, hasCorrectFont); expect(textTheme.body1, isTextFont);
expect(textTheme.caption, hasCorrectFont); expect(textTheme.caption, isTextFont);
expect(textTheme.button, hasCorrectFont); expect(textTheme.button, isTextFont);
} }
}); });
} }
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