@@ -14,7 +14,6 @@ import { DEBUG, BROWSER_MAX_HEIGHT } from "./constants";
1414import type { RegularTableViewModel } from "./table" ;
1515import { RegularTableElement } from "./regular-table" ;
1616import {
17- CellTuple ,
1817 ColumnSizes ,
1918 StyleCallback ,
2019 ContainerSize ,
@@ -95,6 +94,7 @@ export class RegularVirtualTableViewModel extends HTMLElement {
9594 protected _is_styling ?: boolean ;
9695 protected table_model ! : RegularTableViewModel ;
9796 protected _style_callbacks ! : Array < StyleCallback > ;
97+ protected _scroll_pending ?: boolean ;
9898 private _probe_element ?: [ HTMLElement , HTMLElement ] ;
9999
100100 /**
@@ -121,7 +121,11 @@ export class RegularVirtualTableViewModel extends HTMLElement {
121121 * Await any pending rendering operations.
122122 */
123123 async flush ( ) : Promise < void > {
124- await flush_tag ( this ) ;
124+ // A scroll-driven draw may still be waiting on its animation frame
125+ // (see `_on_scroll`); keep flushing until none is pending.
126+ do {
127+ await flush_tag ( this ) ;
128+ } while ( this . _scroll_pending ) ;
125129 }
126130
127131 /**
@@ -309,10 +313,7 @@ export class RegularVirtualTableViewModel extends HTMLElement {
309313 *
310314 * @param viewport
311315 */
312- protected _update_sub_cell_offset (
313- viewport : Viewport ,
314- last_cell ?: CellTuple ,
315- ) : void {
316+ protected _update_sub_cell_offset ( viewport : Viewport ) : void {
316317 const y_offset =
317318 ( this . _column_sizes . row_height || 0 ) * ( viewport . start_row % 1 ) ||
318319 0 ;
@@ -321,13 +322,9 @@ export class RegularVirtualTableViewModel extends HTMLElement {
321322 ( this . table_model . _row_headers_length || 0 ) +
322323 Math . floor ( viewport . start_col ) ;
323324
324- if ( this . _column_sizes . indices [ x_offset_index ] === undefined ) {
325- this . _column_sizes . indices [ x_offset_index ] =
326- last_cell ?. [ 0 ] ?. offsetWidth || 0 ;
327- }
328-
329325 const x_offset =
330- this . _column_sizes . indices [ x_offset_index ] ! *
326+ ( this . _column_sizes . indices [ x_offset_index ] ??
327+ this . table_model . _estimated_column_width ( ) ) *
331328 ( viewport . start_col % 1 ) || 0 ;
332329
333330 this . _sub_cell_rule . style . setProperty ( CLIP_X , `${ x_offset } px` ) ;
@@ -592,12 +589,12 @@ async function internal_draw(
592589 preserve_width ,
593590 viewport ,
594591 safe_num_columns ,
595- async ( last_cells ) => {
592+ async ( ) => {
596593 // We want to perform this before the next event loop so there
597594 // is no scroll jitter, but only on the first iteration as
598595 // subsequent viewports are incorrect.
599596 if ( first_iteration ) {
600- this . _update_sub_cell_offset ( viewport , last_cells ) ;
597+ this . _update_sub_cell_offset ( viewport ) ;
601598 first_iteration = false ;
602599 }
603600
@@ -607,6 +604,10 @@ async function internal_draw(
607604 } ,
608605 ) ;
609606
607+ // Re-apply with post-measurement widths, in case the first
608+ // application used an estimate for a never-measured leading column.
609+ this . _update_sub_cell_offset ( viewport ) ;
610+
610611 const old_height = this . _column_sizes . row_height ;
611612 this . table_model . header . reset_header_cache ( ) ;
612613 if ( old_height !== this . _column_sizes . row_height ) {
0 commit comments