# Tooltip

> A short label or explanation that appears on hover, focus or long press.

- Category: Communication
- API status: Stable
- Compose APIs: `TooltipBox`, `PlainTooltip`, `RichTooltip`, `TooltipDefaults`, `rememberTooltipState`
- Interactive page: https://m3e.ljzapps.app/#components/tooltip

## When to use

Plain tooltips name an element, usually an icon button. Rich tooltips carry a title, a few lines of text and an optional action.

Hover an icon button with the pointer, focus it with the keyboard or long press it to see the tooltip.

## Playground

The interactive page has a playground with live property controls for this component and generated code.

## Examples

### Plain

Hover or focus the button.

```kotlin
TooltipBox(
    positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
    tooltip = { PlainTooltip { Text("Share this page") } },
    state = rememberTooltipState(),
) {
    IconButton(onClick = {}) {
        Icon(Icons.Rounded.Share, contentDescription = "Share")
    }
}
```

### Rich, with action

Persistent until dismissed.

```kotlin
val state = rememberTooltipState(isPersistent = true)
val scope = rememberCoroutineScope()

TooltipBox(
    positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
    tooltip = {
        RichTooltip(
            title = { Text("Sync") },
            action = { TextButton(onClick = { scope.launch { state.dismiss() } }) { Text("Got it") } },
        ) {
            Text("Changes are saved on this device first and uploaded when you are online.")
        }
    },
    state = state,
    hasAction = true,
) {
    Button(onClick = { scope.launch { state.show() } }) {
        Icon(Icons.Rounded.Info, contentDescription = null)
        Text("About sync")
    }
}
```

## Parameters

| Name | Type | Default | Description |
|---|---|---|---|
| `positionProvider` | `PopupPositionProvider` |  | Use TooltipDefaults.rememberTooltipPositionProvider(position). |
| `tooltip` | `@Composable TooltipScope.() -> Unit` |  | PlainTooltip or RichTooltip. |
| `state` | `TooltipState` |  | rememberTooltipState(isPersistent = true) keeps a rich tooltip open. |
| `hasAction` | `Boolean` | `false` | Set to true when a rich tooltip contains an action. |

## Guidelines

Do:
- Keep plain tooltips to a few words.
- Use rich tooltips for context the user may need.

Don't:
- Do not hide essential information in a tooltip.
- Do not put interactive content in a plain tooltip.

## Accessibility

- A tooltip is not a replacement for a content description. Set both.
- Tooltips must be reachable without a pointer: they show on keyboard focus and long press.
- Rich tooltips with actions are focusable and can be dismissed with Escape.

## Related components

- [Icon button](https://m3e.ljzapps.app/docs/components/icon-button.md)
- [Snackbar](https://m3e.ljzapps.app/docs/components/snackbar.md)
