diff --git a/CHANGELOG.md b/CHANGELOG.md index 29979d022..bfc925208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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)) diff --git a/lib/src/controls/flyouts/tooltip.dart b/lib/src/controls/flyouts/tooltip.dart index 0952ddc6d..d45d63474 100644 --- a/lib/src/controls/flyouts/tooltip.dart +++ b/lib/src/controls/flyouts/tooltip.dart @@ -305,7 +305,15 @@ class TooltipState extends State 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); + } } void _handleStatusChanged(AnimationStatus status) { @@ -438,9 +446,6 @@ class TooltipState extends State 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!; @@ -457,19 +462,19 @@ class TooltipState extends State 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); @@ -545,6 +550,10 @@ class TooltipState extends State 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 diff --git a/test/tooltip_test.dart b/test/tooltip_test.dart index 9edfff90c..80dd7a69f 100644 --- a/test/tooltip_test.dart +++ b/test/tooltip_test.dart @@ -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(