mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Assorted a11y fixes (#14395)
This commit is contained in:
parent
882be89e4c
commit
b54b576c1a
@ -19,23 +19,27 @@ class SectionCard extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return new DecoratedBox(
|
return new Semantics(
|
||||||
decoration: new BoxDecoration(
|
label: section.title,
|
||||||
gradient: new LinearGradient(
|
button: true,
|
||||||
begin: Alignment.centerLeft,
|
child: new DecoratedBox(
|
||||||
end: Alignment.centerRight,
|
decoration: new BoxDecoration(
|
||||||
colors: <Color>[
|
gradient: new LinearGradient(
|
||||||
section.leftColor,
|
begin: Alignment.centerLeft,
|
||||||
section.rightColor,
|
end: Alignment.centerRight,
|
||||||
],
|
colors: <Color>[
|
||||||
|
section.leftColor,
|
||||||
|
section.rightColor,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: new Image.asset(
|
||||||
|
section.backgroundAsset,
|
||||||
|
package: section.backgroundAssetPackage,
|
||||||
|
color: const Color.fromRGBO(255, 255, 255, 0.075),
|
||||||
|
colorBlendMode: BlendMode.modulate,
|
||||||
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
|
||||||
child: new Image.asset(
|
|
||||||
section.backgroundAsset,
|
|
||||||
package: section.backgroundAssetPackage,
|
|
||||||
color: const Color.fromRGBO(255, 255, 255, 0.075),
|
|
||||||
colorBlendMode: BlendMode.modulate,
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,7 @@ class ExitButton extends StatelessWidget {
|
|||||||
child: const Tooltip(
|
child: const Tooltip(
|
||||||
message: 'Back',
|
message: 'Back',
|
||||||
child: const Text('Exit'),
|
child: const Text('Exit'),
|
||||||
|
excludeFromSemantics: true,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// The demo is on the root navigator.
|
// The demo is on the root navigator.
|
||||||
|
@ -218,14 +218,20 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new IconButton(
|
new IconButton(
|
||||||
icon: const Icon(Icons.thumb_up),
|
icon: const Icon(
|
||||||
|
Icons.thumb_up,
|
||||||
|
semanticLabel: 'Thumbs up',
|
||||||
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() => iconButtonToggle = !iconButtonToggle);
|
setState(() => iconButtonToggle = !iconButtonToggle);
|
||||||
},
|
},
|
||||||
color: iconButtonToggle ? Theme.of(context).primaryColor : null,
|
color: iconButtonToggle ? Theme.of(context).primaryColor : null,
|
||||||
),
|
),
|
||||||
const IconButton(
|
const IconButton(
|
||||||
icon: const Icon(Icons.thumb_up),
|
icon: const Icon(
|
||||||
|
Icons.thumb_up,
|
||||||
|
semanticLabel: 'Thumbs up',
|
||||||
|
),
|
||||||
onPressed: null,
|
onPressed: null,
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -108,21 +108,24 @@ class _IconsDemoCard extends StatelessWidget {
|
|||||||
return new Card(
|
return new Card(
|
||||||
child: new DefaultTextStyle(
|
child: new DefaultTextStyle(
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
child: new Table(
|
child: new Semantics(
|
||||||
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
explicitChildNodes: true,
|
||||||
children: <TableRow> [
|
child: new Table(
|
||||||
new TableRow(
|
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||||
children: <Widget> [
|
children: <TableRow> [
|
||||||
_centeredText('Size'),
|
new TableRow(
|
||||||
_centeredText('Enabled'),
|
children: <Widget> [
|
||||||
_centeredText('Disabled'),
|
_centeredText('Size'),
|
||||||
]
|
_centeredText('Enabled'),
|
||||||
),
|
_centeredText('Disabled'),
|
||||||
_buildIconRow(18.0),
|
]
|
||||||
_buildIconRow(24.0),
|
),
|
||||||
_buildIconRow(36.0),
|
_buildIconRow(18.0),
|
||||||
_buildIconRow(48.0),
|
_buildIconRow(24.0),
|
||||||
],
|
_buildIconRow(36.0),
|
||||||
|
_buildIconRow(48.0),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -76,7 +76,10 @@ class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> {
|
|||||||
floatingActionButton: new FloatingActionButton(
|
floatingActionButton: new FloatingActionButton(
|
||||||
onPressed: _showMessage,
|
onPressed: _showMessage,
|
||||||
backgroundColor: Colors.redAccent,
|
backgroundColor: Colors.redAccent,
|
||||||
child: const Icon(Icons.add)
|
child: const Icon(
|
||||||
|
Icons.add,
|
||||||
|
semanticLabel: 'Add',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
body: new Center(
|
body: new Center(
|
||||||
child: new RaisedButton(
|
child: new RaisedButton(
|
||||||
|
@ -154,7 +154,10 @@ class FullScreenCodeDialogState extends State<FullScreenCodeDialog> {
|
|||||||
return new Scaffold(
|
return new Scaffold(
|
||||||
appBar: new AppBar(
|
appBar: new AppBar(
|
||||||
leading: new IconButton(
|
leading: new IconButton(
|
||||||
icon: const Icon(Icons.clear),
|
icon: const Icon(
|
||||||
|
Icons.clear,
|
||||||
|
semanticLabel: 'Close',
|
||||||
|
),
|
||||||
onPressed: () { Navigator.pop(context); }
|
onPressed: () { Navigator.pop(context); }
|
||||||
),
|
),
|
||||||
title: const Text('Example code')
|
title: const Text('Example code')
|
||||||
|
@ -52,51 +52,54 @@ class _GalleryDrawerHeaderState extends State<GalleryDrawerHeader> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final double systemTopPadding = MediaQuery.of(context).padding.top;
|
final double systemTopPadding = MediaQuery.of(context).padding.top;
|
||||||
|
|
||||||
return new DrawerHeader(
|
return new Semantics(
|
||||||
decoration: new FlutterLogoDecoration(
|
label: 'Flutter',
|
||||||
margin: new EdgeInsets.fromLTRB(12.0, 12.0 + systemTopPadding, 12.0, 12.0),
|
child: new DrawerHeader(
|
||||||
style: _logoHasName ? _logoHorizontal ? FlutterLogoStyle.horizontal
|
decoration: new FlutterLogoDecoration(
|
||||||
: FlutterLogoStyle.stacked
|
margin: new EdgeInsets.fromLTRB(12.0, 12.0 + systemTopPadding, 12.0, 12.0),
|
||||||
: FlutterLogoStyle.markOnly,
|
style: _logoHasName ? _logoHorizontal ? FlutterLogoStyle.horizontal
|
||||||
lightColor: _logoColor.shade400,
|
: FlutterLogoStyle.stacked
|
||||||
darkColor: _logoColor.shade900,
|
: FlutterLogoStyle.markOnly,
|
||||||
textColor: widget.light ? const Color(0xFF616161) : const Color(0xFF9E9E9E),
|
lightColor: _logoColor.shade400,
|
||||||
|
darkColor: _logoColor.shade900,
|
||||||
|
textColor: widget.light ? const Color(0xFF616161) : const Color(0xFF9E9E9E),
|
||||||
|
),
|
||||||
|
duration: const Duration(milliseconds: 750),
|
||||||
|
child: new GestureDetector(
|
||||||
|
onLongPress: () {
|
||||||
|
setState(() {
|
||||||
|
_logoHorizontal = !_logoHorizontal;
|
||||||
|
if (!_logoHasName)
|
||||||
|
_logoHasName = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_logoHasName = !_logoHasName;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onDoubleTap: () {
|
||||||
|
setState(() {
|
||||||
|
final List<MaterialColor> options = <MaterialColor>[];
|
||||||
|
if (_logoColor != Colors.blue)
|
||||||
|
options.addAll(<MaterialColor>[Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue]);
|
||||||
|
if (_logoColor != Colors.amber)
|
||||||
|
options.addAll(<MaterialColor>[Colors.amber, Colors.amber, Colors.amber]);
|
||||||
|
if (_logoColor != Colors.red)
|
||||||
|
options.addAll(<MaterialColor>[Colors.red, Colors.red, Colors.red]);
|
||||||
|
if (_logoColor != Colors.indigo)
|
||||||
|
options.addAll(<MaterialColor>[Colors.indigo, Colors.indigo, Colors.indigo]);
|
||||||
|
if (_logoColor != Colors.pink)
|
||||||
|
options.addAll(<MaterialColor>[Colors.pink]);
|
||||||
|
if (_logoColor != Colors.purple)
|
||||||
|
options.addAll(<MaterialColor>[Colors.purple]);
|
||||||
|
if (_logoColor != Colors.cyan)
|
||||||
|
options.addAll(<MaterialColor>[Colors.cyan]);
|
||||||
|
_logoColor = options[new math.Random().nextInt(options.length)];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
),
|
||||||
),
|
),
|
||||||
duration: const Duration(milliseconds: 750),
|
|
||||||
child: new GestureDetector(
|
|
||||||
onLongPress: () {
|
|
||||||
setState(() {
|
|
||||||
_logoHorizontal = !_logoHorizontal;
|
|
||||||
if (!_logoHasName)
|
|
||||||
_logoHasName = true;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
_logoHasName = !_logoHasName;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onDoubleTap: () {
|
|
||||||
setState(() {
|
|
||||||
final List<MaterialColor> options = <MaterialColor>[];
|
|
||||||
if (_logoColor != Colors.blue)
|
|
||||||
options.addAll(<MaterialColor>[Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue]);
|
|
||||||
if (_logoColor != Colors.amber)
|
|
||||||
options.addAll(<MaterialColor>[Colors.amber, Colors.amber, Colors.amber]);
|
|
||||||
if (_logoColor != Colors.red)
|
|
||||||
options.addAll(<MaterialColor>[Colors.red, Colors.red, Colors.red]);
|
|
||||||
if (_logoColor != Colors.indigo)
|
|
||||||
options.addAll(<MaterialColor>[Colors.indigo, Colors.indigo, Colors.indigo]);
|
|
||||||
if (_logoColor != Colors.pink)
|
|
||||||
options.addAll(<MaterialColor>[Colors.pink]);
|
|
||||||
if (_logoColor != Colors.purple)
|
|
||||||
options.addAll(<MaterialColor>[Colors.purple]);
|
|
||||||
if (_logoColor != Colors.cyan)
|
|
||||||
options.addAll(<MaterialColor>[Colors.cyan]);
|
|
||||||
_logoColor = options[new math.Random().nextInt(options.length)];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,10 +165,14 @@ class _FloatingActionButtonState extends State<FloatingActionButton> {
|
|||||||
child: new Container(
|
child: new Container(
|
||||||
width: widget.mini ? _kSizeMini : _kSize,
|
width: widget.mini ? _kSizeMini : _kSize,
|
||||||
height: widget.mini ? _kSizeMini : _kSize,
|
height: widget.mini ? _kSizeMini : _kSize,
|
||||||
child: new InkWell(
|
child: new Semantics(
|
||||||
onTap: widget.onPressed,
|
button: true,
|
||||||
onHighlightChanged: _handleHighlightChanged,
|
enabled: widget.onPressed != null,
|
||||||
child: result,
|
child: new InkWell(
|
||||||
|
onTap: widget.onPressed,
|
||||||
|
onHighlightChanged: _handleHighlightChanged,
|
||||||
|
child: result,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -193,6 +193,7 @@ class IconButton extends StatelessWidget {
|
|||||||
|
|
||||||
Widget result = new Semantics(
|
Widget result = new Semantics(
|
||||||
button: true,
|
button: true,
|
||||||
|
enabled: onPressed != null,
|
||||||
child: new ConstrainedBox(
|
child: new ConstrainedBox(
|
||||||
constraints: const BoxConstraints(minWidth: _kMinButtonSize, minHeight: _kMinButtonSize),
|
constraints: const BoxConstraints(minWidth: _kMinButtonSize, minHeight: _kMinButtonSize),
|
||||||
child: new Padding(
|
child: new Padding(
|
||||||
|
@ -48,12 +48,14 @@ class Tooltip extends StatefulWidget {
|
|||||||
this.padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
this.padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
this.verticalOffset: 24.0,
|
this.verticalOffset: 24.0,
|
||||||
this.preferBelow: true,
|
this.preferBelow: true,
|
||||||
|
this.excludeFromSemantics: false,
|
||||||
this.child,
|
this.child,
|
||||||
}) : assert(message != null),
|
}) : assert(message != null),
|
||||||
assert(height != null),
|
assert(height != null),
|
||||||
assert(padding != null),
|
assert(padding != null),
|
||||||
assert(verticalOffset != null),
|
assert(verticalOffset != null),
|
||||||
assert(preferBelow != null),
|
assert(preferBelow != null),
|
||||||
|
assert(excludeFromSemantics != null),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
/// The text to display in the tooltip.
|
/// The text to display in the tooltip.
|
||||||
@ -77,6 +79,10 @@ class Tooltip extends StatefulWidget {
|
|||||||
/// direction.
|
/// direction.
|
||||||
final bool preferBelow;
|
final bool preferBelow;
|
||||||
|
|
||||||
|
/// Whether the tooltip's [message] should be excluded from the semantics
|
||||||
|
/// tree.
|
||||||
|
final bool excludeFromSemantics;
|
||||||
|
|
||||||
/// The widget below this widget in the tree.
|
/// The widget below this widget in the tree.
|
||||||
///
|
///
|
||||||
/// {@macro flutter.widgets.child}
|
/// {@macro flutter.widgets.child}
|
||||||
@ -191,7 +197,7 @@ class _TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
|
|||||||
onLongPress: _handleLongPress,
|
onLongPress: _handleLongPress,
|
||||||
excludeFromSemantics: true,
|
excludeFromSemantics: true,
|
||||||
child: new Semantics(
|
child: new Semantics(
|
||||||
label: widget.message,
|
label: widget.excludeFromSemantics ? null : widget.message,
|
||||||
child: widget.child,
|
child: widget.child,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -573,13 +573,21 @@ void _tests() {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
new TestSemantics(
|
new TestSemantics(
|
||||||
flags: <SemanticsFlag>[SemanticsFlag.isButton],
|
flags: <SemanticsFlag>[
|
||||||
|
SemanticsFlag.isButton,
|
||||||
|
SemanticsFlag.hasEnabledState,
|
||||||
|
SemanticsFlag.isEnabled,
|
||||||
|
],
|
||||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||||
label: r'Previous month December 2015',
|
label: r'Previous month December 2015',
|
||||||
textDirection: TextDirection.ltr,
|
textDirection: TextDirection.ltr,
|
||||||
),
|
),
|
||||||
new TestSemantics(
|
new TestSemantics(
|
||||||
flags: <SemanticsFlag>[SemanticsFlag.isButton],
|
flags: <SemanticsFlag>[
|
||||||
|
SemanticsFlag.isButton,
|
||||||
|
SemanticsFlag.hasEnabledState,
|
||||||
|
SemanticsFlag.isEnabled,
|
||||||
|
],
|
||||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||||
label: r'Next month February 2016',
|
label: r'Next month February 2016',
|
||||||
textDirection: TextDirection.ltr,
|
textDirection: TextDirection.ltr,
|
||||||
|
@ -2,9 +2,14 @@
|
|||||||
// 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 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import '../widgets/semantics_tester.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Floating Action Button control test', (WidgetTester tester) async {
|
testWidgets('Floating Action Button control test', (WidgetTester tester) async {
|
||||||
bool didPressButton = false;
|
bool didPressButton = false;
|
||||||
@ -132,4 +137,68 @@ void main() {
|
|||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(tester.takeException().toString(), contains('xyzzy'));
|
expect(tester.takeException().toString(), contains('xyzzy'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Floating Action Button semantics (enabled)', (WidgetTester tester) async {
|
||||||
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
new Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: new Center(
|
||||||
|
child: new FloatingActionButton(
|
||||||
|
onPressed: () { },
|
||||||
|
child: const Icon(Icons.add, semanticLabel: 'Add'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(semantics, hasSemantics(new TestSemantics.root(
|
||||||
|
children: <TestSemantics>[
|
||||||
|
new TestSemantics.rootChild(
|
||||||
|
label: 'Add',
|
||||||
|
flags: <SemanticsFlag>[
|
||||||
|
SemanticsFlag.isButton,
|
||||||
|
SemanticsFlag.hasEnabledState,
|
||||||
|
SemanticsFlag.isEnabled,
|
||||||
|
],
|
||||||
|
actions: <SemanticsAction>[
|
||||||
|
SemanticsAction.tap
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
), ignoreTransform: true, ignoreId: true, ignoreRect: true));
|
||||||
|
|
||||||
|
semantics.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Floating Action Button semantics (disabled)', (WidgetTester tester) async {
|
||||||
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
const Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: const Center(
|
||||||
|
child: const FloatingActionButton(
|
||||||
|
onPressed: null,
|
||||||
|
child: const Icon(Icons.add, semanticLabel: 'Add'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(semantics, hasSemantics(new TestSemantics.root(
|
||||||
|
children: <TestSemantics>[
|
||||||
|
new TestSemantics.rootChild(
|
||||||
|
label: 'Add',
|
||||||
|
flags: <SemanticsFlag>[
|
||||||
|
SemanticsFlag.isButton,
|
||||||
|
SemanticsFlag.hasEnabledState,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
), ignoreTransform: true, ignoreId: true, ignoreRect: true));
|
||||||
|
|
||||||
|
semantics.dispose();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ void main() {
|
|||||||
await gesture.up();
|
await gesture.up();
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('IconButton Semantics', (WidgetTester tester) async {
|
testWidgets('IconButton Semantics (enabled)', (WidgetTester tester) async {
|
||||||
final SemanticsTester semantics = new SemanticsTester(tester);
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
@ -291,8 +291,14 @@ void main() {
|
|||||||
children: <TestSemantics>[
|
children: <TestSemantics>[
|
||||||
new TestSemantics.rootChild(
|
new TestSemantics.rootChild(
|
||||||
rect: new Rect.fromLTRB(0.0, 0.0, 48.0, 48.0),
|
rect: new Rect.fromLTRB(0.0, 0.0, 48.0, 48.0),
|
||||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
actions: <SemanticsAction>[
|
||||||
flags: <SemanticsFlag>[SemanticsFlag.isButton],
|
SemanticsAction.tap
|
||||||
|
],
|
||||||
|
flags: <SemanticsFlag>[
|
||||||
|
SemanticsFlag.hasEnabledState,
|
||||||
|
SemanticsFlag.isEnabled,
|
||||||
|
SemanticsFlag.isButton
|
||||||
|
],
|
||||||
label: 'link',
|
label: 'link',
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -300,6 +306,34 @@ void main() {
|
|||||||
|
|
||||||
semantics.dispose();
|
semantics.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('IconButton Semantics (disabled)', (WidgetTester tester) async {
|
||||||
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
wrap(
|
||||||
|
child: const IconButton(
|
||||||
|
onPressed: null,
|
||||||
|
icon: const Icon(Icons.link, semanticLabel: 'link'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(semantics, hasSemantics(new TestSemantics.root(
|
||||||
|
children: <TestSemantics>[
|
||||||
|
new TestSemantics.rootChild(
|
||||||
|
rect: new Rect.fromLTRB(0.0, 0.0, 48.0, 48.0),
|
||||||
|
flags: <SemanticsFlag>[
|
||||||
|
SemanticsFlag.hasEnabledState,
|
||||||
|
SemanticsFlag.isButton
|
||||||
|
],
|
||||||
|
label: 'link',
|
||||||
|
)
|
||||||
|
]
|
||||||
|
), ignoreId: true, ignoreTransform: true));
|
||||||
|
|
||||||
|
semantics.dispose();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget wrap({ Widget child }) {
|
Widget wrap({ Widget child }) {
|
||||||
|
@ -602,4 +602,57 @@ void main() {
|
|||||||
feedback.dispose();
|
feedback.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Semantics included', (WidgetTester tester) async {
|
||||||
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
new MaterialApp(
|
||||||
|
home: const Center(
|
||||||
|
child: const Tooltip(
|
||||||
|
message: 'Foo',
|
||||||
|
child: const Text('Bar'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(semantics, hasSemantics(new TestSemantics.root(
|
||||||
|
children: <TestSemantics>[
|
||||||
|
new TestSemantics.rootChild(
|
||||||
|
label: 'Foo\nBar',
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
), ignoreRect: true, ignoreId: true, ignoreTransform: true));
|
||||||
|
|
||||||
|
semantics.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Semantics excluded', (WidgetTester tester) async {
|
||||||
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
new MaterialApp(
|
||||||
|
home: const Center(
|
||||||
|
child: const Tooltip(
|
||||||
|
message: 'Foo',
|
||||||
|
child: const Text('Bar'),
|
||||||
|
excludeFromSemantics: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(semantics, hasSemantics(new TestSemantics.root(
|
||||||
|
children: <TestSemantics>[
|
||||||
|
new TestSemantics.rootChild(
|
||||||
|
label: 'Bar',
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
), ignoreRect: true, ignoreId: true, ignoreTransform: true));
|
||||||
|
|
||||||
|
semantics.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user