I have a `ClickableText` with a URL string inside ...
# compose-desktop
m
I have a
ClickableText
with a URL string inside the annotated text with a corresponding string annotation. When I click the URL text a browser window is opened with that URL. So my setup is working correctly. My question now is, how can I somehow temporarily highlight the URL text when the user hovers over it with the mouse so that he/she knows that there is something to click on?
o
I do it like this: 1. Handle
onTextLayout
and save
TextLayoutResult
in a mutable state 2. Handle
onPointerEvent(PointerEventType.Move)
and use mouse position to find offset in text
textLayout?.multiParagraph?.getOffsetForPosition(position)
3. Find URL annotation in the text matching the position and save its range in a mutable state 4. (re-)Style annotated text depending on which range is hovered, if any
m
Thanks for the hints. I solved it using the experimental onHover callback. Here is the relevant code fragment in case someone is interested:
Copy code
val annotatedText = remember(styledMessage) { styledMessage.parseTaggedText() }
var textLayoutResult by remember { mutableStateOf<TextLayoutResult?>(null) }
var path by remember { mutableStateOf<Path?>(null) }
fun urlRange(offset: Int?): AnnotatedString.Range<String>? {
    return offset?.let {
        annotatedText.getStringAnnotations(
        tag = TaggedTextAnnotationTag.Hyperlink.name,
        start = it,
        end = it
    ).firstOrNull() }
}
ClickableText(
    text = annotatedText,
    modifier = Modifier
        .fillMaxWidth()
        .drawBehind { path?.let { drawPath(it, primaryUltraLightColor) } },
    style = LocalTextStyle.current.copy(textAlign = textAlign, fontSize = 14.sp, color = primaryDarkColor),
    onTextLayout = { textLayoutResult = it },
    onHover = { offset -> path = urlRange(offset)?.let { textLayoutResult?.getPathForRange(it.start, it.end) } },
    onClick = { offset -> urlRange(offset)?.let { mapService.showUrl(it.item) } }
)
m
Looks like
onHover
was removed, and
ClickableText
is deprecated anyway. So what's the proper solution now?
m
At the moment I have disabled that functionality in my app for the above reasons but I’d be interested in a solution too. There were just higher priorities at the moment but I guess this articel https://joebirch.co/migrating-from-the-clickabletext-composable-to-linkannotation/ describes the necessary changes.
m
I moved to
LinkAnnotation
, and styling the text itself on hover is no problem, but I can no longer change the cursor pointer icon on hover. https://youtrack.jetbrains.com/issue/CMP-7615
m
I was just trying to re-establish this functionality in my own code but I stumbled over this issue. https://kotlinlang.slack.com/archives/CJLTWPH7S/p1739623628158029 Do you have a solution for that?
m
Sorry, my app is Desktop-only so I haven't tried this with an Android target.