Skip to content
Merged
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [next]

- fix: `Tooltip` now correctly uses constructor-given style ((#1321)[https://github.com/bdlukaa/fluent_ui/pull/1321))

## 4.15.1

- fix: `NavigationView` auto display mode no longer shows a brief overlay when resizing from minimal to compact mode ([#1316](https://github.com/bdlukaa/fluent_ui/pull/1316))
Expand Down
31 changes: 20 additions & 11 deletions lib/src/controls/flyouts/tooltip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,15 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
void didChangeDependencies() {
super.didChangeDependencies();
_visible = TooltipVisibility.of(context);
_tooltipTheme = TooltipTheme.of(context);
_cacheTooltipTheme(context);
}

@override
void didUpdateWidget(Tooltip oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.style != widget.style) {
_cacheTooltipTheme(context);
}
Comment on lines +314 to +316
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

While updating the cached theme when the widget style changes is correct, if a tooltip is currently waiting to be shown (i.e., _showTimer is active), it will still use the old waitDuration. For a more consistent experience, consider canceling and restarting the timer if the waitDuration changes during didUpdateWidget.

}

void _handleStatusChanged(AnimationStatus status) {
Expand Down Expand Up @@ -438,9 +446,6 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
);
}

// Merge widget style with cached theme
final tooltipTheme = _tooltipTheme.merge(widget.style);

// Compute default decoration based on current theme
final theme = FluentTheme.of(context);
final defaultTextStyle = theme.typography.body!;
Expand All @@ -457,19 +462,19 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
textDirection: Directionality.of(context),
child: _TooltipOverlay(
richMessage: widget.richMessage ?? TextSpan(text: widget.message),
padding: tooltipTheme.padding ?? EdgeInsetsDirectional.zero,
margin: tooltipTheme.margin ?? _defaultMargin,
decoration: tooltipTheme.decoration ?? defaultDecoration,
textStyle: tooltipTheme.textStyle ?? defaultTextStyle,
padding: _tooltipTheme.padding ?? EdgeInsetsDirectional.zero,
margin: _tooltipTheme.margin ?? _defaultMargin,
decoration: _tooltipTheme.decoration ?? defaultDecoration,
textStyle: _tooltipTheme.textStyle ?? defaultTextStyle,
animation: CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn,
),
target: target,
verticalOffset: tooltipTheme.verticalOffset ?? _defaultVerticalOffset,
preferBelow: tooltipTheme.preferBelow ?? _defaultPreferBelow,
verticalOffset: _tooltipTheme.verticalOffset ?? _defaultVerticalOffset,
preferBelow: _tooltipTheme.preferBelow ?? _defaultPreferBelow,
displayHorizontally: widget.displayHorizontally,
maxWidth: tooltipTheme.maxWidth,
maxWidth: _tooltipTheme.maxWidth,
),
);
_entry = OverlayEntry(builder: (_) => overlay);
Expand Down Expand Up @@ -545,6 +550,10 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
}
}

void _cacheTooltipTheme(BuildContext context) {
_tooltipTheme = TooltipTheme.of(context).merge(widget.style);
}

@override
Widget build(BuildContext context) {
// If message is empty then no need to create a tooltip overlay to show
Expand Down
40 changes: 40 additions & 0 deletions test/tooltip_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,46 @@ void main() {
expect(find.text('Test Tooltip'), findsNothing);
});

testWidgets('Tooltip honors style waitDuration on hover', (tester) async {
await tester.pumpWidget(
wrapApp(
child: const ScaffoldPage(
content: Center(
child: Tooltip(
message: 'Styled delay tooltip',
style: TooltipThemeData(waitDuration: Duration(seconds: 10)),
child: Button(
key: Key('StyledDelayButton'),
onPressed: null,
child: Text('Hover Me'),
),
),
),
),
),
);

expect(find.text('Styled delay tooltip'), findsNothing);

final gesture = await tester.createGesture(
kind: PointerDeviceKind.mouse,
pointer: 1,
);
await gesture.addPointer(location: Offset.zero);
await tester.pump();

await gesture.moveTo(
tester.getCenter(find.byKey(const Key('StyledDelayButton'))),
);
await tester.pump();

await tester.pump(const Duration(milliseconds: 9999));
expect(find.text('Styled delay tooltip'), findsNothing);

await tester.pump(const Duration(milliseconds: 1));
expect(find.text('Styled delay tooltip'), findsOneWidget);
});

testWidgets('Tooltip dismisses when clicking outside', (tester) async {
await tester.pumpWidget(
wrapApp(
Expand Down
Loading