Adds windowed rendering to FilesView in ReviewSidebar.tsx using
react-window 2.x (List component). File lists with more than 50 rows
render only visible items, keeping the DOM lean for large diffs.
- Install react-window 2.x and @types/react-window in apps/web
- Flatten directory-grouped file tree into a typed Row[] array via useMemo
- Use VariableSizeList-equivalent react-window 2.x List with rowHeight fn
(32px for dir-headers, 40px for file rows); falls back to plain DOM
render for ≤50 rows to avoid overhead on small diffs
- Directories are collapsible: clicking the dir-header toggles collapse,
removing its file rows from the Row[] and from the virtual list
- Preserve sidebar scroll offset across Files ↔ Commits tab switches via
filesScrollOffsetRef passed from ReviewSidebar into FilesView
- Clicking a file calls listRef.scrollToRow({ index, align: "smart" })
to keep the clicked row visible in the virtual list
- Root-level files (directory === "") render without a dir-header,
preserving existing behavior
- Add resolve.dedupe for react/react-dom in vitest.config.ts to prevent
duplicate-React errors after local workspace package installation
- Add 6 Vitest + RTL tests covering: large-list DOM count, small-list
fallback, collapse, re-expand, tab-switch smoke, root-level files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
36 lines
1.0 KiB
TypeScript
36 lines
1.0 KiB
TypeScript
import { defineConfig } from 'vitest/config';
|
|
import react from '@vitejs/plugin-react';
|
|
import path from 'node:path';
|
|
|
|
export default defineConfig({
|
|
plugins: [react()],
|
|
resolve: {
|
|
alias: {
|
|
'@': path.resolve(__dirname, './apps/web/src'),
|
|
},
|
|
// Deduplicate React to avoid "multiple copies" errors when packages
|
|
// installed in workspace sub-directories shadow the hoisted copies.
|
|
dedupe: ['react', 'react-dom'],
|
|
},
|
|
test: {
|
|
// Enable test globals (describe, it, expect without imports)
|
|
globals: true,
|
|
env: {
|
|
CW_LOG_LEVEL: 'silent',
|
|
},
|
|
// Test file pattern
|
|
include: ['**/*.test.ts', '**/*.test.tsx'],
|
|
exclude: ['**/node_modules/**', '**/dist/**', 'packages/**'],
|
|
environmentMatchGlobs: [
|
|
['apps/web/**', 'happy-dom'],
|
|
],
|
|
// TypeScript support uses tsconfig.json automatically
|
|
// Coverage reporter (optional, for future use)
|
|
coverage: {
|
|
provider: 'v8',
|
|
reporter: ['text', 'json', 'html'],
|
|
reportsDirectory: './apps/server/coverage',
|
|
},
|
|
},
|
|
});
|