@@ -5,35 +5,40 @@ interface ListItemInputProps {
55 render : any ;
66 parentAddEventListener : any ;
77 parentRemoveEventListener : any ;
8+ parentTrigger : any ;
89}
910
1011interface ListItemState {
1112 renderTarget : any ;
1213 shouldRenderItem : boolean ;
1314 isVisible : boolean ;
15+ height : number ;
1416}
1517
18+ const DEFAULT_MAX_HEIGHT = 153 ;
19+
1620class ListItem extends React . Component < ListItemInputProps , ListItemState > {
17- private static MAX_SIZE = 0 ;
21+ private static MAX_HEIGHT = DEFAULT_MAX_HEIGHT ;
1822 private _containerRef : React . RefObject < HTMLDivElement > ;
1923 private _measurementRef : React . RefObject < HTMLDivElement > ;
2024 private _resizeObserver : ResizeObserver ;
21- private _height = 0 ;
2225 private _scrollHandle : any ;
2326 constructor ( props : ListItemInputProps ) {
2427 super ( props ) ;
2528 this . _containerRef = React . createRef ( ) ;
2629 this . _measurementRef = React . createRef ( ) ;
2730 this . _resizeObserver = new ResizeObserver ( ( ) => {
2831 const rect = this . _measurementRef . current ?. getBoundingClientRect ( ) ;
29- if ( ! rect || rect . height === 0 || ( this . _height && rect . height < this . _height ) ) {
32+ if ( ! rect || rect . height === 0 || rect . height < ListItem . MAX_HEIGHT ) {
3033 return ;
3134 }
32- this . _height = rect . height ;
33- if ( this . _height > ListItem . MAX_SIZE ) {
34- ListItem . MAX_SIZE = this . _height ;
35+ if ( rect . height >= ListItem . MAX_HEIGHT ) {
36+ ListItem . MAX_HEIGHT = rect . height ;
37+ this . props . parentTrigger ( "maxHeightUpdate" , rect . height ) ;
3538 }
39+ this . setState ( { height : rect . height >= ListItem . MAX_HEIGHT ? rect . height : ListItem . MAX_HEIGHT } ) ;
3640 } ) ;
41+ this . props . parentAddEventListener ( "maxHeightUpdate" , this . onMaxHeightUpdate ) ;
3742 this . props . parentAddEventListener ( "scroll" , this . onParentScroll ) ;
3843 const renderTarget = this . props . render ( this . props . item ) ;
3944 const isPromise = renderTarget instanceof Promise ;
@@ -43,6 +48,7 @@ class ListItem extends React.Component<ListItemInputProps, ListItemState> {
4348 this . state = {
4449 renderTarget : isPromise ? undefined : renderTarget ,
4550 shouldRenderItem : ! isPromise ,
51+ height : 0 ,
4652 isVisible : true
4753 } ;
4854 }
@@ -56,8 +62,14 @@ class ListItem extends React.Component<ListItemInputProps, ListItemState> {
5662 this . _resizeObserver . unobserve ( this . _measurementRef . current ) ;
5763 }
5864 this . props . parentRemoveEventListener ( "scroll" , this . onParentScroll ) ;
65+ ListItem . MAX_HEIGHT = DEFAULT_MAX_HEIGHT ;
5966 }
60- onParentScroll = ( parentRect : any , _scrollTop : number , padding : number ) : void => {
67+ onMaxHeightUpdate = ( maxHeight : number ) => {
68+ if ( ! this . state . isVisible && this . state . height < maxHeight ) {
69+ this . setState ( { height : maxHeight } ) ;
70+ }
71+ } ;
72+ onParentScroll = ( parentRect : any , _scrollTop : number , padding : number ) => {
6173 clearTimeout ( this . _scrollHandle ) ;
6274 this . _scrollHandle = setTimeout ( ( ) => {
6375 const rect = this . _containerRef . current ?. getBoundingClientRect ( ) ;
@@ -69,7 +81,7 @@ class ListItem extends React.Component<ListItemInputProps, ListItemState> {
6981 } , 100 ) ;
7082 } ;
7183 doRectanglesIntersect = ( rect1 : any , rect2 : any , padding = 13 ) : boolean => {
72- const itemPadding = ListItem . MAX_SIZE * padding ;
84+ const itemPadding = ListItem . MAX_HEIGHT * padding ;
7385 const rect1Top = rect1 . y - itemPadding ;
7486 const rect1Bottom = rect1 . y + rect1 . height + itemPadding ;
7587 const rect2Top = rect2 . y ;
@@ -86,26 +98,36 @@ class ListItem extends React.Component<ListItemInputProps, ListItemState> {
8698 }
8799 return (
88100 < div
101+ key = { this . props . item }
89102 ref = { this . _containerRef }
90103 style = { {
91104 display : "flex" ,
92105 alignItems : "center" ,
93106 justifyContent : "center" ,
94107 padding : "0.5em 0px"
95108 // DEBUGGING ONLY
96- // backgroundColor: this.state.isVisible ? "green" : "red"
109+ // , backgroundColor: this.state.isVisible ? "green" : "red"
97110 } }
98111 >
99112 < div ref = { this . _measurementRef } >
100- { this . state . isVisible ? (
101- this . state . renderTarget
102- ) : (
103- < div
104- style = { {
105- height : `${ ListItem . MAX_SIZE < this . _height ? this . _height : ListItem . MAX_SIZE } px`
106- } }
107- > </ div >
108- ) }
113+ < div
114+ style = { {
115+ display : this . state . isVisible ? undefined : "none" ,
116+ height : `${
117+ ListItem . MAX_HEIGHT < this . state . height ? this . state . height : ListItem . MAX_HEIGHT
118+ } px`
119+ } }
120+ >
121+ { this . state . renderTarget }
122+ </ div >
123+ < div
124+ style = { {
125+ display : ! this . state . isVisible ? undefined : "none" ,
126+ height : `${
127+ ListItem . MAX_HEIGHT < this . state . height ? this . state . height : ListItem . MAX_HEIGHT
128+ } px`
129+ } }
130+ > </ div >
109131 </ div >
110132 </ div >
111133 ) ;
0 commit comments