import * as React from '@theia/core/shared/react'; import { Installable } from '../../../common/protocol/installable'; import { ArduinoComponent } from '../../../common/protocol/arduino-component'; import { ListItemRenderer } from './list-item-renderer'; export class ComponentListItem< T extends ArduinoComponent > extends React.Component, ComponentListItem.State> { constructor(props: ComponentListItem.Props) { super(props); if (props.item.installable) { const version = props.item.availableVersions.filter( (version) => version !== props.item.installedVersion )[0]; this.state = { selectedVersion: version, focus: false, }; } } override componentDidUpdate( prevProps: ComponentListItem.Props, prevState: ComponentListItem.State ): void { if (this.state.focus !== prevState.focus) { this.props.onFocusDidChange(); } } override render(): React.ReactNode { const { item, itemRenderer } = this.props; return (
this.setState({ focus: true })} onMouseLeave={() => this.setState({ focus: false })} > {itemRenderer.renderItem( Object.assign(this.state, { item }), this.install.bind(this), this.uninstall.bind(this), this.onVersionChange.bind(this) )}
); } private async install(item: T): Promise { const toInstall = this.state.selectedVersion; const version = this.props.item.availableVersions.filter( (version) => version !== this.state.selectedVersion )[0]; this.setState({ selectedVersion: version, }); try { await this.props.install(item, toInstall); } catch { this.setState({ selectedVersion: toInstall, }); } } private async uninstall(item: T): Promise { await this.props.uninstall(item); } private onVersionChange(version: Installable.Version): void { this.setState({ selectedVersion: version }); } } export namespace ComponentListItem { export interface Props { readonly item: T; readonly install: (item: T, version?: Installable.Version) => Promise; readonly uninstall: (item: T) => Promise; readonly itemRenderer: ListItemRenderer; readonly onFocusDidChange: () => void; } export interface State { selectedVersion?: Installable.Version; focus: boolean; } }