refactor(listbox): ScrollRow is MVVM-only (completes the migration) - #313
Conversation
Move ListBox's last imperative state field, ScrollRow (the vertical scroll offset), onto an mvvm.Observable exposed through an accessor, mirroring the earlier Selected() migration: - ScrollRow int -> unexported scrollRow *mvvm.Observable[int] with a lazy-init (0) ScrollRow() *mvvm.Observable[int] accessor. There is no settable ScrollRow field left. - Wheel scroll, arrow-key scroll-into-view and scrollbar drag now ScrollRow().Set(n) (clamp preserved); Draw/hit-tests read ScrollRow().Get(). NewListBox seeds the observable to 0. - Wire the one in-package consumer (DropDown popover) and every affected _test.go to the accessor. Rendering is byte-identical at every scroll offset (verified against origin/main into RGBA buffers, cmp-identical). list.go stays at 100% coverage. With ScrollRow migrated, ListBox has no imperative state field left and becomes mvvm-gate-eligible (a follow-up adds it to the gate). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-08-18 22:55 CEST — from the session on the Android back-end. Not an objection to the migration, which is clearly the right shape; a measurement of what it leaves behind downstream, since consumers are not being swept along with it.
|
|
2026-08-19 00:40 CEST — follow-up with the full blast radius, measured rather than estimated. You clearly are sweeping consumers (reader#222 landed while I was porting reader myself, which is my own fault for fetching Method: clone each repo's GitHub HEAD, Still broken against v0.204.0 — 8 repos
Already fine — 9 repos
One false positive, flagged so it doesn't waste your time
Also landed on my side: |
Completes the ListBox MVVM migration by moving its last imperative state field, ScrollRow (the vertical scroll offset), onto an
mvvm.Observableaccessor — mirroring the earlierSelected()migration.What changed
ScrollRow int→ unexportedscrollRow *mvvm.Observable[int]+ lazy-init (0) accessorScrollRow() *mvvm.Observable[int]. No settable ScrollRow field remains.ScrollRow().Set(n)(clamp preserved);Draw/hit-tests readScrollRow().Get().NewListBoxseeds the observable to 0._test.goto the accessor.Verification
EventScroll) into RGBA buffers onorigin/mainvs this branch —cmpbyte-identical (864000 bytes each). Removed before commit.list.gostays at 100% coverage.GOWORK=off go build ./...,GOOS=js GOARCH=wasmbuild,go test ./..., andgofmtall green.Follow-up
With ScrollRow migrated, ListBox now has no imperative state field left and becomes mvvm-gate-eligible — a follow-up gate sweep will add
"ListBox": {"Items": true, "RowHeight": true, "MultiSelect": true, "Reorderable": true}tomvvm_gate_test.go.