@@ -73,7 +73,6 @@ import type CheckBox from "./CheckBox.js";
73
73
import type RadioButton from "./RadioButton.js" ;
74
74
import { isInstanceOfListItemGroup } from "./ListItemGroup.js" ;
75
75
import type ListItemGroup from "./ListItemGroup.js" ;
76
- import { findVerticalScrollContainer } from "./TableUtils.js" ;
77
76
78
77
const INFINITE_SCROLL_DEBOUNCE_RATE = 250 ; // ms
79
78
@@ -525,17 +524,17 @@ class List extends UI5Element {
525
524
static i18nBundle : I18nBundle ;
526
525
_previouslyFocusedItem : ListItemBase | null ;
527
526
_forwardingFocus : boolean ;
528
- listEndObserved : boolean ;
529
- _handleResizeCallback : ResizeObserverCallback ;
530
- initialIntersection : boolean ;
531
527
_selectionRequested ?: boolean ;
532
528
_groupCount : number ;
533
529
_groupItemCount : number ;
534
- growingIntersectionObserver ?: IntersectionObserver | null ;
530
+ _endIntersectionObserver ?: IntersectionObserver | null ;
531
+ _startIntersectionObserver ?: IntersectionObserver | null ;
535
532
_itemNavigation : ItemNavigation ;
536
533
_beforeElement ?: HTMLElement | null ;
537
534
_afterElement ?: HTMLElement | null ;
535
+ _startMarkerOutOfView : boolean = false ;
538
536
537
+ handleResizeCallback : ResizeObserverCallback ;
539
538
onItemFocusedBound : ( e : CustomEvent ) => void ;
540
539
onForwardAfterBound : ( e : CustomEvent ) => void ;
541
540
onForwardBeforeBound : ( e : CustomEvent ) => void ;
@@ -551,20 +550,14 @@ class List extends UI5Element {
551
550
// Indicates that the List is forwarding the focus before or after the internal ul.
552
551
this . _forwardingFocus = false ;
553
552
554
- // Indicates if the IntersectionObserver started observing the List
555
- this . listEndObserved = false ;
556
-
557
553
this . _itemNavigation = new ItemNavigation ( this , {
558
554
skipItemsSize : PAGE_UP_DOWN_SIZE , // PAGE_UP and PAGE_DOWN will skip trough 10 items
559
555
navigationMode : NavigationMode . Vertical ,
560
556
getItemsCallback : ( ) => this . getEnabledItems ( ) ,
561
557
} ) ;
562
558
563
- this . _handleResizeCallback = this . _handleResize . bind ( this ) ;
559
+ this . handleResizeCallback = this . _handleResize . bind ( this ) ;
564
560
565
- // Indicates the List bottom most part has been detected by the IntersectionObserver
566
- // for the first time.
567
- this . initialIntersection = true ;
568
561
this . _groupCount = 0 ;
569
562
this . _groupItemCount = 0 ;
570
563
@@ -600,13 +593,14 @@ class List extends UI5Element {
600
593
onEnterDOM ( ) {
601
594
registerUI5Element ( this , this . _updateAssociatedLabelsTexts . bind ( this ) ) ;
602
595
DragRegistry . subscribe ( this ) ;
603
- ResizeHandler . register ( this . getDomRef ( ) ! , this . _handleResizeCallback ) ;
596
+ ResizeHandler . register ( this . getDomRef ( ) ! , this . handleResizeCallback ) ;
604
597
}
605
598
606
599
onExitDOM ( ) {
607
600
deregisterUI5Element ( this ) ;
608
601
this . unobserveListEnd ( ) ;
609
- ResizeHandler . deregister ( this . getDomRef ( ) ! , this . _handleResizeCallback ) ;
602
+ this . unobserveListStart ( ) ;
603
+ ResizeHandler . deregister ( this . getDomRef ( ) ! , this . handleResizeCallback ) ;
610
604
DragRegistry . unsubscribe ( this ) ;
611
605
}
612
606
@@ -617,11 +611,10 @@ class List extends UI5Element {
617
611
618
612
onAfterRendering ( ) {
619
613
this . attachGroupHeaderEvents ( ) ;
620
- if ( this . growsOnScroll ) {
621
- this . observeListEnd ( ) ;
622
- } else if ( this . listEndObserved ) {
623
- this . unobserveListEnd ( ) ;
624
- }
614
+ this . unobserveListEnd ( ) ;
615
+ this . unobserveListStart ( ) ;
616
+ this . observeListEnd ( ) ;
617
+ this . observeListStart ( ) ;
625
618
626
619
if ( this . grows ) {
627
620
this . checkListInViewport ( ) ;
@@ -670,6 +663,10 @@ class List extends UI5Element {
670
663
return this . shadowRoot ! . querySelector ( ".ui5-list-end-marker" ) ;
671
664
}
672
665
666
+ get listStartDOM ( ) {
667
+ return this . shadowRoot ! . querySelector ( ".ui5-list-start-marker" ) ;
668
+ }
669
+
673
670
get dropIndicatorDOM ( ) : DropIndicator | null {
674
671
return this . shadowRoot ! . querySelector ( "[ui5-drop-indicator]" ) ;
675
672
}
@@ -736,13 +733,9 @@ class List extends UI5Element {
736
733
return this . accessibilityAttributes . growingButton ?. name ? undefined : `${ this . _id } -growingButton-text` ;
737
734
}
738
735
739
- get scrollContainer ( ) {
740
- return this . shadowRoot ! . querySelector < HTMLElement > ( ".ui5-list-scroll-container" ) ;
741
- }
742
-
743
736
hasGrowingComponent ( ) : boolean {
744
- if ( this . growsOnScroll && this . scrollContainer ) {
745
- return this . scrollContainer . clientHeight !== this . scrollContainer . scrollHeight ;
737
+ if ( this . growsOnScroll ) {
738
+ return this . _startMarkerOutOfView ;
746
739
}
747
740
748
741
return this . growsWithButton ;
@@ -824,33 +817,43 @@ class List extends UI5Element {
824
817
}
825
818
826
819
async observeListEnd ( ) {
827
- if ( ! this . listEndObserved ) {
828
- await renderFinished ( ) ;
829
- this . getIntersectionObserver ( ) . observe ( this . listEndDOM ! ) ;
830
- this . listEndObserved = true ;
831
- }
820
+ await renderFinished ( ) ;
821
+ this . getIntersectionObserver ( ) . observe ( this . listEndDOM ! ) ;
832
822
}
833
823
834
824
unobserveListEnd ( ) {
835
- if ( this . growingIntersectionObserver ) {
836
- this . growingIntersectionObserver . disconnect ( ) ;
837
- this . growingIntersectionObserver = null ;
838
- this . listEndObserved = false ;
825
+ if ( this . _endIntersectionObserver ) {
826
+ this . _endIntersectionObserver . disconnect ( ) ;
827
+ this . _endIntersectionObserver = null ;
839
828
}
840
829
}
841
830
842
- onInteresection ( entries : Array < IntersectionObserverEntry > ) {
843
- if ( this . initialIntersection ) {
844
- this . initialIntersection = false ;
845
- return ;
831
+ async observeListStart ( ) {
832
+ await renderFinished ( ) ;
833
+ this . get_StartIntersectionObserver ( ) . observe ( this . listStartDOM ! ) ;
834
+ }
835
+
836
+ unobserveListStart ( ) {
837
+ if ( this . _startIntersectionObserver ) {
838
+ this . _startIntersectionObserver . disconnect ( ) ;
839
+ this . _startIntersectionObserver = null ;
846
840
}
841
+ }
842
+
843
+ onEndIntersection ( entries : Array < IntersectionObserverEntry > ) {
847
844
entries . forEach ( entry => {
848
845
if ( entry . isIntersecting ) {
849
846
debounce ( this . loadMore . bind ( this ) , INFINITE_SCROLL_DEBOUNCE_RATE ) ;
850
847
}
851
848
} ) ;
852
849
}
853
850
851
+ onStartIntersection ( entries : Array < IntersectionObserverEntry > ) {
852
+ entries . forEach ( entry => {
853
+ this . _startMarkerOutOfView = ! entry . isIntersecting ;
854
+ } ) ;
855
+ }
856
+
854
857
/*
855
858
* ITEM SELECTION BASED ON THE CURRENT MODE
856
859
*/
@@ -1444,17 +1447,27 @@ class List extends UI5Element {
1444
1447
}
1445
1448
1446
1449
getIntersectionObserver ( ) {
1447
- if ( ! this . growingIntersectionObserver ) {
1448
- const scrollContainer = this . scrollContainer || findVerticalScrollContainer ( this . getDomRef ( ) ! ) ;
1450
+ if ( ! this . _endIntersectionObserver ) {
1451
+ this . _endIntersectionObserver = new IntersectionObserver ( this . onEndIntersection . bind ( this ) , {
1452
+ root : null , // null means the viewport
1453
+ rootMargin : "0px" ,
1454
+ threshold : 1.0 ,
1455
+ } ) ;
1456
+ }
1457
+
1458
+ return this . _endIntersectionObserver ;
1459
+ }
1449
1460
1450
- this . growingIntersectionObserver = new IntersectionObserver ( this . onInteresection . bind ( this ) , {
1451
- root : scrollContainer ,
1452
- rootMargin : "5px" ,
1461
+ get_StartIntersectionObserver ( ) {
1462
+ if ( ! this . _startIntersectionObserver ) {
1463
+ this . _startIntersectionObserver = new IntersectionObserver ( this . onStartIntersection . bind ( this ) , {
1464
+ root : null , // null means the viewport
1465
+ rootMargin : "0px" ,
1453
1466
threshold : 1.0 ,
1454
1467
} ) ;
1455
1468
}
1456
1469
1457
- return this . growingIntersectionObserver ;
1470
+ return this . _startIntersectionObserver ;
1458
1471
}
1459
1472
}
1460
1473
0 commit comments