expandable-and-linkified-text
Installation
SKILL.md
Expandable text, and tappable spans inside it
Two features that read as one and share no parts: clamping to N lines with a more/less affordance is
maxLines plus onTextLayout { hasVisualOverflow }; tappable substrings are buildAnnotatedString
plus pushStringAnnotation, hit-tested by character offset. They compete for the same tap, so
decide what a tap on the body means before writing either.
Clamping on measured overflow
Only the layout pass knows whether the text overflows — the same string wraps differently per width, font, text scale and translation. Ask it, and re-clamp by hand so the affordance is not itself truncated:
// adapted: names shortened; the source's runCatching if/else (which re-called getLineEnd on the
// success branch) folded into getOrDefault, and its Character.isWhitespace(it) into it.isWhitespace()
var isExpanded by remember { mutableStateOf(false) }
var clickable by remember { mutableStateOf(false) }
var lastCharIndex by remember { mutableIntStateOf(0) }