diff --git a/packages/flutter/lib/src/material/tooltip.dart b/packages/flutter/lib/src/material/tooltip.dart index 5b60bd66a0..6a9f551128 100644 --- a/packages/flutter/lib/src/material/tooltip.dart +++ b/packages/flutter/lib/src/material/tooltip.dart @@ -191,12 +191,6 @@ class Tooltip extends StatefulWidget { }) : assert( (message == null) != (richMessage == null), 'Either `message` or `richMessage` must be specified', - ), - assert( - richMessage == null || textStyle == null, - 'If `richMessage` is specified, `textStyle` will have no effect. ' - 'If you wish to provide a `textStyle` for a rich tooltip, add the ' - '`textStyle` directly to the `richMessage` InlineSpan.', ); /// The text to display in the tooltip. @@ -978,8 +972,8 @@ class _TooltipOverlay extends StatelessWidget { this.padding, this.margin, this.decoration, - this.textStyle, - this.textAlign, + required this.textStyle, + required this.textAlign, required this.animation, required this.target, required this.verticalOffset, @@ -994,8 +988,8 @@ class _TooltipOverlay extends StatelessWidget { final EdgeInsetsGeometry? padding; final EdgeInsetsGeometry? margin; final Decoration? decoration; - final TextStyle? textStyle; - final TextAlign? textAlign; + final TextStyle textStyle; + final TextAlign textAlign; final Animation animation; final Offset target; final double verticalOffset; @@ -1011,7 +1005,8 @@ class _TooltipOverlay extends StatelessWidget { child: ConstrainedBox( constraints: BoxConstraints(minHeight: height), child: DefaultTextStyle( - style: Theme.of(context).textTheme.bodyMedium!, + style: textStyle, + textAlign: textAlign, child: Semantics( container: true, child: Container( diff --git a/packages/flutter/test/material/tooltip_test.dart b/packages/flutter/test/material/tooltip_test.dart index 83a33b1fe5..25ec32cb8b 100644 --- a/packages/flutter/test/material/tooltip_test.dart +++ b/packages/flutter/test/material/tooltip_test.dart @@ -3390,6 +3390,65 @@ void main() { await gesture.removePointer(); }); + + testWidgets('Tooltip should pass its default text style down to widget spans', ( + WidgetTester tester, + ) async { + final GlobalKey tooltipKey = GlobalKey(); + await tester.pumpWidget( + MaterialApp( + home: Tooltip( + key: tooltipKey, + richMessage: const WidgetSpan(child: Text(tooltipText)), + child: Container(width: 100.0, height: 100.0, color: Colors.green[500]), + ), + ), + ); + tooltipKey.currentState?.ensureTooltipVisible(); + await tester.pump(const Duration(seconds: 2)); + + final Finder defaultTextStyle = find.ancestor( + of: find.text(tooltipText), + matching: find.byType(DefaultTextStyle), + ); + final DefaultTextStyle textStyle = tester.widget(defaultTextStyle.first); + expect(textStyle.style.color, Colors.white); + expect(textStyle.style.fontFamily, 'Roboto'); + expect(textStyle.style.decoration, TextDecoration.none); + expect( + textStyle.style.debugLabel, + '((englishLike bodyMedium 2021).merge((blackMountainView bodyMedium).apply)).copyWith', + ); + }); + + testWidgets('Tooltip should apply provided text style to rich messages', ( + WidgetTester tester, + ) async { + final GlobalKey tooltipKey = GlobalKey(); + const TextStyle expectedTextStyle = TextStyle(color: Colors.orange); + await tester.pumpWidget( + MaterialApp( + home: Tooltip( + key: tooltipKey, + richMessage: const TextSpan(text: tooltipText), + textStyle: expectedTextStyle, + child: Container(width: 100.0, height: 100.0, color: Colors.green[500]), + ), + ), + ); + tooltipKey.currentState?.ensureTooltipVisible(); + await tester.pump(const Duration(seconds: 2)); + + final TextStyle textStyle = tester.widget(find.text(tooltipText)).style!; + final Finder defaultTextStyleFinder = find.ancestor( + of: find.text(tooltipText), + matching: find.byType(DefaultTextStyle), + ); + final TextStyle defaultTextStyle = + tester.widget(defaultTextStyleFinder.first).style; + expect(textStyle, same(expectedTextStyle)); + expect(defaultTextStyle, same(expectedTextStyle)); + }); } Future setWidgetForTooltipMode(