feat(Tooltip): pass the default text style down the tree (#163259)

Modify the tooltip's DefaultTextStyle to use the actual default text
style picked to fit the current theme and platform instead of hardcoding
the bodyMedium text style.

Closes: #163255

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
Kamil Szczęk 2025-03-04 23:15:19 +01:00 committed by GitHub
parent 7e2b4e8f86
commit 612d39e0e6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 65 additions and 11 deletions

View File

@ -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<double> 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(

View File

@ -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<TooltipState> tooltipKey = GlobalKey<TooltipState>();
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>(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<TooltipState> tooltipKey = GlobalKey<TooltipState>();
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<Text>(find.text(tooltipText)).style!;
final Finder defaultTextStyleFinder = find.ancestor(
of: find.text(tooltipText),
matching: find.byType(DefaultTextStyle),
);
final TextStyle defaultTextStyle =
tester.widget<DefaultTextStyle>(defaultTextStyleFinder.first).style;
expect(textStyle, same(expectedTextStyle));
expect(defaultTextStyle, same(expectedTextStyle));
});
}
Future<void> setWidgetForTooltipMode(