1+ import 'react-virtualized/styles.css' ;
12import * as React from '@theia/core/shared/react' ;
23import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer' ;
34import {
@@ -14,7 +15,11 @@ import { Installable } from '../../../common/protocol/installable';
1415import { ComponentListItem } from './component-list-item' ;
1516import { ListItemRenderer } from './list-item-renderer' ;
1617
17- function sameAs < T > ( left : T [ ] , right : T [ ] , key : ( item : T ) => string ) : boolean {
18+ function sameAs < T > (
19+ left : T [ ] ,
20+ right : T [ ] ,
21+ ...compareProps : ( keyof T ) [ ]
22+ ) : boolean {
1823 if ( left === right ) {
1924 return true ;
2025 }
@@ -23,10 +28,12 @@ function sameAs<T>(left: T[], right: T[], key: (item: T) => string): boolean {
2328 return false ;
2429 }
2530 for ( let i = 0 ; i < leftLength ; i ++ ) {
26- const leftKey = key ( left [ i ] ) ;
27- const rightKey = key ( right [ i ] ) ;
28- if ( leftKey !== rightKey ) {
29- return false ;
31+ for ( const prop of compareProps ) {
32+ const leftValue = left [ i ] [ prop ] ;
33+ const rightValue = right [ i ] [ prop ] ;
34+ if ( leftValue !== rightValue ) {
35+ return false ;
36+ }
3037 }
3138 }
3239 return true ;
@@ -43,7 +50,7 @@ export class ComponentList<T extends ArduinoComponent> extends React.Component<
4350 constructor ( props : ComponentList . Props < T > ) {
4451 super ( props ) ;
4552 this . cache = new CellMeasurerCache ( {
46- defaultHeight : 300 ,
53+ defaultHeight : 140 ,
4754 fixedWidth : true ,
4855 } ) ;
4956 }
@@ -67,6 +74,11 @@ export class ComponentList<T extends ArduinoComponent> extends React.Component<
6774 rowHeight = { this . cache . rowHeight }
6875 deferredMeasurementCache = { this . cache }
6976 ref = { this . setListRef }
77+ estimatedRowSize = { 140 }
78+ // If default value, then `react-virtualized` will optimize and list item will not receive a `:hover` event.
79+ // Hence, install and version `<select>` won't be visible even if the mouse cursor is over the `<div>`.
80+ // See https://github.com/bvaughn/react-virtualized/blob/005be24a608add0344284053dae7633be86053b2/source/Grid/Grid.js#L38-L42
81+ scrollingResetTimeInterval = { 0 }
7082 />
7183 ) ;
7284 } }
@@ -77,13 +89,13 @@ export class ComponentList<T extends ArduinoComponent> extends React.Component<
7789 override componentDidUpdate ( prevProps : ComponentList . Props < T > ) : void {
7890 if (
7991 this . resizeAllFlag ||
80- ! sameAs ( this . props . items , prevProps . items , this . props . itemLabel )
92+ ! sameAs ( this . props . items , prevProps . items , 'name' , 'installedVersion' )
8193 ) {
8294 this . clearAll ( true ) ;
8395 }
8496 }
8597
86- private setListRef = ( ref : List | null ) : void => {
98+ private readonly setListRef = ( ref : List | null ) : void => {
8799 this . list = ref || undefined ;
88100 } ;
89101
@@ -98,17 +110,7 @@ export class ComponentList<T extends ArduinoComponent> extends React.Component<
98110 }
99111 }
100112
101- private clear ( index : number ) : void {
102- this . cache . clear ( index , 0 ) ;
103- this . list ?. recomputeRowHeights ( index ) ;
104- // Update the last item if the if the one before was updated
105- if ( index === this . props . items . length - 2 ) {
106- this . cache . clear ( index + 1 , 0 ) ;
107- this . list ?. recomputeRowHeights ( index + 1 ) ;
108- }
109- }
110-
111- private createItem : ListRowRenderer = ( {
113+ private readonly createItem : ListRowRenderer = ( {
112114 index,
113115 parent,
114116 key,
@@ -123,16 +125,20 @@ export class ComponentList<T extends ArduinoComponent> extends React.Component<
123125 rowIndex = { index }
124126 parent = { parent }
125127 >
126- < div style = { style } >
127- < ComponentListItem < T >
128- key = { this . props . itemLabel ( item ) }
129- item = { item }
130- itemRenderer = { this . props . itemRenderer }
131- install = { this . props . install }
132- uninstall = { this . props . uninstall }
133- onFocusDidChange = { ( ) => this . clear ( index ) }
134- />
135- </ div >
128+ { ( { measure, registerChild } ) => (
129+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
130+ // @ts -ignore
131+ < div ref = { registerChild } style = { style } >
132+ < ComponentListItem < T >
133+ key = { this . props . itemLabel ( item ) }
134+ item = { item }
135+ itemRenderer = { this . props . itemRenderer }
136+ install = { this . props . install }
137+ uninstall = { this . props . uninstall }
138+ onFocusDidChange = { ( ) => measure ( ) }
139+ />
140+ </ div >
141+ ) }
136142 </ CellMeasurer >
137143 ) ;
138144 } ;
0 commit comments