Frontmatter
| id | 9487 |
| title | Grid Multi-Body: Refactor Layout Engine & SubGrid Partitioning |
| state | Closed |
| labels | enhancementaigrid |
| assignees | tobiu |
| createdAt | Mar 16, 2026, 7:15 PM |
| updatedAt | Mar 31, 2026, 12:27 PM |
| githubUrl | https://github.com/neomjs/neo/issues/9487 |
| author | tobiu |
| commentsCount | 1 |
| parentIssue | 9486 |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Mar 31, 2026, 12:27 PM |
Grid Multi-Body: Refactor Layout Engine & SubGrid Partitioning
Closedenhancementaigrid
tobiu added parent issue #9486 on Mar 16, 2026, 7:15 PM
tobiu assigned to @tobiu on Mar 16, 2026, 7:18 PM
tobiu cross-referenced by #9486 on Mar 31, 2026, 12:02 PM

tobiu
Mar 31, 2026, 12:26 PM
Input from Gemini 3.1 Pro (Antigravity):
✦ Completed Phase 2 of the Multi-Body Epic.
- Implemented
headerWrapperandbodyWrapperinsideGridContainer.mjsto encapsulate symmetrical sub-grids.- Created
createOrUpdateSubGrids()logic for dynamic sub-grid orchestration based on split column collections.- Refactored
Toolbar.passSizeToBody()to explicitly calculate constraints corresponding to its twin GridBody via thelayoutLockconfig, correctly resettingx: 0coordinates.- Overhauled
onColumnLockChange()andonColumnsMutate()for centralized state consistency resulting in automatic sub-grid regeneration boundaries.- Re-architected
Row.mjs&Body.mjsdependency resolution to inherently rely on_gridContainertraversing up multi-tier structures cleanly.
tobiu closed this issue on Mar 31, 2026, 12:27 PM
tobiu cross-referenced by #9607 on Mar 31, 2026, 12:33 PM
Phase 2 of the Multi-Body Epic (#9486).
Before we can render locked columns smoothly, we must physically partition the Grid's layout engine. Currently,
Neo.grid.Containerpasses a single, flatcolumnPositionsarray to a singletonNeo.grid.Body.Requirements:
1. Column Partitioning: Refactor the math engine inside
grid.header.Toolbar#passSizeToBody()(or wherever the logical sizes are calculated). Instead of generating one flat array of physicalxcoordinates and widths, it must group them by theirlockedstate:startColumns: Array of{dataField, width, x}for columns wherelocked: 'start'. Thexcoordinates here start at0.centerColumns: Array of{dataField, width, x}for unlocked columns. Thexcoordinates here also start at0(because they will live in their own physical container).endColumns: Array of{dataField, width, x}for columns wherelocked: 'end'.xstarts at0.2. SubGrid Instantiation (The Wrapper):
grid.Containerneeds a new internal structural layer inside its body configuration to hold up to three instances ofNeo.grid.Body.<div class="neo-grid-body-wrapper" style="overflow-y: auto;"> <div class="neo-multi-body-layout" style="display: flex;"> <div class="neo-body-start">...</div> <div class="neo-body-center">...</div> <div class="neo-body-end">...</div> </div> </div>removeDom: trueOptimization: If a zone (e.g., Left) has no columns assigned to its collection, its corresponding SubGrid VDOM node should receiveremoveDom: trueto keep the live DOM lightweight while preserving the component instance and VDOM structure.3. Routing Configuration:
grid.Containermust route the partitioned column definitions to their respectivegrid.Bodyinstances.4. Header Splitting:
header.Toolbar.mjsto be instantiated up to three times (one per zone), binding to the respective column collections defined in Phase 1.Note: Fixing the vertical scroll math and row pooling for these bodies will be handled in subsequent tickets.