just_tooltip 0.2.0
just_tooltip: ^0.2.0 copied to clipboard
A lightweight, customizable Flutter tooltip with flexible placement, hover & tap triggers, programmatic control, and RTL support.
just_tooltip #
A lightweight, customizable Flutter tooltip widget. Combine direction (top/bottom/left/right) and alignment (start/center/end) for 12 positioning combinations with arrow indicators, viewport-aware auto-flipping, and programmatic control.
Features #
- 12 positioning combinations — 4 directions × 3 alignments
- Reusable theme —
JustTooltipThemegroups all visual styling - Arrow indicator — unified shape with border support
- Viewport overflow protection — auto-flip direction and clamp position
- Hover & tap triggers — independently toggleable
- Interactive tooltips — stays visible while hovering tooltip content
- Programmatic control — show/hide/toggle via controller
- Custom content — any widget via
tooltipBuilder - RTL support — start/end automatically swapped for top/bottom directions
- Single instance — only one tooltip visible at a time
Install #
dependencies:
just_tooltip: ^0.2.0
Basic Usage #
Pass a message string. Defaults to hover trigger, top-center position.
JustTooltip(
message: 'Hello!',
child: Text('Hover me'),
)
Direction & Alignment #
direction controls which side the tooltip appears on. alignment controls where it aligns along that side.
JustTooltip(
message: 'Top left aligned',
direction: TooltipDirection.top,
alignment: TooltipAlignment.start,
child: MyWidget(),
)
12 combinations are available:
| direction | alignment | position |
|---|---|---|
top |
start |
above, left-aligned |
top |
center |
above, centered |
top |
end |
above, right-aligned |
bottom |
start |
below, left-aligned |
bottom |
center |
below, centered |
bottom |
end |
below, right-aligned |
left |
start |
left, top-aligned |
left |
center |
left, centered |
left |
end |
left, bottom-aligned |
right |
start |
right, top-aligned |
right |
center |
right, centered |
right |
end |
right, bottom-aligned |
In RTL environments, start/end are automatically swapped for top/bottom directions.
Viewport Overflow Protection #
When there isn't enough space in the preferred direction, the tooltip automatically flips to the opposite side. The tooltip position is also clamped to stay within screen bounds.
Use screenMargin to control the minimum distance from viewport edges. This also affects the maximum size of the tooltip.
JustTooltip(
message: 'Safe tooltip',
direction: TooltipDirection.top,
screenMargin: 16.0, // 16px minimum distance from screen edges (default: 8.0)
child: MyWidget(),
)
Theme #
Use JustTooltipTheme to group all visual styling parameters. The theme is reusable across multiple tooltips.
// Define a reusable theme
const myTheme = JustTooltipTheme(
backgroundColor: Colors.black87,
textStyle: TextStyle(color: Colors.white),
showArrow: true,
borderColor: Colors.white,
borderWidth: 1.0,
);
// Reuse across widgets
JustTooltip(message: 'A', theme: myTheme, child: WidgetA())
JustTooltip(message: 'B', theme: myTheme, child: WidgetB())
Use copyWith() to derive variations:
final warningTheme = myTheme.copyWith(
backgroundColor: Colors.orange,
borderColor: Colors.deepOrange,
);
Arrow #
Enable showArrow in the theme to display a triangular arrow pointing at the target widget. The arrow is rendered as a unified shape with the tooltip body, so background, shadow, and border all follow the combined outline.
JustTooltip(
message: 'With arrow',
theme: JustTooltipTheme(
showArrow: true,
arrowBaseWidth: 12.0, // arrow base width (default: 12.0)
arrowLength: 6.0, // arrow protrusion length (default: 6.0)
),
child: MyWidget(),
)
For start/end alignments, arrowPositionRatio controls where the arrow sits along the tooltip edge (0.0 = near the aligned edge, 1.0 = far end).
JustTooltip(
message: 'Arrow near edge',
alignment: TooltipAlignment.start,
theme: JustTooltipTheme(
showArrow: true,
arrowPositionRatio: 0.25, // 25% from the start edge (default: 0.25)
),
child: MyWidget(),
)
The arrow auto-flips along with the tooltip when direction changes due to viewport constraints.
Border #
Add an outline that follows the tooltip shape, including the arrow.
JustTooltip(
message: 'Bordered',
theme: JustTooltipTheme(
showArrow: true,
borderColor: Colors.white,
borderWidth: 1.5,
),
child: MyWidget(),
)
Trigger #
Hover and tap triggers can be toggled independently.
// Tap only
JustTooltip(
message: 'Tap tooltip',
enableTap: true,
enableHover: false,
child: MyButton(),
)
Controller #
Use JustTooltipController for programmatic control.
final controller = JustTooltipController();
// Widget
JustTooltip(
message: 'Controlled',
controller: controller,
enableHover: false,
child: MyWidget(),
)
// Control
controller.show();
controller.hide();
controller.toggle();
The controller state automatically syncs when the tooltip is dismissed by hover-out, tap-outside, or auto-hide, so show() works correctly after any dismissal.
Custom Content #
Use tooltipBuilder to render any widget instead of plain text. The caller is responsible for managing the size of the content.
JustTooltip(
tooltipBuilder: (context) => Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.info, color: Colors.white, size: 16),
SizedBox(width: 8),
Text('Custom content', style: TextStyle(color: Colors.white)),
],
),
child: MyWidget(),
)
Cross-Axis Offset #
Use crossAxisOffset to shift the tooltip along the cross-axis from the aligned edge. For start/end, a positive value pushes the tooltip inward (toward center). For center, a positive value moves toward the end direction.
JustTooltip(
message: 'Shifted inward',
direction: TooltipDirection.top,
alignment: TooltipAlignment.start,
crossAxisOffset: 10, // left-aligned but shifted 10px to the right
child: MyWidget(),
)
| direction | alignment | crossAxisOffset: 10 |
|---|---|---|
| top/bottom | start |
shifts right |
| top/bottom | center |
shifts right |
| top/bottom | end |
shifts left (inward) |
| left/right | start |
shifts down |
| left/right | center |
shifts down |
| left/right | end |
shifts up (inward) |
Interactive & Timing #
interactive keeps the tooltip visible when the cursor moves from the child to the tooltip itself. Useful for selectable text or clickable content inside the tooltip. When combined with showDuration, the auto-hide timer pauses while the cursor is on the tooltip.
waitDuration adds a delay before the tooltip appears. showDuration auto-hides the tooltip after a set time.
JustTooltip(
message: 'Interactive tooltip',
interactive: true, // stay visible when hovering tooltip (default: true)
waitDuration: Duration(milliseconds: 300), // delay before showing
showDuration: Duration(seconds: 3), // auto-hide after 3s
child: MyWidget(),
)
Box Shadow #
Use boxShadow in the theme for fine-grained shadow control. When provided, elevation is ignored.
JustTooltip(
message: 'Custom shadow',
theme: JustTooltipTheme(
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.3),
blurRadius: 8.0,
spreadRadius: 1.0,
offset: Offset(0, 4),
),
],
),
child: MyWidget(),
)
Styling #
All visual styling is configured through JustTooltipTheme:
JustTooltip(
message: 'Styled',
offset: 12.0, // gap between child and tooltip
theme: JustTooltipTheme(
backgroundColor: Colors.indigo,
borderRadius: BorderRadius.circular(12),
padding: EdgeInsets.all(16),
elevation: 8.0,
textStyle: TextStyle(color: Colors.white, fontSize: 16),
borderColor: Colors.white,
borderWidth: 1.0,
showArrow: true,
),
child: MyWidget(),
)
Callbacks #
JustTooltip(
message: 'With callbacks',
onShow: () => print('shown'),
onHide: () => print('hidden'),
child: MyWidget(),
)
API Reference #
JustTooltip #
| Parameter | Type | Default | Description |
|---|---|---|---|
child |
Widget |
required | Target widget the tooltip is anchored to |
message |
String? |
null |
Text content (one of message or tooltipBuilder required) |
tooltipBuilder |
WidgetBuilder? |
null |
Custom widget builder |
direction |
TooltipDirection |
top |
Which side the tooltip appears on |
alignment |
TooltipAlignment |
center |
Alignment along the cross-axis |
offset |
double |
8.0 |
Gap between child and tooltip |
crossAxisOffset |
double |
0.0 |
Shift along the cross-axis (inward for start/end) |
screenMargin |
double |
8.0 |
Minimum distance from viewport edges |
theme |
JustTooltipTheme |
JustTooltipTheme() |
Visual styling (see below) |
controller |
JustTooltipController? |
null |
Programmatic control |
enableTap |
bool |
false |
Tap trigger |
enableHover |
bool |
true |
Hover trigger |
interactive |
bool |
true |
Keep tooltip visible when hovering over it |
waitDuration |
Duration? |
null |
Delay before tooltip appears |
showDuration |
Duration? |
null |
Auto-hide after this duration |
animationDuration |
Duration |
150ms |
Fade animation duration |
onShow |
VoidCallback? |
null |
Called when tooltip is shown |
onHide |
VoidCallback? |
null |
Called when tooltip is hidden |
JustTooltipTheme #
| Parameter | Type | Default | Description |
|---|---|---|---|
backgroundColor |
Color |
Color(0xFF616161) |
Background color |
borderRadius |
BorderRadius |
circular(6) |
Corner radius |
padding |
EdgeInsets |
h:12, v:8 |
Inner padding |
elevation |
double |
4.0 |
Shadow elevation (ignored if boxShadow is set) |
boxShadow |
List<BoxShadow>? |
null |
Custom box shadows |
borderColor |
Color? |
null |
Border color |
borderWidth |
double |
0.0 |
Border stroke width |
textStyle |
TextStyle? |
null |
Text style for message |
showArrow |
bool |
false |
Display triangular arrow pointing at target |
arrowBaseWidth |
double |
12.0 |
Arrow base width |
arrowLength |
double |
6.0 |
Arrow protrusion length |
arrowPositionRatio |
double |
0.25 |
Arrow position along the edge for start/end (0.0-1.0) |
Migration from 0.1.x #
Individual styling parameters have been moved into JustTooltipTheme:
// Before (0.1.x)
JustTooltip(
message: 'Hello',
backgroundColor: Colors.blue,
showArrow: true,
borderColor: Colors.white,
borderWidth: 1.0,
child: MyWidget(),
)
// After (0.2.0)
JustTooltip(
message: 'Hello',
theme: JustTooltipTheme(
backgroundColor: Colors.blue,
showArrow: true,
borderColor: Colors.white,
borderWidth: 1.0,
),
child: MyWidget(),
)
Example #
An interactive playground app is included in the example/ folder.
cd example
flutter run