mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Make helper and error text separate widgets, make error and counter live region (#21752)
This commit is contained in:
parent
f8c50ea15f
commit
bf7c27095c
@ -320,32 +320,39 @@ class _HelperErrorState extends State<_HelperError> with SingleTickerProviderSta
|
||||
|
||||
Widget _buildHelper() {
|
||||
assert(widget.helperText != null);
|
||||
return Opacity(
|
||||
opacity: 1.0 - _controller.value,
|
||||
child: Text(
|
||||
widget.helperText,
|
||||
style: widget.helperStyle,
|
||||
textAlign: widget.textAlign,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
return Semantics(
|
||||
container: true,
|
||||
child: Opacity(
|
||||
opacity: 1.0 - _controller.value,
|
||||
child: Text(
|
||||
widget.helperText,
|
||||
style: widget.helperStyle,
|
||||
textAlign: widget.textAlign,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildError() {
|
||||
assert(widget.errorText != null);
|
||||
return Opacity(
|
||||
opacity: _controller.value,
|
||||
child: FractionalTranslation(
|
||||
translation: Tween<Offset>(
|
||||
begin: const Offset(0.0, -0.25),
|
||||
end: const Offset(0.0, 0.0),
|
||||
).evaluate(_controller.view),
|
||||
child: Text(
|
||||
widget.errorText,
|
||||
style: widget.errorStyle,
|
||||
textAlign: widget.textAlign,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: widget.errorMaxLines,
|
||||
return Semantics(
|
||||
container: true,
|
||||
liveRegion: true,
|
||||
child: Opacity(
|
||||
opacity: _controller.value,
|
||||
child: FractionalTranslation(
|
||||
translation: Tween<Offset>(
|
||||
begin: const Offset(0.0, -0.25),
|
||||
end: const Offset(0.0, 0.0),
|
||||
).evaluate(_controller.view),
|
||||
child: Text(
|
||||
widget.errorText,
|
||||
style: widget.errorStyle,
|
||||
textAlign: widget.textAlign,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: widget.errorMaxLines,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -1815,6 +1822,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
final Widget counter = decoration.counterText == null ? null :
|
||||
Semantics(
|
||||
container: true,
|
||||
liveRegion: isFocused,
|
||||
child: Text(
|
||||
decoration.counterText,
|
||||
style: _getHelperStyle(themeData).merge(decoration.counterStyle),
|
||||
|
||||
@ -2843,7 +2843,7 @@ void main() {
|
||||
expect(semantics, hasSemantics(TestSemantics.root(
|
||||
children: <TestSemantics>[
|
||||
TestSemantics.rootChild(
|
||||
label: 'label\nhelper',
|
||||
label: 'label',
|
||||
id: 1,
|
||||
textDirection: TextDirection.ltr,
|
||||
actions: <SemanticsAction>[
|
||||
@ -2855,6 +2855,11 @@ void main() {
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
id: 2,
|
||||
label: 'helper',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
TestSemantics(
|
||||
id: 3,
|
||||
label: '10 characters remaining',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
@ -2869,7 +2874,7 @@ void main() {
|
||||
expect(semantics, hasSemantics(TestSemantics.root(
|
||||
children: <TestSemantics>[
|
||||
TestSemantics.rootChild(
|
||||
label: 'hint\nhelper',
|
||||
label: 'hint',
|
||||
id: 1,
|
||||
textDirection: TextDirection.ltr,
|
||||
textSelection: const TextSelection(baseOffset: 0, extentOffset: 0),
|
||||
@ -2885,7 +2890,15 @@ void main() {
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
id: 2,
|
||||
label: 'helper',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
TestSemantics(
|
||||
id: 3,
|
||||
label: '10 characters remaining',
|
||||
flags: <SemanticsFlag>[
|
||||
SemanticsFlag.isLiveRegion,
|
||||
],
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
@ -2922,8 +2935,7 @@ void main() {
|
||||
expect(semantics, hasSemantics(TestSemantics.root(
|
||||
children: <TestSemantics>[
|
||||
TestSemantics.rootChild(
|
||||
label: 'label\nhelper',
|
||||
id: 1,
|
||||
label: 'label',
|
||||
textDirection: TextDirection.ltr,
|
||||
actions: <SemanticsAction>[
|
||||
SemanticsAction.tap,
|
||||
@ -2932,6 +2944,10 @@ void main() {
|
||||
SemanticsFlag.isTextField,
|
||||
],
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
label: 'helper',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
TestSemantics(
|
||||
label: '0 out of 10',
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2944,6 +2960,52 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('InputDecoration errorText semantics', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
final TextEditingController controller = TextEditingController();
|
||||
final Key key = UniqueKey();
|
||||
|
||||
await tester.pumpWidget(
|
||||
overlay(
|
||||
child: TextField(
|
||||
key: key,
|
||||
controller: controller,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'label',
|
||||
hintText: 'hint',
|
||||
errorText: 'oh no!',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(semantics, hasSemantics(TestSemantics.root(
|
||||
children: <TestSemantics>[
|
||||
TestSemantics.rootChild(
|
||||
label: 'label',
|
||||
textDirection: TextDirection.ltr,
|
||||
actions: <SemanticsAction>[
|
||||
SemanticsAction.tap,
|
||||
],
|
||||
flags: <SemanticsFlag>[
|
||||
SemanticsFlag.isTextField,
|
||||
],
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
label: 'oh no!',
|
||||
flags: <SemanticsFlag>[
|
||||
SemanticsFlag.isLiveRegion,
|
||||
],
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
), ignoreTransform: true, ignoreRect: true, ignoreId: true));
|
||||
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('floating label does not overlap with value at large textScaleFactors', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(text: 'Just some text');
|
||||
await tester.pumpWidget(
|
||||
@ -2964,6 +3026,7 @@ void main() {
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byType(TextField));
|
||||
final Rect labelRect = tester.getRect(find.text('Label'));
|
||||
final Rect fieldRect = tester.getRect(find.text('Just some text'));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user