# ngx-pretext-table Variable-height virtual scrolling for PrimeNG `p-table`, powered by [@chenglou/pretext](https://github.com/chenglou/pretext). PrimeNG's built-in virtual scroll only supports **fixed row heights** (`virtualScrollItemSize`). This library replaces it with pretext-calculated variable row heights — no DOM measurement, no layout thrashing, O(log n) scroll lookup. ## Install ```bash npm install ngx-pretext-table @chenglou/pretext ``` ## Usage ```typescript import { Component } from '@angular/core'; import { TableModule } from 'primeng/table'; import { PretextVirtualScrollDirective, PretextScrollEvent, PretextColumnDef, } from 'ngx-pretext-table'; @Component({ standalone: true, imports: [TableModule, PretextVirtualScrollDirective], template: `
{{ row.name }} {{ row.description }}
`, }) export class MyComponent { data = [/* your data */]; // field + available text width (column width minus padding) columns: PretextColumnDef[] = [ { field: 'name', width: 184 }, { field: 'description', width: 384 }, ]; visibleData: any[] = []; rowHeights: number[] = []; onRange(e: PretextScrollEvent) { this.visibleData = this.data.slice(e.start, e.end); this.rowHeights = e.rowHeights; } } ``` ## API ### `PretextVirtualScrollDirective` | Input | Type | Default | Description | |-------|------|---------|-------------| | `data` | `any[]` | required | Full data array | | `columns` | `PretextColumnDef[]` | required | Column field + text width | | `font` | `string` | `'14px system-ui'` | CSS font shorthand | | `lineHeight` | `number` | `20` | Line height in px | | `rowPadding` | `number` | `16` | Vertical padding per row | | `minRowHeight` | `number` | `32` | Minimum row height | | `rowGap` | `number` | `0` | Gap between rows | | `scrollHeight` | `string` | `'400px'` | Viewport height | | `bufferRows` | `number` | `5` | Buffer rows above/below | | Output | Type | Description | |--------|------|-------------| | `visibleRangeChange` | `PretextScrollEvent` | Emits when visible range changes | | Method | Description | |--------|-------------| | `scrollToIndex(index, behavior?)` | Scroll to a specific row | ### `PretextRowHeightService` Low-level service for direct control: ```typescript const cache = service.prepareRows(data, columns, font); const heights = service.calculateRowHeights(cache, columns, lineHeight, padding); const positions = service.buildPositionIndex(heights); const range = service.findVisibleRange(positions, scrollTop, viewportHeight); ``` ## How it works 1. **Prepare** (once) — `@chenglou/pretext` segments text and measures via canvas 2. **Layout** (on resize) — pure arithmetic, ~0.0002ms per cell, no DOM access 3. **Scroll** (continuous) — O(log n) binary search in cumulative position arrays ## License MIT