8
8
useI18nBundle ,
9
9
useIsomorphicId ,
10
10
useIsomorphicLayoutEffect ,
11
- useIsRTL
11
+ useIsRTL ,
12
+ useSyncRef
12
13
} from '@ui5/webcomponents-react-base' ;
13
14
import { clsx } from 'clsx' ;
14
15
import type { CSSProperties , MutableRefObject } from 'react' ;
@@ -175,10 +176,9 @@ const AnalyticalTable = forwardRef<AnalyticalTableDomRef, AnalyticalTablePropTyp
175
176
176
177
const classes = useStyles ( ) ;
177
178
178
- const [ analyticalTableRef , scrollToRef ] = useTableScrollHandles ( ref ) ;
179
179
const tableRef = useRef < DivWithCustomScrollProp > ( null ) ;
180
-
181
- const isRtl = useIsRTL ( analyticalTableRef ) ;
180
+ const parentRef = useRef < DivWithCustomScrollProp > ( null ) ;
181
+ const verticalScrollBarRef = useRef < DivWithCustomScrollProp > ( null ) ;
182
182
183
183
const getSubRows = useCallback ( ( row ) => getSubRowsByString ( subRowsKey , row ) || [ ] , [ subRowsKey ] ) ;
184
184
@@ -228,7 +228,6 @@ const AnalyticalTable = forwardRef<AnalyticalTableDomRef, AnalyticalTablePropTyp
228
228
markNavigatedRow,
229
229
renderRowSubComponent,
230
230
alwaysShowSubComponent,
231
- scrollToRef,
232
231
showOverlay,
233
232
uniqueId,
234
233
subRowsKey,
@@ -275,6 +274,40 @@ const AnalyticalTable = forwardRef<AnalyticalTableDomRef, AnalyticalTablePropTyp
275
274
setGlobalFilter
276
275
} = tableInstanceRef . current ;
277
276
const tableState : AnalyticalTableState = tableInstanceRef . current . state ;
277
+ const { triggerScroll } = tableState ;
278
+
279
+ const [ componentRef , updatedRef ] = useSyncRef < AnalyticalTableDomRef > ( ref ) ;
280
+ //@ts -expect-error: types are compatible
281
+ const isRtl = useIsRTL ( updatedRef ) ;
282
+
283
+ const columnVirtualizer = useVirtualizer ( {
284
+ count : visibleColumnsWidth . length ,
285
+ getScrollElement : ( ) => tableRef . current ,
286
+ estimateSize : useCallback ( ( index ) => visibleColumnsWidth [ index ] , [ visibleColumnsWidth ] ) ,
287
+ horizontal : true ,
288
+ overscan : isRtl ? Infinity : overscanCountHorizontal ,
289
+ indexAttribute : 'data-column-index' ,
290
+ // necessary as otherwise values are rounded which leads to wrong total width calculation leading to unnecessary scrollbar
291
+ measureElement : ! scaleXFactor || scaleXFactor === 1 ? ( el ) => el . getBoundingClientRect ( ) . width : undefined
292
+ } ) ;
293
+ const [ analyticalTableRef , scrollToRef ] = useTableScrollHandles ( updatedRef , dispatch ) ;
294
+
295
+ if ( parentRef . current ) {
296
+ scrollToRef . current = {
297
+ ...scrollToRef . current ,
298
+ horizontalScrollToOffset : columnVirtualizer . scrollToOffset ,
299
+ horizontalScrollToIndex : columnVirtualizer . scrollToIndex
300
+ } ;
301
+ }
302
+ useEffect ( ( ) => {
303
+ if ( triggerScroll && triggerScroll . direction === 'horizontal' ) {
304
+ if ( triggerScroll . type === 'offset' ) {
305
+ columnVirtualizer . scrollToOffset ( ...triggerScroll . args ) ;
306
+ } else {
307
+ columnVirtualizer . scrollToIndex ( ...triggerScroll . args ) ;
308
+ }
309
+ }
310
+ } , [ triggerScroll ] ) ;
278
311
279
312
const includeSubCompRowHeight =
280
313
! ! renderRowSubComponent &&
@@ -543,40 +576,27 @@ const AnalyticalTable = forwardRef<AnalyticalTableDomRef, AnalyticalTablePropTyp
543
576
}
544
577
} , [ tableState . columnResizing , retainColumnWidth , tableState . tableColResized ] ) ;
545
578
546
- const parentRef = useRef < DivWithCustomScrollProp > ( null ) ;
547
- const verticalScrollBarRef = useRef < DivWithCustomScrollProp > ( null ) ;
548
-
549
579
const handleBodyScroll = ( e ) => {
550
580
if ( typeof onTableScroll === 'function' ) {
551
581
onTableScroll ( e ) ;
552
582
}
553
- if ( verticalScrollBarRef . current && verticalScrollBarRef . current . scrollTop !== parentRef . current . scrollTop ) {
554
- if ( ! parentRef . current . isExternalVerticalScroll ) {
555
- verticalScrollBarRef . current . scrollTop = parentRef . current . scrollTop ;
583
+ const targetScrollTop = e . currentTarget . scrollTop ;
584
+ if ( verticalScrollBarRef . current && verticalScrollBarRef . current . scrollTop !== targetScrollTop ) {
585
+ if ( ! e . currentTarget . isExternalVerticalScroll ) {
586
+ verticalScrollBarRef . current . scrollTop = targetScrollTop ;
556
587
verticalScrollBarRef . current . isExternalVerticalScroll = true ;
557
588
}
558
- parentRef . current . isExternalVerticalScroll = false ;
589
+ e . currentTarget . isExternalVerticalScroll = false ;
559
590
}
560
591
} ;
561
592
562
- const handleVerticalScrollBarScroll = ( ) => {
563
- if ( parentRef . current && ! verticalScrollBarRef . current . isExternalVerticalScroll ) {
564
- parentRef . current . scrollTop = verticalScrollBarRef . current . scrollTop ;
593
+ const handleVerticalScrollBarScroll = useCallback ( ( e ) => {
594
+ if ( parentRef . current && ! e . currentTarget . isExternalVerticalScroll ) {
595
+ parentRef . current . scrollTop = e . currentTarget . scrollTop ;
565
596
parentRef . current . isExternalVerticalScroll = true ;
566
597
}
567
- verticalScrollBarRef . current . isExternalVerticalScroll = false ;
568
- } ;
569
-
570
- const columnVirtualizer = useVirtualizer ( {
571
- count : visibleColumnsWidth . length ,
572
- getScrollElement : ( ) => tableRef . current ,
573
- estimateSize : useCallback ( ( index ) => visibleColumnsWidth [ index ] , [ visibleColumnsWidth ] ) ,
574
- horizontal : true ,
575
- overscan : isRtl ? Infinity : overscanCountHorizontal ,
576
- indexAttribute : 'data-column-index' ,
577
- // necessary as otherwise values are rounded which leads to wrong total width calculation leading to unnecessary scrollbar
578
- measureElement : ! scaleXFactor || scaleXFactor === 1 ? ( el ) => el . getBoundingClientRect ( ) . width : undefined
579
- } ) ;
598
+ e . currentTarget . isExternalVerticalScroll = false ;
599
+ } , [ ] ) ;
580
600
581
601
useEffect ( ( ) => {
582
602
columnVirtualizer . measure ( ) ;
@@ -592,12 +612,6 @@ const AnalyticalTable = forwardRef<AnalyticalTableDomRef, AnalyticalTablePropTyp
592
612
showVerticalEndBorder && classes . showVerticalEndBorder
593
613
) ;
594
614
595
- scrollToRef . current = {
596
- ...scrollToRef . current ,
597
- horizontalScrollToOffset : columnVirtualizer . scrollToOffset ,
598
- horizontalScrollToIndex : columnVirtualizer . scrollToIndex
599
- } ;
600
-
601
615
const handleOnLoadMore = ( e ) => {
602
616
const rootNodes = rows . filter ( ( row ) => row . depth === 0 ) ;
603
617
onLoadMore (
@@ -610,7 +624,13 @@ const AnalyticalTable = forwardRef<AnalyticalTableDomRef, AnalyticalTablePropTyp
610
624
611
625
return (
612
626
< >
613
- < div className = { className } style = { inlineStyle } ref = { analyticalTableRef } { ...rest } >
627
+ < div
628
+ className = { className }
629
+ style = { inlineStyle }
630
+ //@ts -expect-error: types are compatible
631
+ ref = { componentRef }
632
+ { ...rest }
633
+ >
614
634
{ header && (
615
635
< TitleBar ref = { titleBarRef } titleBarId = { titleBarId } >
616
636
{ header }
@@ -723,6 +743,7 @@ const AnalyticalTable = forwardRef<AnalyticalTableDomRef, AnalyticalTablePropTyp
723
743
manualGroupBy = { reactTableOptions ?. manualGroupBy as boolean | undefined }
724
744
subRowsKey = { subRowsKey }
725
745
subComponentsBehavior = { subComponentsBehavior }
746
+ triggerScroll = { tableState . triggerScroll }
726
747
/>
727
748
</ VirtualTableBodyContainer >
728
749
) }
@@ -736,6 +757,7 @@ const AnalyticalTable = forwardRef<AnalyticalTableDomRef, AnalyticalTablePropTyp
736
757
ref = { verticalScrollBarRef }
737
758
data-native-scrollbar = { props [ 'data-native-scrollbar' ] }
738
759
scrollContainerRef = { scrollContainerRef }
760
+ parentRef = { parentRef }
739
761
/>
740
762
) }
741
763
</ FlexBox >
0 commit comments