sortedWithinRowBlocks

fun <T> List<T>.sortedWithinRowBlocks(blockOf: (T) -> Any?, comparator: Comparator<in T>): List<T>

Sorts rows within each block while keeping every block whole — a plain sortedBy fragments blocks into duplicate bands. Each unit — a block or a standalone row — takes its position from its minimal member under comparator, so the list still reads as sorted at unit granularity. The sort is stable both within a block and between units: ties keep their existing order, and re-applying the same sort changes nothing.

With drag enabled, apply this one-shot to the SOURCE list — rewriting it — never as a persistent render-time projection. Unit order here follows comparator, not drag history (ties excepted), so a live projection re-pins unit order after every committed block move, making the move invisible in the rendered list — the same theorem that rules out composing a free sort with drag, replayed at unit granularity.