Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d0dfc65

Browse filesBrowse files
Akos Kittakittaakos
Akos Kitta
authored andcommitted
Improved the scrolling UX in list widgets
- Fixed scrollbar does not reach end of list widget. - Estimated row heights to provide better scroll UX. - Last item's `<select>` must be visible. Closes #1380 Closes #1381 Closes #1387 Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
1 parent df3a34e commit d0dfc65
Copy full SHA for d0dfc65

File tree

3 files changed

+38
-34
lines changed
Filter options

3 files changed

+38
-34
lines changed

‎arduino-ide-extension/src/browser/style/list-widget.css

Copy file name to clipboardExpand all lines: arduino-ide-extension/src/browser/style/list-widget.css
-4Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@
4444
height: 100%; /* This has top be 100% down to the `scrollContainer`. */
4545
}
4646

47-
.filterable-list-container .items-container {
48-
padding-bottom: calc(2 * var(--theia-statusBar-height));
49-
}
50-
5147
.filterable-list-container .items-container > div > div:nth-child(odd) {
5248
background-color: var(--theia-sideBar-background);
5349
filter: contrast(105%);

‎arduino-ide-extension/src/browser/widgets/component-list/component-list.tsx

Copy file name to clipboardExpand all lines: arduino-ide-extension/src/browser/widgets/component-list/component-list.tsx
+35-29Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'react-virtualized/styles.css';
12
import * as React from '@theia/core/shared/react';
23
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer';
34
import {
@@ -14,7 +15,11 @@ import { Installable } from '../../../common/protocol/installable';
1415
import { ComponentListItem } from './component-list-item';
1516
import { 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
};

‎arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx

Copy file name to clipboardExpand all lines: arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ export class FilterableListContainer<
5151
<div className={'filterable-list-container'}>
5252
{this.renderSearchBar()}
5353
{this.renderSearchFilter()}
54-
{this.renderComponentList()}
54+
<div className="filterable-list-container">
55+
{this.renderComponentList()}
56+
</div>
5557
</div>
5658
);
5759
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.