mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-04-19 12:57:17 +00:00
fix: relaxed hover service request when scrolling
- do not render footer when scrolling - fix anchor word wrapping for long long links in the markdown - underline the link and change the cursor to pointer on hover - consider status-bar height when calculating hover top Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
parent
03355903b9
commit
5c31c93636
@ -4,7 +4,7 @@
|
||||
/* Adapted from https://github.com/microsoft/vscode/blob/7d9b1c37f8e5ae3772782ba3b09d827eb3fdd833/src/vs/workbench/services/hover/browser/hoverService.ts */
|
||||
|
||||
:root {
|
||||
--theia-hover-max-width: 200px;
|
||||
--theia-hover-max-width: 200px; /* customized */
|
||||
}
|
||||
|
||||
.theia-hover {
|
||||
@ -29,10 +29,13 @@
|
||||
|
||||
.theia-hover a {
|
||||
color: var(--theia-textLink-foreground);
|
||||
word-wrap: break-word; /* customized */
|
||||
cursor: pointer; /* customized */
|
||||
}
|
||||
|
||||
.theia-hover a:hover {
|
||||
color: var(--theia-textLink-active-foreground);
|
||||
/* color: var(--theia-textLink-active-foreground); */
|
||||
text-decoration: underline; /* customized */
|
||||
}
|
||||
|
||||
.theia-hover .hover-row .actions {
|
||||
|
@ -158,6 +158,10 @@
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.component-list-item .footer.scrolling {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.component-list-item .footer > * {
|
||||
display: inline-block;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ export class HoverService {
|
||||
const documentWidth = document.body.getBoundingClientRect().width;
|
||||
// document.body.getBoundingClientRect().height doesn't work as expected
|
||||
// scrollHeight will always be accurate here: https://stackoverflow.com/a/44077777
|
||||
const documentHeight = document.documentElement.scrollHeight;
|
||||
const documentHeight = document.documentElement.scrollHeight - 22; // --theia-statusBar-height: 22px;
|
||||
position = HoverPosition.invertIfNecessary(
|
||||
position,
|
||||
targetDimensions,
|
||||
|
@ -24,6 +24,7 @@ export class ComponentListItem<
|
||||
item,
|
||||
selectedVersion,
|
||||
inProgress: this.state.inProgress,
|
||||
isScrolling: this.props.isScrolling,
|
||||
install: (item) => this.install(item),
|
||||
uninstall: (item) => this.uninstall(item),
|
||||
onVersionChange: (version) => this.onVersionChange(version),
|
||||
@ -88,6 +89,7 @@ export namespace ComponentListItem {
|
||||
selectedVersion: Installable.Version
|
||||
) => void;
|
||||
readonly itemRenderer: ListItemRenderer<T>;
|
||||
readonly isScrolling: boolean;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
|
@ -2,16 +2,33 @@ import * as React from '@theia/core/shared/react';
|
||||
import { Virtuoso } from '@theia/core/shared/react-virtuoso';
|
||||
import { ArduinoComponent } from '../../../common/protocol/arduino-component';
|
||||
import { Installable } from '../../../common/protocol/installable';
|
||||
import { HoverService } from '../../theia/core/hover-service';
|
||||
import { ComponentListItem } from './component-list-item';
|
||||
import { ListItemRenderer } from './list-item-renderer';
|
||||
|
||||
export class ComponentList<T extends ArduinoComponent> extends React.Component<
|
||||
ComponentList.Props<T>
|
||||
ComponentList.Props<T>,
|
||||
ComponentList.State
|
||||
> {
|
||||
constructor(props: Readonly<ComponentList.Props<T>>) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isScrolling: false,
|
||||
};
|
||||
}
|
||||
|
||||
override render(): React.ReactNode {
|
||||
return (
|
||||
<Virtuoso
|
||||
data={this.props.items}
|
||||
isScrolling={(isScrolling) => {
|
||||
if (this.state.isScrolling !== isScrolling) {
|
||||
this.setState({ isScrolling });
|
||||
if (isScrolling) {
|
||||
this.props.hoverService.cancelHover();
|
||||
}
|
||||
}
|
||||
}}
|
||||
itemContent={(_: number, item: T) => (
|
||||
<ComponentListItem<T>
|
||||
key={this.props.itemLabel(item)}
|
||||
@ -21,6 +38,7 @@ export class ComponentList<T extends ArduinoComponent> extends React.Component<
|
||||
uninstall={this.props.uninstall}
|
||||
edited={this.props.edited}
|
||||
onItemEdit={this.props.onItemEdit}
|
||||
isScrolling={this.state.isScrolling}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
@ -42,5 +60,9 @@ export namespace ComponentList {
|
||||
item: T,
|
||||
selectedVersion: Installable.Version
|
||||
) => void;
|
||||
readonly hoverService: HoverService;
|
||||
}
|
||||
export interface State {
|
||||
isScrolling: boolean;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import { ListItemRenderer } from './list-item-renderer';
|
||||
import { ResponseServiceClient } from '../../../common/protocol';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import { HoverService } from '../../theia/core/hover-service';
|
||||
|
||||
export class FilterableListContainer<
|
||||
T extends ArduinoComponent,
|
||||
@ -93,6 +94,7 @@ export class FilterableListContainer<
|
||||
uninstall={this.uninstall.bind(this)}
|
||||
edited={this.state.edited}
|
||||
onItemEdit={this.onItemEdit.bind(this)}
|
||||
hoverService={this.props.hoverService}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -193,6 +195,7 @@ export namespace FilterableListContainer {
|
||||
progressId: string;
|
||||
}) => Promise<void>;
|
||||
readonly commandService: CommandService;
|
||||
readonly hoverService: HoverService;
|
||||
}
|
||||
|
||||
export interface State<T, S extends Searchable.Options> {
|
||||
|
@ -114,6 +114,7 @@ interface ListItemRendererParams<T extends ArduinoComponent> {
|
||||
readonly item: T;
|
||||
readonly selectedVersion: Installable.Version | undefined;
|
||||
readonly inProgress?: 'installing' | 'uninstalling' | undefined;
|
||||
readonly isScrolling: boolean;
|
||||
readonly install: (item: T) => Promise<void>;
|
||||
readonly uninstall: (item: T) => Promise<void>;
|
||||
readonly onVersionChange: (version: Installable.Version) => void;
|
||||
@ -156,15 +157,17 @@ export class ListItemRenderer<T extends ArduinoComponent> {
|
||||
|
||||
private readonly showHover = (
|
||||
event: React.MouseEvent<HTMLElement>,
|
||||
markdown: string
|
||||
params: ListItemRendererParams<T>
|
||||
) => {
|
||||
this.hoverService.requestHover({
|
||||
content: new MarkdownStringImpl(markdown),
|
||||
target: event.currentTarget,
|
||||
position: 'right',
|
||||
});
|
||||
if (!params.isScrolling) {
|
||||
const markdown = this.markdown(params);
|
||||
this.hoverService.requestHover({
|
||||
content: new MarkdownStringImpl(markdown),
|
||||
target: event.currentTarget,
|
||||
position: 'right',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
renderItem(params: ListItemRendererParams<T>): React.ReactNode {
|
||||
const action = this.action(params);
|
||||
return (
|
||||
@ -172,7 +175,7 @@ export class ListItemRenderer<T extends ArduinoComponent> {
|
||||
<Separator />
|
||||
<div
|
||||
className="component-list-item noselect"
|
||||
onMouseEnter={(event) => this.showHover(event, this.markdown(params))}
|
||||
onMouseOver={(event) => this.showHover(event, params)}
|
||||
>
|
||||
<Header
|
||||
params={params}
|
||||
@ -650,8 +653,13 @@ class Footer<T extends ArduinoComponent> extends React.Component<
|
||||
}>
|
||||
> {
|
||||
override render(): React.ReactNode {
|
||||
const { isScrolling } = this.props.params;
|
||||
const className = ['footer'];
|
||||
if (isScrolling) {
|
||||
className.push('scrolling');
|
||||
}
|
||||
return (
|
||||
<div className="footer">
|
||||
<div className={className.join(' ')}>
|
||||
<SelectVersion {...this.props} />
|
||||
<Button {...this.props} />
|
||||
</div>
|
||||
|
@ -21,6 +21,7 @@ import { FilterableListContainer } from './filterable-list-container';
|
||||
import { ListItemRenderer } from './list-item-renderer';
|
||||
import { NotificationCenter } from '../../notification-center';
|
||||
import { StatefulWidget } from '@theia/core/lib/browser';
|
||||
import { HoverService } from '../../theia/core/hover-service';
|
||||
|
||||
@injectable()
|
||||
export abstract class ListWidget<
|
||||
@ -38,6 +39,8 @@ export abstract class ListWidget<
|
||||
private readonly commandService: CommandService;
|
||||
@inject(ResponseServiceClient)
|
||||
private readonly responseService: ResponseServiceClient;
|
||||
@inject(HoverService)
|
||||
private readonly hoverService: HoverService;
|
||||
|
||||
/**
|
||||
* Do not touch or use it. It is for setting the focus on the `input` after the widget activation.
|
||||
@ -162,6 +165,7 @@ export abstract class ListWidget<
|
||||
commandService={this.commandService}
|
||||
responseService={this.responseService}
|
||||
onDidShow={this.onDidShowEmitter.event}
|
||||
hoverService={this.hoverService}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user