@Composable fun HighlightedText( text: String, highlights: List, modifier: Modifier = Modifier, ) { data class TextData( val text: String, val tag: String? = null, val data: String? = null, val onClick: ((data: AnnotatedString.Range) -> Unit)? = null ) val textData = mutableListOf() if (highlights.isEmpty()) { textData.add( TextData( text = text ) ) } else { var startIndex = 0 highlights.forEachIndexed { i, link -> val endIndex = text.indexOf(link.text) if (endIndex == -1) { throw Exception("Highlighted text mismatch") } textData.add( TextData( text = text.substring(startIndex, endIndex) ) ) textData.add( TextData( text = link.text, tag = "${link.text}_TAG", data = link.data, onClick = { link.onClick(it.item) } ) ) startIndex = endIndex + link.text.length if (i == highlights.lastIndex && startIndex < text.length) { textData.add( TextData( text = text.substring(startIndex, text.length) ) ) } } } val annotatedString = buildAnnotatedString { textData.forEach { linkTextData -> if (linkTextData.tag != null && linkTextData.data != null) { pushStringAnnotation( tag = linkTextData.tag, annotation = linkTextData.data, ) withStyle( style = SpanStyle( color = infoLinkTextColor ), ) { append(linkTextData.text) } pop() } else { append(linkTextData.text) } } } ClickableText( text = annotatedString, style = TextStyle( fontSize = 0.031.sw, fontWeight = FontWeight.Normal, color = infoTextColor, textAlign = TextAlign.Start ), onClick = { offset -> textData.forEach { annotatedStringData -> if (annotatedStringData.tag != null && annotatedStringData.data != null) { annotatedString.getStringAnnotations( tag = annotatedStringData.tag, start = offset, end = offset, ).firstOrNull()?.let { annotatedStringData.onClick?.invoke(it) } } } }, modifier = modifier ) }