LearnNewsExamplesServices
Frontmatter
id12903
titleWithin-region column drags leave the grid's region-column arrays stale
stateClosed
labels
bugaigrid
assigneesneo-fable
createdAtJun 11, 2026, 4:16 PM
updatedAtJun 11, 2026, 5:11 PM
githubUrlhttps://github.com/neomjs/neo/issues/12903
authorneo-fable
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 11, 2026, 5:11 PM

Within-region column drags leave the grid's region-column arrays stale

neo-fable
neo-fable commented on Jun 11, 2026, 4:16 PM

Context

Found while running the merged locked-column whitebox spec (GridColumnCrossBodyDnD.spec.mjs, PR #12893) under the identity-bound fixture (#12897 fix): the landing leg's worker assertion fails on merged dev — and the analysis shows it could never have passed.

Release classification: boardless — engine-state correctness + spec-enabler; the L4 manual gate (#12883) does not read these arrays.

The Problem

A within-region column drop reorders the global collection via gridContainer.columns.move(from, to) (draggable.grid.header.toolbar.SortZone#moveTo). collection.Base#move mutates _items directly via splices and fires no mutate event — so grid.Container#onColumnsMutate never runs, and the derived region-grouped arrays (lockedStartColumns, centerColumns, lockedEndColumns) keep their pre-drag order indefinitely.

Empirical proof (live spec run, identity-bound to the test's own page): after the Total→index-2 drag, the DOM header order reads ["Commits %", "Private %", "Total", …] (the drag landed correctly) while the engine's centerColumns still reads ["totalContributions", "commitRatio", "privateContributionsRatio", …] (pristine). Cross-region drops are unaffected (the locked change runs onColumnLockChangeonColumnsMutate) — exactly why the spec's cross-region leg passes and its landing leg fails.

Blast radius today is bounded: columnIndexOffset() consumes only the arrays' lengths (immune); header rebuild paths run on mutate-paths only. But the arrays are the documented engine oracle for region order ("the engine's authoritative region+index model"), the merged spec asserts through them, and any future consumer reading region ORDER post-drag gets stale state.

The Architectural Reality

  • src/collection/Base.mjs move() — event-silent by design (splice-only).
  • src/grid/Container.mjs onColumnsMutate — recomputes the three region arrays by filtering _columns.items, then drives sub-grid/header/colCount updates; wired to the collection's mutate event (fires on add/remove, not move).
  • src/draggable/grid/header/toolbar/SortZone.mjs moveTosuper.moveTo (toolbar items) + columns.move(from+offset, to+offset) (global collection).

The Fix

Extract the three-filter refresh from onColumnsMutate into grid.Container#refreshRegionColumns() and invoke it from the drag's moveTo after columns.move(...). Deliberately NOT making collection.move fire mutate (framework-wide blast radius for every collection consumer) and NOT running full onColumnsMutate on every within-region drop (sub-grid/header/size work is unnecessary — the toolbars were already reordered by the drag's own switch flow).

Acceptance Criteria

  • After a within-region drop, centerColumns (and siblings) reflect the new order (the spec's landing-leg worker assertion region.center[2] === 'totalContributions' passes, identity-bound).
  • Cross-region behavior unchanged (the spec's re-home leg stays green).
  • No additional updates triggered on the within-region path beyond the array refresh.

Out of Scope

  • Making collection.Base#move event-firing (framework-wide change; consider post-v13 if more consumers need it).
  • The drag-scroll body-rendering report (#12883's open investigation — separate thread).

Related

  • Refs #12807 (the spec this enables), #12883 (the drag-quality umbrella), #12897 (the identity-bind fixture fix that exposed it)

Live latest-open sweep: checked latest open issues at 2026-06-11T14:20Z; no equivalent found.

Origin Session ID: e605ce21-3668-445c-bc00-45896aa9a092

Retrieval Hint: "centerColumns stale within-region drag collection move no mutate event"

tobiu referenced in commit e93c8f4 - "fix(grid): refresh region-column arrays after within-region drag reorders (#12903) (#12905) on Jun 11, 2026, 5:11 PM
tobiu closed this issue on Jun 11, 2026, 5:11 PM