Skip to content

Virtualize artifacts list with reusable component - #22061

Merged
AmethystLiang merged 1 commit into
mainfrom
virtualize-artifacts-list
Sep 21, 2026
Merged

AmethystLiang merged 1 commit into
mainfrom
virtualize-artifacts-list

Conversation

@AmethystLiang

@AmethystLiang AmethystLiang commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 5 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1351 $\color{#cf222e}{\Huge{\mathbf{−}}}$​84 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1267
Prod 9 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​309 $\color{#cf222e}{\Huge{\mathbf{−}}}$​225 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​84

Problem

The artifacts list renders all rows in the DOM regardless of size, degrading performance with large collections. Virtualization logic exists in source control but is tightly coupled and not reusable.

Solution

Extract virtualization into a generic VirtualizedList component applicable across features. Apply it to artifacts, enabling windowing of large lists. Add support for announcing list position to screen readers and handling paginated lists with "load more" controls.

What Changed

  • Created ArtifactListRow component to extract individual row rendering and actions
  • Refactored ArtifactListRows to use VirtualizedList instead of rendering all rows
  • Moved SourceControlVirtualFileList → VirtualizedList as a reusable component in shared location
  • Renamed SOURCE_CONTROL_* constants to generic VIRTUALIZED_LIST_* equivalents
  • Enhanced VirtualizedList with announceListPosition and hasUnloadedRows options
  • Updated all source control imports to use the new shared component
  • Added comprehensive windowing tests

Why

Centralizes list virtualization logic used by multiple features, enabling code reuse. Artifacts list now windows rows like source control, supporting large collections without performance degradation. Adds accessibility support for announcing list position and handling paginated lists with unknown totals.

Testing

  • I manually tested these changes locally
  • Automated tests added/updated

Comprehensive new tests in artifact-list-windowing.test.tsx and updated virtualized-list.test.tsx covering natural flow below threshold, windowing above threshold, scroll margin handling, row identity preservation, selection/deletion in windowed view, pagination without scroll jump, and accessibility announcements.

Visual Proof

N/A — refactoring for performance and code reuse; no user-facing behavioral change beyond ability to handle larger lists without lag.

Linked Issue

None

Review

No accessibility tree changes for opt-out callers. Preserves scroll position across threshold crossing. Maintains column alignment and row dividers per design system.

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • Before/after screenshots or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass

Extract SourceControlVirtualFileList to a generic VirtualizedList component
and apply windowing to the artifacts table for efficient rendering of large
lists. Add aria-setsize and aria-posinset announcements to windowed rows
when opted in.
@coderabbitai

coderabbitai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Understand this PR’s impact

Explore downstream dependencies and potential security impact with Blast Radius.

View blast radius →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: e112d27a-2978-4c2f-b087-d1be316e4bd8

📥 Commits

Reviewing files that changed from the base of the PR and between f7955e8 and eea267e.

📒 Files selected for processing (14)
  • src/renderer/src/components/artifacts/ArtifactCollection.test.tsx
  • src/renderer/src/components/artifacts/ArtifactCollection.tsx
  • src/renderer/src/components/artifacts/ArtifactListRow.tsx
  • src/renderer/src/components/artifacts/ArtifactListRows.tsx
  • src/renderer/src/components/artifacts/artifact-list-windowing.test.tsx
  • src/renderer/src/components/artifacts/artifacts-table-layout.ts
  • src/renderer/src/components/editor/combined-diff/browse-files/combined-diff-file-tree-rows.tsx
  • src/renderer/src/components/editor/combined-diff/browse-files/combined-diff-file-tree-windowing.test.tsx
  • src/renderer/src/components/right-sidebar/SourceControl.virtual-file-list.test.tsx
  • src/renderer/src/components/right-sidebar/source-control/listing/branch-section.tsx
  • src/renderer/src/components/right-sidebar/source-control/listing/section-file-list.tsx
  • src/renderer/src/components/virtualized-list.test.tsx
  • src/renderer/src/components/virtualized-list.tsx
  • src/renderer/src/lib/list-table-layout.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The shared virtualized list is renamed and extended with optional list-position announcements and scroll-offset preservation. The artifact collection now uses windowed rows through a new ArtifactListRow component, with pagination-aware ARIA set sizes and shared row actions. Combined-diff and source-control consumers and tests migrate to the shared component. Extensive tests cover virtualization, selection, menus, resizing, scrolling, row identity, and threshold transitions.

Priority: ➖ Normal

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the problem, solution, changes, rationale, testing, visual proof, and checklist. However, the required Linked Issue section states "None," although the template requires an issu… Add the issue reference in the Linked Issue section, using the required format such as Fixes #1234``. If no issue exists, create or identify the issue before merging.
Docstring Coverage ⚠️ Warning Docstring coverage is 52.46% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 61 functions across 14 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary changes: applying virtualization to the artifacts list and extracting a reusable component.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description covers the problem, solution, changes, rationale, testing, visual proof, and checklist. However, the required Linked Issue section states "None," although the template requires an issue link.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

The component move left one consumer behind. ConflictReviewFileTree still imports the deleted source-control/listing/virtual-file-list, so the renderer build and the conflict-review test suite both fail to resolve the module.

Reviewed changes

  • Extracted VirtualizedList — the source-control list implementation moved to src/renderer/src/components/virtualized-list.tsx, its SOURCE_CONTROL_* constants renamed to VIRTUALIZED_LIST_*, and the combined-diff / branch-section / section-file-list call sites now import the shared component.
  • Virtualized the artifacts table — ArtifactListRow extracted, ArtifactListRows now windows through VirtualizedList, and the parent divide-y band was replaced by a per-row LIST_TABLE_ROW_DIVIDER_CLASS.
  • Added list-position announcements — opt-in announceListPosition adds role="list" / listitem plus aria-setsize / aria-posinset, and hasUnloadedRows publishes -1 while a server cursor remains.
  • Kept scroll position across threshold crossing — initialOffset seeds the virtualizer from the scroller's current offset, with tests covering append, search clear, and the exact 49→50 boundary.
  • Test coverage — a large new artifact-list-windowing.test.tsx derives row geometry from the row's own classes, plus updates to the virtualized-list and source-control suites.

🚨 Conflict review file tree still imports the removed module

ConflictReviewFileTree.tsx:12 imports SourceControlVirtualFileList from @/components/right-sidebar/source-control/listing/virtual-file-list, which this PR moved to @/components/virtualized-list. That is a production editor surface (reached from ConflictComponents.tsx:17), so the renderer build cannot resolve the module. The companion conflict-review-file-tree-windowing.test.tsx imports the same deleted module and also still queries the old [data-testid="source-control-virtual-list"].

Technical details
# Dangling `source-control/listing/virtual-file-list` imports after the move

## Affected sites
- `src/renderer/src/components/editor/ConflictReviewFileTree.tsx:12` — imports `SourceControlVirtualFileList` from the removed module and uses it at line 106.
- `src/renderer/src/components/editor/conflict-review-file-tree-windowing.test.tsx:6-9` — imports `SOURCE_CONTROL_FILE_ROW_OVERSCAN` and `SOURCE_CONTROL_VIRTUALIZE_MIN_ROWS` from the removed module.
- `src/renderer/src/components/editor/conflict-review-file-tree-windowing.test.tsx:87,248,327,382,600,682` — query `[data-testid="source-control-virtual-list"]`, which is now `virtualized-list`.

## Required outcome
- `ConflictReviewFileTree` compiles against the shared `VirtualizedList` and its windowing test suite resolves and passes.
- No reference to the removed module path or the old test id remains anywhere in the repo.

## Suggested approach
- In `ConflictReviewFileTree.tsx`, import `{ VirtualizedList }` from `@/components/virtualized-list` and rename the JSX usage.
- In the windowing test, import `{ VIRTUALIZED_LIST_OVERSCAN, VIRTUALIZED_LIST_MIN_ROWS }` from `@/components/virtualized-list` and switch the selector to `[data-testid="virtualized-list"]`.

## Evidence
- `pnpm vitest run src/renderer/src/components/editor/conflict-review-file-tree-windowing.test.tsx` fails at transform with `Failed to resolve import "@/components/right-sidebar/source-control/listing/virtual-file-list"`.

ℹ️ Nitpicks

  • SourceControl.virtual-file-list.test.tsx still carries the old component name in its filename and describes itself in terms of source control, though it now exercises the shared VirtualizedList; renaming it would keep the move honest.
  • announceListPosition produces list semantics only in the virtualized path, so an artifacts list announces a list at 50+ rows and no list below that. The comment calls this out as intentional — worth a quick confirmation that the screen-reader discontinuity is acceptable.

Pullfrog  | Fix it ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@AmethystLiang
AmethystLiang merged commit 7047cdc into main Sep 21, 2026
21 of 31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant