33 changed files with 242 additions and 103 deletions
@ -0,0 +1,17 @@ |
|||
///
|
|||
/// Copyright © 2016-2024 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
export * from './tooltip/tooltip.directive'; |
|||
@ -0,0 +1,109 @@ |
|||
///
|
|||
/// Copyright © 2016-2024 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { |
|||
AfterViewInit, |
|||
Directive, |
|||
ElementRef, |
|||
Input, |
|||
OnDestroy, |
|||
OnInit, |
|||
Renderer2, |
|||
} from '@angular/core'; |
|||
import { fromEvent, Subject } from 'rxjs'; |
|||
import { filter, takeUntil, tap } from 'rxjs/operators'; |
|||
import { MatTooltip, TooltipPosition } from '@angular/material/tooltip'; |
|||
|
|||
@Directive({ |
|||
standalone: true, |
|||
selector: '[tbTruncateTooltip]', |
|||
providers: [MatTooltip], |
|||
|
|||
}) |
|||
export class TooltipDirective implements OnInit, AfterViewInit, OnDestroy { |
|||
@Input('tbTruncateTooltip') text: string; |
|||
@Input() tooltipEnabled = true; |
|||
@Input() position: TooltipPosition = 'above'; |
|||
|
|||
private destroy$ = new Subject<void>(); |
|||
|
|||
constructor( |
|||
private elementRef: ElementRef, |
|||
private renderer: Renderer2, |
|||
private tooltip: MatTooltip |
|||
) {} |
|||
|
|||
ngOnInit(): void { |
|||
this.observeMouseEvents(); |
|||
this.applyTruncationStyles(); |
|||
} |
|||
|
|||
ngAfterViewInit(): void { |
|||
if (!this.text) { |
|||
this.text = this.elementRef.nativeElement.innerText; |
|||
} |
|||
|
|||
this.tooltip.position = this.position; |
|||
} |
|||
|
|||
ngOnDestroy(): void { |
|||
if (this.tooltip._isTooltipVisible()) { |
|||
this.hideTooltip(); |
|||
} |
|||
this.destroy$.next(); |
|||
this.destroy$.complete(); |
|||
} |
|||
|
|||
private observeMouseEvents(): void { |
|||
fromEvent(this.elementRef.nativeElement, 'mouseenter') |
|||
.pipe( |
|||
filter(() => this.tooltipEnabled), |
|||
filter(() => this.isOverflown(this.elementRef.nativeElement)), |
|||
tap(() => this.showTooltip()), |
|||
takeUntil(this.destroy$), |
|||
) |
|||
.subscribe(); |
|||
fromEvent(this.elementRef.nativeElement, 'mouseleave') |
|||
.pipe( |
|||
filter(() => this.tooltipEnabled), |
|||
filter(() => this.tooltip._isTooltipVisible()), |
|||
tap(() => this.hideTooltip()), |
|||
takeUntil(this.destroy$), |
|||
) |
|||
.subscribe(); |
|||
} |
|||
|
|||
private applyTruncationStyles(): void { |
|||
this.renderer.setStyle(this.elementRef.nativeElement, 'white-space', 'nowrap'); |
|||
this.renderer.setStyle(this.elementRef.nativeElement, 'overflow', 'hidden'); |
|||
this.renderer.setStyle(this.elementRef.nativeElement, 'text-overflow', 'ellipsis'); |
|||
} |
|||
|
|||
private isOverflown(element: HTMLElement): boolean { |
|||
return element.clientWidth < element.scrollWidth; |
|||
} |
|||
|
|||
private showTooltip(): void { |
|||
this.tooltip.message = this.text; |
|||
|
|||
this.renderer.setAttribute(this.elementRef.nativeElement, 'matTooltip', this.text); |
|||
this.tooltip.show(); |
|||
} |
|||
|
|||
private hideTooltip(): void { |
|||
this.tooltip.hide(); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue