Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/material_ui/lib/src/tooltip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,14 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
ignorePointer: widget.ignorePointer ?? widget.message != null,
child: effectiveChild,
);
} else {
// A TooltipVisibility ancestor has disabled the tooltip overlay and its
// triggers, but the message should still be reported to assistive
// technology, matching what RawTooltip does when the tooltip is enabled.
effectiveChild = Semantics(
tooltip: excludeFromSemantics ? null : _tooltipMessage,
child: effectiveChild,
);
}
Comment on lines +569 to 577

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

When excludeFromSemantics is true, wrapping the child in a Semantics widget with a null tooltip is redundant and adds unnecessary overhead to the widget tree. We can avoid building the Semantics widget entirely in this case by changing the else block to an else if (!excludeFromSemantics) block.

    } else if (!excludeFromSemantics) {
      // A TooltipVisibility ancestor has disabled the tooltip overlay and its
      // triggers, but the message should still be reported to assistive
      // technology, matching what RawTooltip does when the tooltip is enabled.
      effectiveChild = Semantics(
        tooltip: _tooltipMessage,
        child: effectiveChild,
      );
    }


return effectiveChild;
Expand Down
50 changes: 50 additions & 0 deletions packages/material_ui/test/tooltip_visibility_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,56 @@ void main() {
await tester.pump();
expect(find.text(tooltipText), findsOneWidget);
});

testWidgets('Tooltip contributes semantics when in TooltipVisibility with visible = false', (
WidgetTester tester,
) async {
// Regression test for https://github.com/flutter/flutter/issues/189062.
final SemanticsHandle handle = tester.ensureSemantics();
const childKey = Key('child');

await tester.pumpWidget(
const MaterialApp(
home: TooltipVisibility(
visible: false,
child: Tooltip(
message: tooltipText,
child: SizedBox(key: childKey, width: 100.0, height: 100.0),
),
),
),
);

expect(tester.getSemantics(find.byKey(childKey)), containsSemantics(tooltip: tooltipText));
handle.dispose();
});

testWidgets(
'Tooltip in TooltipVisibility with visible = false contributes no semantics when excluded',
(WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
const childKey = Key('child');

await tester.pumpWidget(
const MaterialApp(
home: TooltipVisibility(
visible: false,
child: Tooltip(
message: tooltipText,
excludeFromSemantics: true,
child: SizedBox(key: childKey, width: 100.0, height: 100.0),
),
),
),
);

expect(
tester.getSemantics(find.byKey(childKey)),
isNot(containsSemantics(tooltip: tooltipText)),
);
handle.dispose();
},
);
}

Future<void> setWidgetForTooltipMode(
Expand Down