@@ -16,7 +16,8 @@ const middleRowFocusOption = 'middleRowFocus' as const;
1616export class MiddleRowFocus extends Module {
1717 static moduleName = 'middleRowFocus' ;
1818
19- goToRowId : number = 0 ;
19+ tableHolder : HTMLElement | null = null ;
20+ middleRow : RowComponent | null = null ;
2021 constructor ( table : Tabulator ) {
2122 super ( table ) ;
2223 this . registerTableOption ( middleRowFocusOption , false ) ;
@@ -25,60 +26,64 @@ export class MiddleRowFocus extends Module {
2526 initialize ( ) {
2627 // @ts -expect-error not in types
2728 if ( this . options ( middleRowFocusOption ) ) {
29+ this . tableHolder = this . table . element . querySelector ( '.tabulator-tableholder' ) ;
30+
2831 this . table . on ( 'dataTreeRowExpanded' , ( ) => {
29- window . clearTimeout ( this . goToRowId ) ;
30- middleRow = null ;
32+ this . _clearFocusRow ( ) ;
3133 } ) ;
3234
3335 this . table . on ( 'dataTreeRowCollapsed' , ( ) => {
34- window . clearTimeout ( this . goToRowId ) ;
35- middleRow = null ;
36+ this . _clearFocusRow ( ) ;
3637 } ) ;
3738
38- let middleRow : RowComponent | null ;
3939 this . table . on ( 'renderStarted' , ( ) => {
40- if ( this . table && ! middleRow ) {
41- middleRow = this . _findMiddleVisibleRow ( this . table ) ;
40+ if ( this . table && this . tableHolder && ! this . middleRow ) {
41+ this . middleRow = this . _findMiddleVisibleRow ( this . tableHolder ) ;
4242 }
4343 } ) ;
4444
4545 this . table . on ( 'renderComplete' , async ( ) => {
46- const rowToScrollTo = middleRow ;
47- this . goToRowId = this . _scrollToRow ( rowToScrollTo ) ;
48- middleRow = null ;
46+ const rowToScrollTo = this . middleRow ;
47+ this . _scrollToRow ( rowToScrollTo ) ;
48+ this . middleRow = null ;
4949 } ) ;
5050 }
5151 }
5252
53- private _scrollToRow ( row : RowComponent | null ) : number {
53+ private _clearFocusRow ( ) {
54+ this . middleRow = null ;
55+ }
56+
57+ private _scrollToRow ( row : RowComponent | null ) {
5458 if ( ! row ) {
55- return 0 ;
59+ return ;
5660 }
57- return window . setTimeout ( ( ) => {
58- let rowToScrollTo : RowComponent | null = row ;
59- if ( rowToScrollTo ) {
60- //@ts -expect-error This is private to tabulator, but we have no other choice atm.
61- const internalRow = rowToScrollTo . _getSelf ( ) ;
62- const displayRows = internalRow . table . rowManager . getDisplayRows ( ) ;
63- const canScroll = displayRows . indexOf ( internalRow ) !== - 1 ;
64- if ( ! canScroll ) {
65- const rowData = rowToScrollTo . getData ( ) as TimedNodeProp ;
66- const node = rowData . originalData ;
67-
68- rowToScrollTo = this . _findClosestActive ( this . table . getRows ( 'active' ) , node . timestamp ) ;
69- }
7061
71- if ( rowToScrollTo ) {
72- this . table . scrollToRow ( rowToScrollTo , 'center' , true ) . then ( ( ) => {
62+ let rowToScrollTo : RowComponent | null = row ;
63+ if ( rowToScrollTo ) {
64+ const displayRows = this . table . rowManager . getDisplayRows ( ) ;
65+ //@ts -expect-error This is private to tabulator, but we have no other choice atm.
66+ const internalRow = rowToScrollTo . _getSelf ( ) ;
67+ const canScroll = displayRows . indexOf ( internalRow ) !== - 1 ;
68+ if ( ! canScroll ) {
69+ const rowData = rowToScrollTo . getData ( ) as TimedNodeProp ;
70+ const node = rowData . originalData ;
71+
72+ rowToScrollTo = this . _findClosestActive ( this . table . getRows ( 'active' ) , node . timestamp ) ;
73+ }
74+
75+ if ( rowToScrollTo ) {
76+ this . table . scrollToRow ( rowToScrollTo , 'center' , true ) . then ( ( ) => {
77+ setTimeout ( ( ) => {
7378 if ( rowToScrollTo ) {
7479 rowToScrollTo
7580 ?. getElement ( )
7681 . scrollIntoView ( { behavior : 'auto' , block : 'center' , inline : 'start' } ) ;
7782 }
7883 } ) ;
79- }
84+ } ) ;
8085 }
81- } ) ;
86+ }
8287 }
8388
8489 private _findClosestActive ( rows : RowComponent [ ] , timeStamp : number ) : RowComponent | null {
@@ -90,6 +95,7 @@ export class MiddleRowFocus extends Module {
9095 end = rows . length - 1 ;
9196
9297 // Iterate as long as the beginning does not encounter the end.
98+ const displayRows = this . table . rowManager . getDisplayRows ( ) ;
9399 while ( start <= end ) {
94100 // find out the middle index
95101 const mid = Math . floor ( ( start + end ) / 2 ) ;
@@ -99,13 +105,11 @@ export class MiddleRowFocus extends Module {
99105 break ;
100106 }
101107 const node = ( row . getData ( ) as TimedNodeProp ) . originalData ;
102-
103- //@ts -expect-error This is private to tabulator, but we have no other choice atm.
104- const internalRow = row . _getSelf ( ) ;
105- const displayRows = internalRow . table . rowManager . getDisplayRows ( ) ;
106108 const endTime = node . exitStamp ?? node . timestamp ;
107109
108110 if ( timeStamp === node . timestamp ) {
111+ //@ts -expect-error This is private to tabulator, but we have no other choice atm.
112+ const internalRow = row . _getSelf ( ) ;
109113 const isActive = displayRows . indexOf ( internalRow ) !== - 1 ;
110114 if ( isActive ) {
111115 return row ;
@@ -187,13 +191,16 @@ export class MiddleRowFocus extends Module {
187191 return closestIndex ? rows [ closestIndex ] || null : null ;
188192 }
189193
190- private _findMiddleVisibleRow ( table : Tabulator ) {
191- const visibleRows = table . getRows ( 'visible' ) ;
192- if ( visibleRows . length === 1 ) {
193- return visibleRows [ 0 ] || null ;
194+ private _findMiddleVisibleRow ( tableHolder : HTMLElement ) {
195+ const visibleRows = this . table . getRows ( 'visible' ) ;
196+ const len = visibleRows . length ;
197+ if ( len === 0 ) {
198+ return null ;
199+ } else if ( len === 1 ) {
200+ return visibleRows [ 0 ] ?? null ;
194201 }
195202
196- const tableRect = table . element . getBoundingClientRect ( ) ;
203+ const tableRect = tableHolder . getBoundingClientRect ( ) ;
197204 const totalHeight = Math . round ( tableRect . height / 2 ) ;
198205
199206 let currentHeight = 0 ;
0 commit comments