Unverified Commit 3b309bda authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Add a localization for counter text, separate into own semantic node (#21029)

parent 1c2d3f32
......@@ -1813,10 +1813,14 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
);
final Widget counter = decoration.counterText == null ? null :
new Text(
decoration.counterText,
style: _getHelperStyle(themeData).merge(decoration.counterStyle),
overflow: TextOverflow.ellipsis,
new Semantics(
container: true,
child: new Text(
decoration.counterText,
style: _getHelperStyle(themeData).merge(decoration.counterStyle),
overflow: TextOverflow.ellipsis,
semanticsLabel: decoration.semanticCounterText,
),
);
// The _Decoration widget and _RenderDecoration assume that contentPadding
......@@ -1940,6 +1944,7 @@ class InputDecoration {
this.enabledBorder,
this.border,
this.enabled = true,
this.semanticCounterText,
}) : assert(enabled != null),
assert(!(prefix != null && prefixText != null), 'Declaring both prefix and prefixText is not allowed'),
assert(!(suffix != null && suffixText != null), 'Declaring both suffix and suffixText is not allowed'),
......@@ -1983,7 +1988,8 @@ class InputDecoration {
focusedBorder = null,
focusedErrorBorder = null,
disabledBorder = null,
enabledBorder = null;
enabledBorder = null,
semanticCounterText = null;
/// An icon to show before the input field and outside of the decoration's
/// container.
......@@ -2197,6 +2203,8 @@ class InputDecoration {
///
/// Rendered using [counterStyle]. Uses [helperStyle] if [counterStyle] is
/// null.
///
/// The semantic label can be replaced by providing a [semanticCounterText].
final String counterText;
/// The style to use for the [counterText].
......@@ -2380,6 +2388,13 @@ class InputDecoration {
/// This property is true by default.
final bool enabled;
/// A semantic label for the [counterText].
///
/// Defaults to null.
///
/// If provided, this replaces the semantic label of the [counterText].
final String semanticCounterText;
/// Creates a copy of this input decoration with the given fields replaced
/// by the new values.
///
......@@ -2416,6 +2431,7 @@ class InputDecoration {
InputBorder enabledBorder,
InputBorder border,
bool enabled,
String semanticCounterText,
}) {
return new InputDecoration(
icon: icon ?? this.icon,
......@@ -2449,6 +2465,7 @@ class InputDecoration {
enabledBorder: enabledBorder ?? this.enabledBorder,
border: border ?? this.border,
enabled: enabled ?? this.enabled,
semanticCounterText: semanticCounterText ?? this.semanticCounterText,
);
}
......@@ -2518,7 +2535,8 @@ class InputDecoration {
&& typedOther.disabledBorder == disabledBorder
&& typedOther.enabledBorder == enabledBorder
&& typedOther.border == border
&& typedOther.enabled == enabled;
&& typedOther.enabled == enabled
&& typedOther.semanticCounterText == semanticCounterText;
}
@override
......@@ -2565,6 +2583,7 @@ class InputDecoration {
enabledBorder,
border,
enabled,
semanticCounterText,
),
);
}
......@@ -2630,6 +2649,8 @@ class InputDecoration {
description.add('border: $border');
if (!enabled)
description.add('enabled: false');
if (semanticCounterText != null)
description.add('semanticCounterText: $semanticCounterText');
return 'InputDecoration(${description.join(', ')})';
}
}
......
......@@ -307,6 +307,9 @@ abstract class MaterialLocalizations {
/// The semantics hint to describe the tap action on a collapsed [ExpandIcon].
String get collapsedIconTapHint => 'Expand';
/// The label for the [TextField]'s character counter.
String remainingTextFieldCharacterCount(int remaining);
/// The `MaterialLocalizations` from the closest [Localizations] instance
/// that encloses the given context.
///
......@@ -709,4 +712,16 @@ class DefaultMaterialLocalizations implements MaterialLocalizations {
///
/// [MaterialApp] automatically adds this value to [MaterialApp.localizationsDelegates].
static const LocalizationsDelegate<MaterialLocalizations> delegate = _MaterialLocalizationsDelegate();
@override
String remainingTextFieldCharacterCount(int remaining) {
switch (remaining) {
case 0:
return 'No characters remaining';
case 1:
return '1 character remaining';
default:
return '$remaining characters remaining';
}
}
}
......@@ -14,6 +14,7 @@ import 'feedback.dart';
import 'ink_well.dart' show InteractiveInkFeature;
import 'input_decorator.dart';
import 'material.dart';
import 'material_localizations.dart';
import 'text_selection.dart';
import 'theme.dart';
......@@ -379,6 +380,7 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi
&& widget.decoration.counterText == null;
InputDecoration _getEffectiveDecoration() {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final InputDecoration effectiveDecoration = (widget.decoration ?? const InputDecoration())
.applyDefaults(Theme.of(context).inputDecorationTheme)
.copyWith(
......@@ -388,7 +390,10 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi
if (!needsCounter)
return effectiveDecoration;
final String counterText = '${_effectiveController.value.text.runes.length}/${widget.maxLength}';
final int currentLength = _effectiveController.value.text.runes.length;
final String counterText = '$currentLength/${widget.maxLength}';
final int remaining = (widget.maxLength - currentLength).clamp(0, widget.maxLength);
final String semanticCounterText = localizations.remainingTextFieldCharacterCount(remaining);
if (_effectiveController.value.text.runes.length > widget.maxLength) {
final ThemeData themeData = Theme.of(context);
return effectiveDecoration.copyWith(
......@@ -396,9 +401,13 @@ class _TextFieldState extends State<TextField> with AutomaticKeepAliveClientMixi
counterStyle: effectiveDecoration.errorStyle
?? themeData.textTheme.caption.copyWith(color: themeData.errorColor),
counterText: counterText,
semanticCounterText: semanticCounterText,
);
}
return effectiveDecoration.copyWith(counterText: counterText);
return effectiveDecoration.copyWith(
counterText: counterText,
semanticCounterText: semanticCounterText,
);
}
@override
......
......@@ -2580,11 +2580,11 @@ void main() {
child: new TextField(
key: key,
controller: controller,
maxLength: 10,
decoration: const InputDecoration(
labelText: 'label',
hintText: 'hint',
helperText: 'helper',
counterText: 'counter',
),
),
),
......@@ -2593,7 +2593,7 @@ void main() {
expect(semantics, hasSemantics(new TestSemantics.root(
children: <TestSemantics>[
new TestSemantics.rootChild(
label: 'label\nhelper\ncounter',
label: 'label\nhelper',
id: 1,
textDirection: TextDirection.ltr,
actions: <SemanticsAction>[
......@@ -2602,6 +2602,13 @@ void main() {
flags: <SemanticsFlag>[
SemanticsFlag.isTextField,
],
children: <TestSemantics>[
new TestSemantics(
id: 2,
label: '10 characters remaining',
textDirection: TextDirection.ltr,
),
],
),
],
), ignoreTransform: true, ignoreRect: true));
......@@ -2612,7 +2619,7 @@ void main() {
expect(semantics, hasSemantics(new TestSemantics.root(
children: <TestSemantics>[
new TestSemantics.rootChild(
label: 'hint\nhelper\ncounter',
label: 'hint\nhelper',
id: 1,
textDirection: TextDirection.ltr,
textSelection: const TextSelection(baseOffset: 0, extentOffset: 0),
......@@ -2625,6 +2632,13 @@ void main() {
SemanticsFlag.isTextField,
SemanticsFlag.isFocused,
],
children: <TestSemantics>[
new TestSemantics(
id: 2,
label: '10 characters remaining',
textDirection: TextDirection.ltr,
),
],
),
],
), ignoreTransform: true, ignoreRect: true));
......@@ -2634,4 +2648,49 @@ void main() {
semantics.dispose();
});
testWidgets('InputDecoration counterText can have a semanticCounterText', (WidgetTester tester) async {
final SemanticsTester semantics = new SemanticsTester(tester);
final TextEditingController controller = new TextEditingController();
final Key key = new UniqueKey();
await tester.pumpWidget(
overlay(
child: new TextField(
key: key,
controller: controller,
decoration: const InputDecoration(
labelText: 'label',
hintText: 'hint',
helperText: 'helper',
counterText: '0/10',
semanticCounterText: '0 out of 10',
),
),
),
);
expect(semantics, hasSemantics(new TestSemantics.root(
children: <TestSemantics>[
new TestSemantics.rootChild(
label: 'label\nhelper',
id: 1,
textDirection: TextDirection.ltr,
actions: <SemanticsAction>[
SemanticsAction.tap,
],
flags: <SemanticsFlag>[
SemanticsFlag.isTextField,
],
children: <TestSemantics>[
new TestSemantics(
label: '0 out of 10',
textDirection: TextDirection.ltr,
),
],
),
],
), ignoreTransform: true, ignoreRect: true, ignoreId: true));
semantics.dispose();
});
}
......@@ -51,5 +51,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -48,5 +48,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
\ No newline at end of file
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -49,5 +49,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -48,5 +48,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -245,5 +245,13 @@
"collapsedIconTapHint": "Expand",
"@collapsedIconTapHint": {
"description": "The verb which describes what happens when a collapsed ExpandIcon toggle button is pressed. This is used by TalkBack on Android to replace the default hint on the accessibility action. The verb will be concatenated with a prefix string which describes how to perform the action, which by default is 'double tap to activate'. In the case of US english, this would be 'double tap to expand.' The exact phrasing of the hint will vary based on locale"
},
"remainingTextFieldCharacterCountZero": "No characters remaining",
"remainingTextFieldCharacterCountOne": "1 character remaining",
"remainingTextFieldCharacterCountOther": "$remainingCount characters remaining",
"@remainingTextFieldCharacterCount": {
"description": "The label for the TextField's character counter. remainingCharacters is a integer representing how many more characters the user can type into the text field before using up a given budget. All values are greater than or equal to zero.",
"plural": "remainingCount"
}
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "Move left",
"reorderItemRight": "Move right",
"expandedIconTapHint": "Collapse",
"collapsedIconTapHint": "Expand"
"collapsedIconTapHint": "Expand",
"remainingTextFieldCharacterCountZero": "No characters remaining",
"remainingTextFieldCharacterCountOne": "1 character remaining",
"remainingTextFieldCharacterCountOther": "$remainingCount characters remaining"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "Move left",
"reorderItemRight": "Move right",
"expandedIconTapHint": "Collapse",
"collapsedIconTapHint": "Expand"
"collapsedIconTapHint": "Expand",
"remainingTextFieldCharacterCountZero": "No characters remaining",
"remainingTextFieldCharacterCountOne": "1 character remaining",
"remainingTextFieldCharacterCountOther": "$remainingCount characters remaining"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "Move left",
"reorderItemRight": "Move right",
"expandedIconTapHint": "Collapse",
"collapsedIconTapHint": "Expand"
"collapsedIconTapHint": "Expand",
"remainingTextFieldCharacterCountZero": "No characters remaining",
"remainingTextFieldCharacterCountOne": "1 character remaining",
"remainingTextFieldCharacterCountOther": "$remainingCount characters remaining"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "Move left",
"reorderItemRight": "Move right",
"expandedIconTapHint": "Collapse",
"collapsedIconTapHint": "Expand"
"collapsedIconTapHint": "Expand",
"remainingTextFieldCharacterCountZero": "No characters remaining",
"remainingTextFieldCharacterCountOne": "1 character remaining",
"remainingTextFieldCharacterCountOther": "$remainingCount characters remaining"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "Move left",
"reorderItemRight": "Move right",
"expandedIconTapHint": "Collapse",
"collapsedIconTapHint": "Expand"
"collapsedIconTapHint": "Expand",
"remainingTextFieldCharacterCountZero": "No characters remaining",
"remainingTextFieldCharacterCountOne": "1 character remaining",
"remainingTextFieldCharacterCountOther": "$remainingCount characters remaining"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "Move left",
"reorderItemRight": "Move right",
"expandedIconTapHint": "Collapse",
"collapsedIconTapHint": "Expand"
"collapsedIconTapHint": "Expand",
"remainingTextFieldCharacterCountZero": "No characters remaining",
"remainingTextFieldCharacterCountOne": "1 character remaining",
"remainingTextFieldCharacterCountOther": "$remainingCount characters remaining"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "Move left",
"reorderItemRight": "Move right",
"expandedIconTapHint": "Collapse",
"collapsedIconTapHint": "Expand"
"collapsedIconTapHint": "Expand",
"remainingTextFieldCharacterCountZero": "No characters remaining",
"remainingTextFieldCharacterCountOne": "1 character remaining",
"remainingTextFieldCharacterCountOther": "$remainingCount characters remaining"
}
......@@ -48,5 +48,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -41,5 +41,8 @@
"alertDialogLabel": "Alerta",
"searchFieldLabel": "Buscar",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -48,5 +48,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -49,5 +49,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -48,5 +48,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -49,5 +49,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -48,5 +48,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -48,5 +48,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -49,5 +49,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -46,5 +46,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -49,5 +49,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -49,5 +49,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -50,5 +50,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -49,5 +49,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -49,5 +49,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -48,5 +48,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -48,5 +48,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -49,5 +49,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -47,5 +47,8 @@
"reorderItemLeft": "TBD",
"reorderItemRight": "TBD",
"expandedIconTapHint": "TBD",
"collapsedIconTapHint": "TBD"
"collapsedIconTapHint": "TBD",
"remainingTextFieldCharacterCountZero": "TBD",
"remainingTextFieldCharacterCountOne": "TBD",
"remainingTextFieldCharacterCountOther": "TBD"
}
......@@ -393,6 +393,56 @@ abstract class GlobalMaterialLocalizations implements MaterialLocalizations {
return timeOfDayFormatRaw;
}
/// The "zero" form of [remainingTextFieldCharacterCount].
///
/// This form is required.
///
/// See also:
///
/// * [Intl.plural], to which this form is passed.
/// * [remainingTextFieldCharacterCountZero], the "zero" form
/// * [remainingTextFieldCharacterCountOne], the "one" form
/// * [remainingTextFieldCharacterCountOther], the "other" form
@protected
String get remainingTextFieldCharacterCountZero;
/// The "one" form of [remainingTextFieldCharacterCount].
///
/// This form is optional.
///
/// See also:
///
/// * [Intl.plural], to which this form is passed.
/// * [remainingTextFieldCharacterCountZero], the "zero" form
/// * [remainingTextFieldCharacterCountOne], the "one" form
/// * [remainingTextFieldCharacterCountOther], the "other" form
@protected
String get remainingTextFieldCharacterCountOne => null;
/// The "other" form of [remainingTextFieldCharacterCount].
///
/// This form is required.
///
/// See also:
///
/// * [Intl.plural], to which this form is passed.
/// * [remainingTextFieldCharacterCountZero], the "zero" form
/// * [remainingTextFieldCharacterCountOne], the "one" form
/// * [remainingTextFieldCharacterCountOther], the "other" form
@protected
String get remainingTextFieldCharacterCountOther;
@override
String remainingTextFieldCharacterCount(int remainingCount) {
return intl.Intl.pluralLogic(
remainingCount,
zero: remainingTextFieldCharacterCountZero,
one: remainingTextFieldCharacterCountOne,
other: remainingTextFieldCharacterCountOther,
locale: _localeName,
).replaceFirst(r'$remainingCount', formatDecimal(remainingCount));
}
/// The script category used by [localTextGeometry]. Must be one of the strings
/// declared in [MaterialTextGeometry].
//
......
......@@ -41,6 +41,13 @@ void main() {
expect(localizations.collapsedIconTapHint, isNotNull);
expect(localizations.expandedIconTapHint, isNotNull);
expect(localizations.remainingTextFieldCharacterCount(0), isNotNull);
expect(localizations.remainingTextFieldCharacterCount(1), isNotNull);
expect(localizations.remainingTextFieldCharacterCount(10), isNotNull);
expect(localizations.remainingTextFieldCharacterCount(0), isNot(contains(r'$remainingCount')));
expect(localizations.remainingTextFieldCharacterCount(1), isNot(contains(r'$remainingCount')));
expect(localizations.remainingTextFieldCharacterCount(10), isNot(contains(r'$remainingCount')));
expect(localizations.aboutListTileTitle('FOO'), isNotNull);
expect(localizations.aboutListTileTitle('FOO'), contains('FOO'));
......
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