LearnNewsExamplesServices
Frontmatter
id19665
titleGrid: AnimateRows uses the row geometry or refuses content-sized mode
stateClosed
labels
enhancementaigrid
assigneesneo-opus-ada
createdAtOct 12, 2026, 4:08 PM
updatedAtOct 12, 2026, 10:45 PM
githubUrlhttps://github.com/neomjs/neo/issues/19665
authorneo-opus-ada
commentsCount2
parentIssue19658
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[x] 19661 Grid: an opt-in row-geometry model drives offsets, extents and navigation
blocking[x] 19666 Grid: a 10k wrapped-text example proves content-sized rows end to end
closedAtOct 12, 2026, 9:53 PM
milestonev13.3

Grid: AnimateRows uses the row geometry or refuses content-sized mode

Closed Backlog/active-chunk-8 enhancementaigrid
neo-opus-ada
neo-opus-ada commented on Oct 12, 2026, 4:08 PM

Context

This is leaf L5 of epic #19658, blocked by #19661 (the geometry model). The D#19645 STEP_BACK (point 2) found one more fixed-height consumer: plugin/AnimateRows translates rows by rowIndex × owner.rowHeight (L160, dev bf91293bde).

The Problem

In content-sized mode, AnimateRows would animate rows to fixed-height positions that don't match the geometry model, and the rows would land in the wrong places. The epic does not accept a silent fixed-height fallback.

Found at intake: the plugin does not work in fixed-height mode either. A sort or a filter throws owner.createRow is not a function, because the pooled grid.Body has no createRow any more. The plugin also keys rows by vdom id, while the body's vdom root now holds Row component references. Its repair is a rewrite onto the Row pool, tracked in #6858.

The Fix

Choose one at intake and record why:

  • (a) AnimateRows reads row offsets from the geometry model when the mode is on, so sort and filter animations land on the real offsets;
  • (b) the combination is refused explicitly: enabling content-sized mode with AnimateRows raises a clear error, or a documented warning plus the plugin disabling itself, never a silent wrong layout.

Chosen at intake: (b). (a) presupposes a plugin that works with the pooled Body, and that is the #6858 rewrite, not a geometry read. In content-sized mode, the plugin's store handlers (which shadow grid.Body#onStoreFilter and #onStoreLoad on the body instance) run the Body's own handlers and warn once that animatedRowSorting is ignored with contentSizedRows. Rows then render at their geometry offsets through the normal path. This works in either order, plugin first or mode first, and nothing has to be uninstalled.

Contract Ledger

Target surface Source of authority Proposed behavior Fallback / edge case Docs Evidence
plugin/AnimateRows with content-sized mode STEP_BACK point 2; intake (b) the plugin stands aside with a one-time warning; the Body's handlers render Fixed-height mode unchanged JSDoc Spec for the chosen branch

Acceptance Criteria

  • In content-sized mode, AnimateRows refuses the combination explicitly: a spec shows the warning, and rows land at the geometry's prefix offsets after a sort and a filter.
  • In fixed-height mode, the plugin's code path is unchanged. No AnimateRows specs exist; its fixed-height breakage is #6858's scope.

Out of Scope

Every other consumer (L1, L4), the 100k journey (L6), and repairing the plugin for the pooled Body (#6858).

Related

#19658 · #19661 (blocked by) · #6858 · D#19645 STEP_BACK (18881069)

Origin Session ID: daac81df-5205-405e-a3af-aec56e5cca45

tobiu closed this issue on Oct 12, 2026, 9:53 PM
tobiu referenced in commit 358af02 - "feat(grid): AnimateRows stands aside in content-sized mode (#19665) (#19677) on Oct 12, 2026, 9:53 PM