react-spectrum
e6de3d7f - fix(useGridState): prevent infinite loop restoring focus when no focusable row remains (#10241)

Commit
7 days ago
fix(useGridState): prevent infinite loop restoring focus when no focusable row remains (#10241) * fix: prevent infinite loop in useGridState focus restoration When the focused row is removed from the collection, the focus-restoration effect searches collection.rows for a non-disabled, non-headerrow row to move focus to. The single loop walked forward to the end, then jumped back to parentNode.index and decremented — but the next iteration's `index < rows.length - 1` check sent it forward again, so when every row in the search range was disabled (or a headerrow) it bounced between parentNode.index and the end forever and never reached `index < 0`. This hangs the main thread (e.g. a table whose only rows are disabled loading skeletons while a row is focused). Replace the bouncing loop with two bounded passes — forward from the start index, then backward — mirroring the already-correct walk in useListState. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: guard empty rows in useGridState focus restoration Start the forward scan at Math.max(0, index) so an empty rows array (index === -1 from Math.min(..., rows.length - 1)) no longer reads rows[-1], matching the old `while (index >= 0)` no-op. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test: focus restoration does not hang when no focusable row remains Removing the focused row while every remaining row is disabled previously infinite-looped in useGridState's focus restoration. Without the fix this test hangs; with it, focus is cleared and the render completes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: satisfy oxfmt formatting in regression test Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: trim bug-history narration from focus-restoration comment Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Remove redundant comment Co-authored-by: Robert Snow <snowystinger@gmail.com> * refactor(useGridState): use strict equality for focus-restoration null check newRow is only ever null or a GridNode (never undefined), so `=== null` is equivalent to `== null` here. Addresses review feedback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Robert Snow <snowystinger@gmail.com>
Author
Parents
Loading