NakedTooltip
Hover/touch triggered tooltip overlay with positioning, animation, and lifecycle callbacks
Headless tooltip component built on Flutter's RawTooltip. Handles hover/touch triggers, positioning, animations, timers, and dismissal. The builder receives an Animation for easy transitions.
When to use this
- Help text: Explain UI elements or provide additional context
- Icon explanations: Clarify what icon buttons do
- Form field hints: Show validation rules or input examples
- Feature descriptions: Brief explanations of complex features
Working example: example/lib/api/naked_tooltip.0.dart.
Basic implementation
import 'package:flutter/material.dart';
import 'package:naked_ui/naked_ui.dart';
class TooltipExample extends StatelessWidget {
const TooltipExample({super.key});
@override
Widget build(BuildContext context) {
return NakedTooltip(
positioning: const OverlayPositionConfig(
targetAnchor: Alignment.topCenter,
followerAnchor: Alignment.bottomCenter,
),
hoverDelay: const Duration(milliseconds: 400),
dismissDelay: const Duration(seconds: 2),
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.grey.shade900,
borderRadius: BorderRadius.circular(8),
),
child: const Icon(Icons.copy, color: Colors.white, size: 18),
),
overlayBuilder: (context, animation) {
return FadeTransition(
opacity: animation,
child: Material(
elevation: 4,
borderRadius: BorderRadius.circular(8),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: const Text('Copy to clipboard'),
),
),
);
},
semanticLabel: 'Copy button tooltip',
);
}
}
Constructor
const NakedTooltip({
Key? key,
required this.child,
required this.overlayBuilder,
this.hoverDelay = Duration.zero,
this.touchDelay = const Duration(milliseconds: 1500),
this.dismissDelay = const Duration(milliseconds: 100),
this.enableTapToDismiss = true,
this.triggerMode = TooltipTriggerMode.longPress,
this.enableFeedback = true,
this.onTriggered,
this.animationStyle,
this.positioning = const OverlayPositionConfig(),
this.semanticLabel,
this.excludeSemantics = false,
})
Key Parameters
child→ trigger widget that displays the tooltip on hover/touchoverlayBuilder→(BuildContext, Animation<double>)that returns the tooltip body; the animation drives show/hide transitionshoverDelay→ delay before showing once hover occurs (default: immediate)dismissDelay→ delay before hiding after mouse exits (default: 100ms)touchDelay→ how long the tooltip stays visible after touch release (default: 1500ms)positioning→OverlayPositionConfigcontrolling anchor & offsettriggerMode→ how touch events trigger the tooltip (longPress, tap, or manual)animationStyle→ customize animation duration, curve, and reverse behavioronTriggered→ called when triggered by tap or long press (not hover)semanticLabel→ text announced by assistive technologiesexcludeSemantics→ hide tooltip semantics from accessibility services
Behaviour Notes
- Tooltips open on pointer hover automatically
- Touch triggers depend on
triggerMode(longPress by default, or tap) - The
overlayBuilderreceives anAnimation<double>(0→1 on show, 1→0 on hide) for smooth transitions - Use
AnimationStyle.noAnimationto disable the built-in transition - The tooltip dismisses on outside tap (controllable via
enableTapToDismiss) - Only one tooltip is shown at a time when using nested tooltips
Positioning Tips
Use OverlayPositionConfig.offset to nudge the tooltip position:
const OverlayPositionConfig(
targetAnchor: Alignment.topCenter,
followerAnchor: Alignment.bottomCenter,
offset: Offset(0, -8),
);
For fully custom positioning beyond what OverlayPositionConfig exposes, drop down to Flutter's RawTooltip directly and supply your own TooltipPositionDelegate.