fix to display helpers only when the elements are visible

This commit is contained in:
Valentin Mihai 2022-02-17 09:05:11 +02:00
parent 77d0a4bb1b
commit a3a090162c
5 changed files with 66 additions and 16 deletions

View File

@ -10,6 +10,3 @@
box-shadow: 0 0 0 2px var(--iqser-helpmode-primary) inset;
cursor: help;
}

View File

@ -8,6 +8,7 @@ import { Router } from '@angular/router';
})
export class HelpModeDirective implements OnInit {
@Input('iqserHelpMode') elementName!: string;
@Input() isVirtualScrollElement: boolean = false;
private _path: string;
constructor(
@ -34,7 +35,7 @@ export class HelpModeDirective implements OnInit {
this._renderer.setAttribute(helperElement, 'href', this._helpModeService.getDocsLink(this.elementName));
this._renderer.setAttribute(helperElement, 'target', '_blank');
this._renderer.addClass(helperElement, 'help-mode');
this._helpModeService.addElement(helperElementName, element, helperElement);
this._helpModeService.addElement(helperElementName, element, helperElement, this.isVirtualScrollElement);
}
private _generateId(): string {

View File

@ -8,8 +8,12 @@ import { HELP_DOCS, MANUAL_BASE_URL } from './tokens';
interface Helper {
readonly element: HTMLElement;
readonly helperElement: HTMLElement;
readonly isVirtualScrollElement: boolean;
}
const VIRTUAL_SCROLL_ID = 'virtual-scroll';
const SCROLL_BUTTONS_IDS = ['scroll-up', 'scroll-down'];
@Injectable({
providedIn: 'root',
})
@ -77,7 +81,7 @@ export class HelpModeService {
}
highlightHelperElements(): void {
Object.values(this._helperElements).forEach(({ helperElement }) => {
Object.values(this._helperElements).forEach(({ element, helperElement }) => {
this._renderer.addClass(helperElement, 'help-highlight');
setTimeout(() => {
this._renderer.removeClass(helperElement, 'help-highlight');
@ -85,30 +89,77 @@ export class HelpModeService {
});
}
addElement(helperElementName: string, element: HTMLElement, helperElement: HTMLElement): void {
this._helperElements[helperElementName] = { element, helperElement };
addElement(helperElementName: string, element: HTMLElement, helperElement: HTMLElement, isVirtualScrollElement: boolean): void {
this._helperElements[helperElementName] = { element, helperElement, isVirtualScrollElement };
}
updateHelperElements() {
Object.values(this._helperElements).forEach(({element, helperElement }) => {
this._updateHelperElement(element, helperElement);
Object.values(this._helperElements).forEach(({element, helperElement, isVirtualScrollElement }) => {
this._updateHelperElement(element, helperElement, isVirtualScrollElement);
});
}
private _updateHelperElement(element: HTMLElement, helperElement: HTMLElement) {
const dimensions = this._getElementDimensions(element);
helperElement.style.cssText = `
private _isElementVisible(element: HTMLElement, isVirtualScrollElement: boolean): boolean {
const elementRect = element.getBoundingClientRect();
if (elementRect.top === 0 && elementRect.left === 0 && elementRect.bottom === 0 && elementRect.bottom === 0) {
return false;
}
if (isVirtualScrollElement) {
const virtualScroll: any = document.getElementById(VIRTUAL_SCROLL_ID);
if (!virtualScroll) {
return false;
}
const virtualScrollRect = virtualScroll.getBoundingClientRect();
if (!(elementRect.top > virtualScrollRect.top
&& elementRect.left > virtualScrollRect.left
&& elementRect.bottom < virtualScrollRect.bottom
&& elementRect.right < virtualScrollRect.right)) {
return false;
}
for (const id of SCROLL_BUTTONS_IDS) {
const scroll: any = document.getElementById(id);
const elementRect = element.getBoundingClientRect();
const scrollRect = scroll.getBoundingClientRect();
if(elementRect.top + elementRect.height > scrollRect.top
&& elementRect.left + elementRect.width > scrollRect.left
&& elementRect.bottom - elementRect.height < scrollRect.bottom
&& elementRect.right - elementRect.width < scrollRect.right) {
return false
}
}
}
return true;
}
private _updateHelperElement(element: HTMLElement, helperElement: HTMLElement, isVirtualScrollElement: boolean) {
if (this._isElementVisible(element, isVirtualScrollElement)) {
const dimensions = this._getElementDimensions(element);
helperElement.style.cssText = `
top:${dimensions.y}px;
left:${dimensions.x}px;
width:${dimensions.width}px;
height:${dimensions.height}px;
`;
helperElement.classList.add('help-mode')
} else {
helperElement.classList.remove('help-mode')
}
}
private _enableHelperElements() {
Object.values(this._helperElements).forEach(({ element, helperElement }) => {
Object.values(this._helperElements).forEach(({ element, helperElement, isVirtualScrollElement }) => {
document.body.appendChild(helperElement)
this._updateHelperElement(element, helperElement);
this._updateHelperElement(element, helperElement, isVirtualScrollElement);
});
}

View File

@ -1,7 +1,7 @@
<button (click)="scroll(buttonType.top)" [hidden]="(showScrollUp$ | async) === false" class="scroll-button top pointer" iqserHelpMode="scroll_up_and_down">
<button (click)="scroll(buttonType.top)" [hidden]="(showScrollUp$ | async) === false" class="scroll-button top pointer" iqserHelpMode="scroll_up_and_down" id="scroll-up">
<mat-icon svgIcon="iqser:arrow-down-o"></mat-icon>
</button>
<button (click)="scroll(buttonType.bottom)" [hidden]="(showScrollDown$ | async) === false" class="scroll-button bottom pointer" iqserHelpMode="scroll_up_and_down">
<button (click)="scroll(buttonType.bottom)" [hidden]="(showScrollDown$ | async) === false" class="scroll-button bottom pointer" iqserHelpMode="scroll_up_and_down" id="scroll-down">
<mat-icon svgIcon="iqser:arrow-down-o"></mat-icon>
</button>

View File

@ -5,6 +5,7 @@
[maxBufferPx]="1500"
[minBufferPx]="300"
iqserHasScrollbar
id="virtual-scroll"
>
<ng-container *cdkVirtualFor="let entity of listingComponent.sortedDisplayedEntities$; trackBy: trackBy; templateCacheSize: 60">
<!-- mouseenter and mouseleave triggers change detection event if itemMouse functions are undefined -->