@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
Basic Example
The Tooltip component has 2 main slots: its panel and its anchor.
The anchor contains the element to which the tooltip is anchored. When this element has focus, is hovered or long-pressed (on touch) the tooltip will be displayed.
The panel contains one of the overloads of TooltipPanel which renders the content of the tooltip according to the
Tooltip's internal state.
Tooltips are placed in the same layout as the trigger. This is different
to how Tooltips work in Compose Foundation, in order to prevent any
focus and pointer issues. Because of this, you need to use Modifier.zIndex() to your panel to place it above other
elements in the same layout.
Tooltip(
placement = RelativeAlignment.TopCenter,
panel = {
TooltipPanel(
modifier = Modifier.zIndex(15f),
enter = slideInVertically(tween(150), initialOffsetY = { (it * 0.25).toInt() }) +
scaleIn(
animationSpec = tween(150),
transformOrigin = TransformOrigin(0.5f, 1f),
initialScale = 0.65f
) + fadeIn(tween(150)),
exit = fadeOut(tween(250)),
arrow = { direction ->
val degrees = when (direction) {
TooltipArrowDirection.Up -> 0f
TooltipArrowDirection.Down -> 180f
TooltipArrowDirection.Left -> 90f
TooltipArrowDirection.Right -> 270f
}
ArrowUp(Modifier.rotate(degrees), Color.Black.copy(0.8f))
}
) {
Box(
modifier = Modifier
.clip(RoundedCornerShape(100))
.background(Color.Black.copy(0.8f))
.padding(vertical = 8.dp, horizontal = 12.dp),
) {
Text("Notifications", color = Color.White)
}
}
}
) {
val interactionSource = remember { MutableInteractionSource() }
Button(
onClick = { },
contentPadding = PaddingValues(8.dp),
shape = CircleShape,
modifier = Modifier.focusRing(interactionSource, 1.dp, Color(0xFF3B82F6), CircleShape),
interactionSource = interactionSource
) {
Icon(Lucide.BellDot, contentDescription = null)
}
}
Code Examples
Styling the Tooltip
The TooltipPanel composable contains styling properties such as backgroundColor, contentColor, shape and
contentPadding for easy styling.
Tooltip(
placement = RelativeAlignment.TopCenter,
panel = {
TooltipPanel(
modifier = Modifier.zIndex(15f),
backgroundColor = Color(0xFF1E293B),
contentColor = Color.White,
shape = RoundedCornerShape(8.dp),
contentPadding = PaddingValues(horizontal = 12.dp, vertical = 8.dp)
) {
Text("Styled tooltip")
}
}
) {
Button(onClick = {}) {
Text("Hover me")
}
}
Positioning the Tooltip
Pass the relative alignment you want to the Tooltip's placement property:
Tooltip(
placement = RelativeAlignment.TopEnd,
panel = {
TooltipPanel {
Text("This is a tooltip")
}
}
) {
Button(onClick = {}) {
Text("Hover me")
}
}
Tooltip with Arrow (Caret)
Use the TooltipPanel with the arrow parameter. The arrow lambda gives you the TooltipArrowDirection which the
arrow needs to be pointing towards.
We will always place the arrow between the anchor and the panel centering it to the respective direction.
@Composable
fun ArrowUp(modifier: Modifier = Modifier, color: Color) {
Canvas(modifier = modifier.size(8.dp, 4.dp)) {
val path = Path().apply {
moveTo(size.width / 2f, 0f)
lineTo(0f, size.height)
lineTo(size.width, size.height)
close()
}
drawPath(path, color = color)
}
}
Tooltip(
placement = RelativeAlignment.BottomCenter,
panel = {
TooltipPanel(
modifier = Modifier.zIndex(15f),
arrow = { direction ->
// Draw your arrow pointing towards the given direction
val degrees = when (direction) {
TooltipArrowDirection.Up -> 0f
TooltipArrowDirection.Down -> 180f
TooltipArrowDirection.Left -> 90f
TooltipArrowDirection.Right -> 270f
}
ArrowUp(Modifier.rotate(degrees), Color.Black)
}
) {
Text("Tooltip with arrow")
}
}
) {
Button(onClick = {}) {
Text("Hover me")
}
}
Animating the Tooltip
Pass the respective animation specs you want in the TooltipPanel's enter and exit parameters:
Tooltip(
placement = RelativeAlignment.TopCenter,
panel = {
TooltipPanel(
modifier = Modifier.zIndex(15f),
enter = fadeIn(animationSpec = tween(300)),
exit = fadeOut(animationSpec = tween(300))
) {
Text("This tooltip fades in and out")
}
}
) {
Button(onClick = {}) {
Text("Hover me")
}
}
Unstyled Tooltip vs Compose Foundation Tooltips
Tooltips in Compose Foundation are implemented using Popups. Popups do not allow pointer events behind them. This can cause weird glitches when the Tooltip is right above the trigger and mouse overed.
Unstyled Tooltips are placed in the same layout as its trigger, and do not use Popups. As a result, there are no weird focus or pointer issues.
Keyboard Interactions
| Key | Description |
|---|---|
Escape | Dismisses the tooltip when it is visible. |
Component API
Tooltip
| Parameter | Description |
|---|---|
enabled | Whether the tooltip is enabled. When disabled, the tooltip will not show. |
panel | A composable function that defines the tooltip content panel. |
placement | The relative alignment of the tooltip to the anchor element. Default is TopCenter. |
longPressShowDurationMillis | Duration in milliseconds to show the tooltip after a long press. Default is 1500ms. |
hoverDelayMillis | Delay in milliseconds before showing the tooltip on hover. Default is 0ms. |
anchor | A composable function that defines the anchor element that triggers the tooltip. |
TooltipPanel
| Parameter | Description |
|---|---|
modifier | Modifier to be applied to the tooltip panel. |
enter | The enter transition for the tooltip panel. Default is instant appearance. |
exit | The exit transition for the tooltip panel. Default is instant disappearance. |
shape | The shape of the tooltip panel. |
backgroundColor | The background color of the tooltip panel. |
contentColor | The color to apply to the contents of the tooltip panel. |
contentPadding | Padding values for the content within the tooltip panel. |
content | A composable function that defines the content of the tooltip. |
TooltipPanel (with arrow)
| Parameter | Description |
|---|---|
modifier | Modifier to be applied to the tooltip panel. |
arrow | A composable function that receives TooltipArrowDirection and draws the arrow accordingly. |
enter | The enter transition for the tooltip panel. Default is instant appearance. |
exit | The exit transition for the tooltip panel. Default is instant disappearance. |
content | A composable function that defines the content of the tooltip. |
