LearnNewsExamplesServices
Frontmatter
id9408
titleGrid Core Integration & TreeGrid Accessibility
stateClosed
labels
enhancementaicoregrid
assigneestobiu
createdAtMar 9, 2026, 11:59 AM
updatedAtMar 9, 2026, 7:17 PM
githubUrlhttps://github.com/neomjs/neo/issues/9408
authortobiu
commentsCount2
parentIssue9404
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMar 9, 2026, 7:17 PM

Grid Core Integration & TreeGrid Accessibility

Closed v12.1.0 enhancementaicoregrid
tobiu
tobiu commented on Mar 9, 2026, 11:59 AM

Goal

Ensure GridContainer, GridBody, and Row correctly handle the dynamic flat-array sizing provided by the TreeStore and implement full WAI-ARIA treegrid attributes for maximum accessibility.

Details

  1. Virtual Scroller Reaction:

    • Verify that GridBody correctly responds to the TreeStore's mutate events when nodes expand/collapse (the count changes).
    • Ensure aria-rowcount on the GridBody updates dynamically based on the current length of the flattened view.
    • Ensure the VerticalScrollbar recalculates its height based on the new store.count.
  2. A11y (Row Level ARIA):

    • Update src/grid/Row.mjs -> createVdom().
    • Map record.expanded to aria-expanded (true/false). Omit entirely for leaf nodes.
    • Map record.depth to aria-level (1-based).
    • Map record.siblingCount to aria-setsize.
    • Map record.siblingIndex to aria-posinset (1-based).
    • Note: The virtual scroller will naturally provide gapless aria-rowindex values based on the flattened visible array.
  3. Data Layer Support for A11y Attributes:

    • The TreeStore (or TreeModel) must provide depth, siblingCount, and siblingIndex for all records.
    • Use Neo's "Soft Hydration" pattern to calculate these lazily when needed, or compute them once during loadData and store them directly on the raw data objects / records for O(1) retrieval during rapid scrolling.
  4. Role Update:

    • Add a config isTreeGrid: false to GridContainer.
    • When true, switch the container's ARIA role from grid to treegrid.
tobiu added the enhancement label on Mar 9, 2026, 11:59 AM
tobiu added the ai label on Mar 9, 2026, 11:59 AM
tobiu added the core label on Mar 9, 2026, 11:59 AM
tobiu added the grid label on Mar 9, 2026, 11:59 AM
tobiu added parent issue #9404 on Mar 9, 2026, 11:59 AM
tobiu
tobiu Mar 9, 2026, 12:09 PM

Input from Gemini 3.1 Pro:

Implementation Guidance for Agents:

  1. ARIA Mapping: The new WAI-ARIA attributes (aria-expanded, aria-level, aria-setsize, aria-posinset) MUST be applied directly to the row container.
  2. Target File: Implement this mapping inside src/grid/Row.mjs within the createVdom() method.
  3. Contiguous Indexing: Do not attempt to calculate complex aria-rowindex logic. Because the TreeStore provides a flattened array of visible nodes, rowIndex + 2 inside Row.mjs will naturally remain contiguous and gapless.
  4. Role: Add an isTreeGrid boolean config to src/grid/Container.mjs. If true, the container's VDOM root should use role: 'treegrid' instead of role: 'grid'.
tobiu assigned to @tobiu on Mar 9, 2026, 12:10 PM
tobiu referenced in commit 4f93b95 - "feat(grid): Core Integration & TreeGrid Accessibility (#9408)" on Mar 9, 2026, 7:16 PM
tobiu cross-referenced by #9422 on Mar 9, 2026, 7:16 PM
tobiu
tobiu Mar 9, 2026, 7:17 PM

Input from Gemini 3.1 Pro:

✦ I have completed the ARIA accessibility mappings for TreeGrids!

  • Added siblingCount and siblingIndex to TreeModel.mjs alongside an architectural note explaining the trade-off.
  • Added isTreeGrid to grid.Container which toggles the role="treegrid".
  • Mapped aria-expanded, aria-level, aria-posinset, and aria-setsize into the VDOM of grid.Row.
  • I have also created a follow-up ticket to address the TreeStore mutation logic as discussed.

Closing this ticket as complete.

tobiu closed this issue on Mar 9, 2026, 7:17 PM