Skip to content

Commit 2e8ce5b

Browse files
author
Akos Kitta
committed
Moved focus tracing inside item.
Signed-off-by: Akos Kitta <[email protected]>
1 parent 3ae1338 commit 2e8ce5b

File tree

4 files changed

+70
-60
lines changed

4 files changed

+70
-60
lines changed

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

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
}
2424

2525
.filterable-list-container .items-container {
26-
height: 100%; /* This has to be propagated down from the widget. */
27-
position: relative; /* To fix the `top` of the vertical toolbar. */
26+
padding-bottom: calc(2 * var(--theia-statusBar-height));
2827
}
2928

3029
.filterable-list-container .items-container > div > div:nth-child(odd) {
@@ -42,14 +41,6 @@
4241
filter: contrast(90%);
4342
}
4443

45-
/* Perfect scrollbar does not like if we explicitly set the `background-color` of the contained elements.
46-
See above: `.filterable-list-container .items-container > div:nth-child(odd|event)`.
47-
We have to increase `z-index` of the scroll-bar thumb. Otherwise, the thumb is not visible.
48-
https://github.com/arduino/arduino-pro-ide/issues/82 */
49-
.arduino-list-widget .filterable-list-container .items-container .ps__rail-y {
50-
z-index: 1;
51-
}
52-
5344
.component-list-item {
5445
padding: 10px 10px 10px 15px;
5546
font-size: var(--theia-ui-font-size1);
@@ -113,7 +104,7 @@ https://github.com/arduino/arduino-pro-ide/issues/82 */
113104

114105
.component-list-item[min-width~="170px"] .footer {
115106
padding: 5px 5px 0px 0px;
116-
min-height: 30px;
107+
min-height: 35px;
117108
display: flex;
118109
flex-direction: row-reverse;
119110
}
@@ -122,10 +113,6 @@ https://github.com/arduino/arduino-pro-ide/issues/82 */
122113
flex-direction: column-reverse;
123114
}
124115

125-
.component-list-item .footer > * {
126-
display: none
127-
}
128-
129116
.component-list-item:hover .footer > * {
130117
display: inline-block;
131118
margin: 5px 0px 0px 10px;

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

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,38 @@ export class ComponentListItem<
1414
)[0];
1515
this.state = {
1616
selectedVersion: version,
17+
focus: false,
1718
};
1819
}
1920
}
2021

21-
protected async install(item: T): Promise<void> {
22+
override componentDidUpdate(
23+
prevProps: ComponentListItem.Props<T>,
24+
prevState: ComponentListItem.State
25+
): void {
26+
if (this.state.focus !== prevState.focus) {
27+
this.props.onFocusDidChange();
28+
}
29+
}
30+
31+
override render(): React.ReactNode {
32+
const { item, itemRenderer } = this.props;
33+
return (
34+
<div
35+
onMouseEnter={() => this.setState({ focus: true })}
36+
onMouseLeave={() => this.setState({ focus: false })}
37+
>
38+
{itemRenderer.renderItem(
39+
Object.assign(this.state, { item }),
40+
this.install.bind(this),
41+
this.uninstall.bind(this),
42+
this.onVersionChange.bind(this)
43+
)}
44+
</div>
45+
);
46+
}
47+
48+
private async install(item: T): Promise<void> {
2249
const toInstall = this.state.selectedVersion;
2350
const version = this.props.item.availableVersions.filter(
2451
(version) => version !== this.state.selectedVersion
@@ -35,23 +62,13 @@ export class ComponentListItem<
3562
}
3663
}
3764

38-
protected async uninstall(item: T): Promise<void> {
65+
private async uninstall(item: T): Promise<void> {
3966
await this.props.uninstall(item);
4067
}
4168

42-
protected onVersionChange(version: Installable.Version): void {
69+
private onVersionChange(version: Installable.Version): void {
4370
this.setState({ selectedVersion: version });
4471
}
45-
46-
override render(): React.ReactNode {
47-
const { item, itemRenderer } = this.props;
48-
return itemRenderer.renderItem(
49-
Object.assign(this.state, { item }),
50-
this.install.bind(this),
51-
this.uninstall.bind(this),
52-
this.onVersionChange.bind(this)
53-
);
54-
}
5572
}
5673

5774
export namespace ComponentListItem {
@@ -60,9 +77,11 @@ export namespace ComponentListItem {
6077
readonly install: (item: T, version?: Installable.Version) => Promise<void>;
6178
readonly uninstall: (item: T) => Promise<void>;
6279
readonly itemRenderer: ListItemRenderer<T>;
80+
readonly onFocusDidChange: () => void;
6381
}
6482

6583
export interface State {
6684
selectedVersion?: Installable.Version;
85+
focus: boolean;
6786
}
6887
}

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

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,26 @@ import { Installable } from '../../../common/protocol/installable';
1414
import { ComponentListItem } from './component-list-item';
1515
import { ListItemRenderer } from './list-item-renderer';
1616

17+
function sameAs<T>(left: T[], right: T[], key: (item: T) => string): boolean {
18+
if (left === right) {
19+
return true;
20+
}
21+
const leftLength = left.length;
22+
if (leftLength !== right.length) {
23+
return false;
24+
}
25+
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;
30+
}
31+
}
32+
return true;
33+
}
34+
1735
export class ComponentList<T extends ArduinoComponent> extends React.Component<
18-
ComponentList.Props<T>,
19-
ComponentList.State
36+
ComponentList.Props<T>
2037
> {
2138
private readonly cache: CellMeasurerCache;
2239
private resizeAllFlag: boolean;
@@ -25,9 +42,8 @@ export class ComponentList<T extends ArduinoComponent> extends React.Component<
2542

2643
constructor(props: ComponentList.Props<T>) {
2744
super(props);
28-
this.state = { focusIndex: 'none' };
2945
this.cache = new CellMeasurerCache({
30-
defaultHeight: 200,
46+
defaultHeight: 300,
3147
fixedWidth: true,
3248
});
3349
}
@@ -38,14 +54,13 @@ export class ComponentList<T extends ArduinoComponent> extends React.Component<
3854
{({ width, height }) => {
3955
if (this.mostRecentWidth && this.mostRecentWidth !== width) {
4056
this.resizeAllFlag = true;
41-
setTimeout(this.clearAll, 0);
57+
setTimeout(() => this.clearAll(), 0);
4258
}
4359
this.mostRecentWidth = width;
4460
return (
4561
<List
4662
className={'items-container'}
4763
rowRenderer={this.createItem}
48-
overscanRowCount={100}
4964
height={height}
5065
width={width}
5166
rowCount={this.props.items.length}
@@ -59,19 +74,12 @@ export class ComponentList<T extends ArduinoComponent> extends React.Component<
5974
);
6075
}
6176

62-
override componentDidUpdate(
63-
prevProps: ComponentList.Props<T>,
64-
prevState: ComponentList.State
65-
): void {
66-
if (this.resizeAllFlag || this.props.items !== prevProps.items) {
77+
override componentDidUpdate(prevProps: ComponentList.Props<T>): void {
78+
if (
79+
this.resizeAllFlag ||
80+
!sameAs(this.props.items, prevProps.items, this.props.itemLabel)
81+
) {
6782
this.clearAll(true);
68-
} else if (this.state.focusIndex !== prevState.focusIndex) {
69-
if (typeof this.state.focusIndex === 'number') {
70-
this.clear(this.state.focusIndex);
71-
}
72-
if (typeof prevState.focusIndex === 'number') {
73-
this.clear(prevState.focusIndex);
74-
}
7583
}
7684
}
7785

@@ -112,17 +120,14 @@ export class ComponentList<T extends ArduinoComponent> extends React.Component<
112120
rowIndex={index}
113121
parent={parent}
114122
>
115-
<div
116-
style={style}
117-
onMouseEnter={() => this.setState({ focusIndex: index })}
118-
onMouseLeave={() => this.setState({ focusIndex: 'none' })}
119-
>
123+
<div style={style}>
120124
<ComponentListItem<T>
121125
key={this.props.itemLabel(item)}
122126
item={item}
123127
itemRenderer={this.props.itemRenderer}
124128
install={this.props.install}
125129
uninstall={this.props.uninstall}
130+
onFocusDidChange={() => this.clear(index)}
126131
/>
127132
</div>
128133
</CellMeasurer>
@@ -139,7 +144,4 @@ export namespace ComponentList {
139144
readonly install: (item: T, version?: Installable.Version) => Promise<void>;
140145
readonly uninstall: (item: T) => Promise<void>;
141146
}
142-
export interface State {
143-
focusIndex: number | 'none';
144-
}
145147
}

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export class ListItemRenderer<T extends ArduinoComponent> {
1414

1515
protected onMoreInfoClick = (
1616
event: React.SyntheticEvent<HTMLAnchorElement, Event>
17-
) => {
17+
): void => {
1818
const { target } = event.nativeEvent;
1919
if (target instanceof HTMLAnchorElement) {
2020
this.windowService.openNewWindow(target.href, { external: true });
@@ -28,7 +28,7 @@ export class ListItemRenderer<T extends ArduinoComponent> {
2828
uninstall: (item: T) => Promise<void>,
2929
onVersionChange: (version: Installable.Version) => void
3030
): React.ReactNode {
31-
const { item } = input;
31+
const { item, focus } = input;
3232
let nameAndAuthor: JSX.Element;
3333
if (item.name && item.author) {
3434
const name = <span className="name">{item.name}</span>;
@@ -120,10 +120,12 @@ export class ListItemRenderer<T extends ArduinoComponent> {
120120
{description}
121121
</div>
122122
<div className="info">{moreInfo}</div>
123-
<div className="footer">
124-
{versions}
125-
{installButton}
126-
</div>
123+
{focus && (
124+
<div className="footer">
125+
{versions}
126+
{installButton}
127+
</div>
128+
)}
127129
</div>
128130
);
129131
}

0 commit comments

Comments
 (0)