Allow specifying and a11y label for Icon widget (#12475)
* Allow specifying and a11y label for Icon widget
This commit is contained in:
parent
c38b843460
commit
5e595d12e4
@ -35,7 +35,8 @@ class Icon extends StatelessWidget {
|
|||||||
const Icon(this.icon, {
|
const Icon(this.icon, {
|
||||||
Key key,
|
Key key,
|
||||||
this.size,
|
this.size,
|
||||||
this.color
|
this.color,
|
||||||
|
this.semanticLabel,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
/// The icon to display. The available icons are described in [Icons].
|
/// The icon to display. The available icons are described in [Icons].
|
||||||
@ -83,6 +84,14 @@ class Icon extends StatelessWidget {
|
|||||||
/// ```
|
/// ```
|
||||||
final Color color;
|
final Color color;
|
||||||
|
|
||||||
|
/// Semantic label for the icon.
|
||||||
|
///
|
||||||
|
/// This would be read out in accessibility modes (e.g TalkBack/VoiceOver).
|
||||||
|
/// This label does not show in the UI.
|
||||||
|
///
|
||||||
|
/// See [Semantics.label];
|
||||||
|
final String semanticLabel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
assert(debugCheckHasDirectionality(context));
|
assert(debugCheckHasDirectionality(context));
|
||||||
@ -93,27 +102,29 @@ class Icon extends StatelessWidget {
|
|||||||
final double iconSize = size ?? iconTheme.size;
|
final double iconSize = size ?? iconTheme.size;
|
||||||
|
|
||||||
if (icon == null)
|
if (icon == null)
|
||||||
return new SizedBox(width: iconSize, height: iconSize);
|
return _wrapWithSemantics(new SizedBox(width: iconSize, height: iconSize));
|
||||||
|
|
||||||
final double iconOpacity = iconTheme.opacity;
|
final double iconOpacity = iconTheme.opacity;
|
||||||
Color iconColor = color ?? iconTheme.color;
|
Color iconColor = color ?? iconTheme.color;
|
||||||
if (iconOpacity != 1.0)
|
if (iconOpacity != 1.0)
|
||||||
iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity);
|
iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity);
|
||||||
|
|
||||||
return new ExcludeSemantics(
|
return _wrapWithSemantics(
|
||||||
child: new SizedBox(
|
new ExcludeSemantics(
|
||||||
width: iconSize,
|
child: new SizedBox(
|
||||||
height: iconSize,
|
width: iconSize,
|
||||||
child: new Center(
|
height: iconSize,
|
||||||
child: new RichText(
|
child: new Center(
|
||||||
textDirection: textDirection, // Since we already fetched it for the assert...
|
child: new RichText(
|
||||||
text: new TextSpan(
|
textDirection: textDirection, // Since we already fetched it for the assert...
|
||||||
text: new String.fromCharCode(icon.codePoint),
|
text: new TextSpan(
|
||||||
style: new TextStyle(
|
text: new String.fromCharCode(icon.codePoint),
|
||||||
inherit: false,
|
style: new TextStyle(
|
||||||
color: iconColor,
|
inherit: false,
|
||||||
fontSize: iconSize,
|
color: iconColor,
|
||||||
fontFamily: icon.fontFamily,
|
fontSize: iconSize,
|
||||||
|
fontFamily: icon.fontFamily,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -122,6 +133,17 @@ class Icon extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wraps the widget with a Semantics widget if [semanticLabel] is set.
|
||||||
|
Widget _wrapWithSemantics(Widget widget) {
|
||||||
|
if (semanticLabel == null)
|
||||||
|
return widget;
|
||||||
|
|
||||||
|
return new Semantics(
|
||||||
|
child: widget,
|
||||||
|
label: semanticLabel,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void debugFillProperties(DiagnosticPropertiesBuilder description) {
|
void debugFillProperties(DiagnosticPropertiesBuilder description) {
|
||||||
super.debugFillProperties(description);
|
super.debugFillProperties(description);
|
||||||
|
@ -2,9 +2,12 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
import 'semantics_tester.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Can set opacity for an Icon', (WidgetTester tester) async {
|
testWidgets('Can set opacity for an Icon', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
@ -122,4 +125,40 @@ void main() {
|
|||||||
final RichText richText = tester.firstWidget(find.byType(RichText));
|
final RichText richText = tester.firstWidget(find.byType(RichText));
|
||||||
expect(richText.text.style.fontFamily, equals('Roboto'));
|
expect(richText.text.style.fontFamily, equals('Roboto'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Icon with semantic label', (WidgetTester tester) async {
|
||||||
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
const Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: const Center(
|
||||||
|
child: const Icon(
|
||||||
|
Icons.title,
|
||||||
|
semanticLabel: 'a label',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(semantics, hasSemantics(new TestSemantics.root(label: 'a label')));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Null icon with semantic label', (WidgetTester tester) async {
|
||||||
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
const Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: const Center(
|
||||||
|
child: const Icon(
|
||||||
|
null,
|
||||||
|
semanticLabel: 'a label',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(semantics, hasSemantics(new TestSemantics.root(label: 'a label')));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user