Sitemap
MobileByteSensei

Deep-dives on Compose, Kotlin Multiplatform, and the agents now writing alongside us — from shipped work, not from the docs.

TextFieldState is a document, and edits are transactions on it

6 min readSep 25, 2026

--

Undo, selection, IME composition — the machinery Day 38 skipped, and why editing through state.edit is different from replacing a String.

Press enter or click to view image in full size
Day 52 — TextFieldState is a document; edits are transactions

Day 52 of 100. Day 38 introduced TextFieldState and the cursor problem. Today: what else it holds, and why editing it looks the way it does.

The case this post is about

One clear button that breaks undo:

IconButton(onClick = { state.setTextAndPlaceCursorAtEnd("") }) {
Icon(Icons.Default.Close, contentDescription = "Clear")
}


It clears the field correctly. Press undo afterwards and you do not get the text back — you get something from several keystrokes earlier, or nothing at all, depending on how the field had been edited before.
The field holds three things that move together: the text, the selection, and the IME composing region. Replacing the text wholesale tells the buffer that everything changed and has no relationship to what came before, so the undo history has nothing coherent to step back into.
This post follows that one button, because the fix is the same operation expressed as a transaction, and the difference is invisible at the call site.

The symptom

A “clear” button that breaks undo:

IconButton(onClick = {…

--

--

Senior Software Engineer at OpenLane Inc, Open source contributor at Mifos Initiative and mentoring GSoC Students. https://github.com/therajanmaurya

MobileByteSensei
MobileByteSensei

Published in MobileByteSensei

Deep-dives on Compose, Kotlin Multiplatform, and the agents now writing alongside us — from shipped work, not from the docs.