Skip to content

Tooltips

Tooltips display floating UI anchored to a document position.

Basic tooltip

Create a Tooltip and register it through the showTooltip facet:

import com.monkopedia.kodemirror.view.*

val myTooltip = Tooltip(
    pos = 42,
    above = true,
    content = {
        Text("Information at position 42")
    }
)

val state = EditorState.create(EditorStateConfig(
    extensions = showTooltip.of(myTooltip)
))

Tooltip data class

data class Tooltip(
    val pos: Int,
    val above: Boolean = false,
    val strictSide: Boolean = false,
    val content: @Composable () -> Unit
)
Property Description
pos Document position to anchor the tooltip to
above Show above the anchor position (default: below)
strictSide Don't flip to the other side even if off-screen
content Composable content (replaces toDOM() in upstream)

Cursor tooltip

Show a tooltip that follows the cursor using a StateField:

val cursorTooltipField = StateField.define(
    create = { state -> getCursorTooltips(state) },
    update = { _, tr -> getCursorTooltips(tr.state) },
    provide = { field -> showTooltips.from(field) }
)

fun getCursorTooltips(state: EditorState): List<Tooltip> {
    return state.selection.ranges.map { range ->
        Tooltip(
            pos = range.head,
            above = true,
            content = {
                val line = state.doc.lineAt(range.head)
                Text("Line ${line.number}, Col ${range.head - line.from + 1}")
            }
        )
    }
}

Hover tooltip

Show a tooltip when the user hovers over text:

private val hoverInfo = hoverTooltip { session, pos ->
    val doc = session.state.doc
    val line = doc.lineAt(DocPos(pos))
    val text = line.text
    // Find word boundaries
    val lineStart = line.from.value
    var start = pos - lineStart
    var end = start
    while (start > 0 && text[start - 1].isLetterOrDigit()) start--
    while (end < text.length && text[end].isLetterOrDigit()) end++
    if (start == end) return@hoverTooltip null
    val word = text.substring(start, end)
    Tooltip(
        pos = lineStart + start,
        above = true
    ) {
        Text(
            text = "\"$word\" at line ${line.number}, col ${start + 1}",
            style = MaterialTheme.typography.bodySmall,
            color = Color(0xFFABB2BF),
            modifier = Modifier
                .background(Color(0xFF2C313C))
                .padding(8.dp)
        )
    }
}

hoverTooltip takes a function (EditorSession, Int) -> Tooltip? that receives the view and the document position under the pointer. Return null for no tooltip.

Multiple tooltips

Use the showTooltips facet to display several tooltips at once:

val state = EditorState.create(EditorStateConfig(
    extensions = showTooltips.of(listOf(tooltip1, tooltip2))
))

Facets

Facet Type Description
showTooltip Facet<Tooltip?, Tooltip?> Single tooltip (first non-null wins)
showTooltips Facet<List<Tooltip>, List<Tooltip>> Multiple simultaneous tooltips

Based on the CodeMirror Tooltip example.