LearnNewsExamplesServices
Frontmatter
id8980
titleFix Grid Keyboard Navigation and Focus Layout Shift
stateClosed
labels
bugairefactoring
assigneestobiu
createdAtFeb 4, 2026, 12:31 PM
updatedAtFeb 4, 2026, 12:32 PM
githubUrlhttps://github.com/neomjs/neo/issues/8980
authortobiu
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtFeb 4, 2026, 12:32 PM

Fix Grid Keyboard Navigation and Focus Layout Shift

Closed v12.0.0 bugairefactoring
tobiu
tobiu commented on Feb 4, 2026, 12:31 PM

Problem: Keyboard navigation in the grid is broken. Selecting a row or cell no longer triggers focus on the grid body wrapper, preventing KeyNavigation from capturing arrow key events. Additionally, focusing the body wrapper manually causes a layout shift where the header toolbar is scrolled out of view.

Scope:

  1. Focus Restoration: Ensure GridBody receives focus on row/cell clicks.
  2. Layout Stability: Implement preventScroll support for focus() to stop the browser from scrolling the parent container.

Changes Required:

  • src/main/DomAccess.mjs: Update focus to support preventScroll.
  • src/component/Base.mjs: Update focus signature to pass preventScroll.
  • src/grid/Body.mjs: Call this.focus(this.vdom.id, false, true) in onRowClick.
tobiu added the bug label on Feb 4, 2026, 12:31 PM
tobiu added the ai label on Feb 4, 2026, 12:31 PM
tobiu added the refactoring label on Feb 4, 2026, 12:31 PM
tobiu referenced in commit 830bbb5 - "fix: Restore Grid keyboard navigation and prevent layout shift on focus (#8980)" on Feb 4, 2026, 12:31 PM
tobiu
tobiu Feb 4, 2026, 12:31 PM

Input from Gemini 3 Pro:

Fixed Grid Keyboard Navigation & Layout Stability

  1. Focus Restoration:

    • Updated GridBody.onRowClick to explicitly call this.focus(this.vdom.id). This ensures the grid wrapper (which has tabIndex="-1") receives focus upon interaction, re-enabling keyboard navigation events.
  2. Layout Shift Prevention:

    • Identified that focusing the grid body caused the browser to scroll the parent GridContainer, pushing the HeaderToolbar out of view.
    • Updated Neo.main.DomAccess.focus to support the {preventScroll: true} option for the native HTMLElement.focus() method.
    • Updated Neo.component.Base.focus to accept and pass the preventScroll argument.
    • Applied preventScroll: true to the GridBody focus call.

This resolves the regression where row selection broke arrow-key navigation and caused visual jarring.

tobiu assigned to @tobiu on Feb 4, 2026, 12:31 PM
tobiu closed this issue on Feb 4, 2026, 12:32 PM