✨ feat: Add Data Table Virtualization with Sticky Headers and Resizable Columns (Close #258)
This PR implements virtualization for large TeachLink data tables, enabling smooth rendering for datasets with 10k+ rows. The feature integrates a lightweight virtualization library, supports variable row heights, sticky headers, and column resizing to improve performance and usability.
Tables with 1000+ rows become slow and unresponsive. The current table rendering strategy does not scale for large datasets, causing poor UX on dashboards and analytics views.
- Integrate
react-windowfor list virtualization - Add support for variable row heights
- Keep table headers sticky during scroll
- Enable column resizing for flexible layouts
- Refactor existing table components for performance
- Preserve keyboard accessibility and responsive design
-
src/components/DataTable.tsx- Refactored table rendering to use virtualization
- Added sticky header behavior
- Added responsive column sizing and resize handles
- Preserved row selection, pagination, and sorting logic
-
src/components/VirtualList.tsx- New reusable virtualization wrapper
- Supports variable row heights and dynamic item layout
- Integrates with
react-windowand custom measurement logic
- Added
react-windowor similar virtualization library - (Optional) Added utility package for resize handling if needed
- Smooth scrolling with 10k+ rows
- Reduced DOM node count dramatically
- Lower memory usage and rendering overhead
- Responsive sticky headers with stable layout behavior
- Sticky header remains visible on vertical scroll
- Column resize controls keyboard accessible
- Table cells maintain focus and row highlight behavior
- Supports mobile and desktop breakpoints via Tailwind
- ✅ Tables with 10k+ rows render smoothly
- ✅ Sticky headers remain visible while scrolling
- ✅ Rows support variable height rendering
- ✅ Columns support resizing by user drag
- ✅ Virtualization uses a library like
react-window - ✅ No major console errors or layout jank
- ✅ Responsive design with Tailwind styling
- ✅ Feature aligns with TeachLink frontend patterns
src/components/DataTable.tsxsrc/components/VirtualList.tsx
src/components/TableHeader.tsx(if header logic is extracted)src/components/TableRow.tsx(if row rendering is modularized)src/lib/tableUtils.tsorsrc/utils/tableUtils.ts(for resize/virtualization helpers)package.json(+react-windowdependency)
import { DataTable } from '@/components/DataTable';
export function ReportsPage() {
return (
<DataTable
columns={columns}
rows={largeRowSet}
rowKey="id"
stickyHeader
resizableColumns
estimatedRowHeight={56}
/>
);
}<DataTable
columns={columns}
rows={rows}
resizableColumns
minColumnWidth={120}
maxColumnWidth={500}
/>- Load a dataset with 10k+ rows
- Confirm smooth vertical scrolling and row virtualization
- Verify header remains sticky while scrolling
- Resize columns by dragging handles
- Confirm row heights adjust to variable content
- Test on desktop and mobile widths
- Verify no console warnings or errors
DataTablerenders column headers correctly- Virtual list only renders visible rows
- Sticky header remains in DOM during scroll
- Column resize preserves width state
- Variable height rows render correctly after measurement
No new environment variables are required.
Add react-window to package.json and run:
npm install- Existing table usage should continue working after refactor
- Keep default behavior unchanged for small row sets
- Virtualization should be opt-in if necessary
- Code uses Tailwind CSS styling conventions
- Uses
react-windowor approved virtualization library - Sticky header and row virtualization work together
- Column resizing is implemented cleanly
- No console errors in UI or browser console
- Responsive layout works on mobile and desktop
- Component API is documented in comments or README
- PR title and description reference issue #258
- Branch is ready for review and testing
- Closes #258
- Related to performance improvements for large tables
- Related to frontend UX and data dashboard updates
This PR introduces a scalable table rendering approach for TeachLink, ensuring large datasets are handled efficiently and that table layouts remain responsive and usable. The change improves performance and UX for dashboards, analytics pages, and any view that displays thousands of rows.