• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IgniteUI / igniteui-angular / 13331632524

14 Feb 2025 02:51PM CUT coverage: 22.015% (-69.6%) from 91.622%
13331632524

Pull #15372

github

web-flow
Merge d52d57714 into bcb78ae0a
Pull Request #15372: chore(*): test ci passing

1990 of 15592 branches covered (12.76%)

431 of 964 new or added lines in 18 files covered. (44.71%)

19956 existing lines in 307 files now uncovered.

6452 of 29307 relevant lines covered (22.02%)

249.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

22.33
/projects/igniteui-angular/src/lib/directives/tooltip/tooltip-target.directive.ts
1
import { useAnimation } from '@angular/animations';
2
import { Directive, OnInit, OnDestroy, Output, ElementRef, Optional, ViewContainerRef, HostListener, Input, EventEmitter, booleanAttribute } from '@angular/core';
3
import { Subject } from 'rxjs';
4
import { takeUntil } from 'rxjs/operators';
5
import { IgxNavigationService } from '../../core/navigation';
6
import { IBaseEventArgs } from '../../core/utils';
7
import { AutoPositionStrategy, HorizontalAlignment, PositionSettings } from '../../services/public_api';
8
import { IgxToggleActionDirective } from '../toggle/toggle.directive';
9
import { IgxTooltipComponent } from './tooltip.component';
10
import { IgxTooltipDirective } from './tooltip.directive';
11
import { fadeOut, scaleInCenter } from 'igniteui-angular/animations';
12

13
export interface ITooltipShowEventArgs extends IBaseEventArgs {
14
    target: IgxTooltipTargetDirective;
15
    tooltip: IgxTooltipDirective;
16
    cancel: boolean;
17
}
18
export interface ITooltipHideEventArgs extends IBaseEventArgs {
19
    target: IgxTooltipTargetDirective;
20
    tooltip: IgxTooltipDirective;
21
    cancel: boolean;
22
}
23

24
/**
25
 * **Ignite UI for Angular Tooltip Target** -
26
 * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/tooltip)
27
 *
28
 * The Ignite UI for Angular Tooltip Target directive is used to mark an HTML element in the markup as one that has a tooltip.
29
 * The tooltip target is used in combination with the Ignite UI for Angular Tooltip by assigning the exported tooltip reference to the
30
 * target's selector property.
31
 *
32
 * Example:
33
 * ```html
34
 * <button type="button" igxButton [igxTooltipTarget]="tooltipRef">Hover me</button>
35
 * <span #tooltipRef="tooltip" igxTooltip>Hello there, I am a tooltip!</span>
36
 * ```
37
 */
38
@Directive({
39
    exportAs: 'tooltipTarget',
40
    selector: '[igxTooltipTarget]',
41
    standalone: true
42
})
43
export class IgxTooltipTargetDirective extends IgxToggleActionDirective implements OnInit, OnDestroy {
2✔
44
    /**
45
     * Gets/sets the amount of milliseconds that should pass before showing the tooltip.
46
     *
47
     * ```typescript
48
     * // get
49
     * let tooltipShowDelay = this.tooltipTarget.showDelay;
50
     * ```
51
     *
52
     * ```html
53
     * <!--set-->
54
     * <button type="button" igxButton [igxTooltipTarget]="tooltipRef" [showDelay]="1500">Hover me</button>
55
     * <span #tooltipRef="tooltip" igxTooltip>Hello there, I am a tooltip!</span>
56
     * ```
57
     */
58
    @Input()
59
    public showDelay = 500;
149✔
60

61
    /**
62
     * Gets/sets the amount of milliseconds that should pass before hiding the tooltip.
63
     *
64
     * ```typescript
65
     * // get
66
     * let tooltipHideDelay = this.tooltipTarget.hideDelay;
67
     * ```
68
     *
69
     * ```html
70
     * <!--set-->
71
     * <button type="button" igxButton [igxTooltipTarget]="tooltipRef" [hideDelay]="1500">Hover me</button>
72
     * <span #tooltipRef="tooltip" igxTooltip>Hello there, I am a tooltip!</span>
73
     * ```
74
     */
75
    @Input()
76
    public hideDelay = 500;
149✔
77

78
    /**
79
     * Specifies if the tooltip should not show when hovering its target with the mouse. (defaults to false)
80
     * While setting this property to 'true' will disable the user interactions that shows/hides the tooltip,
81
     * the developer will still be able to show/hide the tooltip through the API.
82
     *
83
     * ```typescript
84
     * // get
85
     * let tooltipDisabledValue = this.tooltipTarget.tooltipDisabled;
86
     * ```
87
     *
88
     * ```html
89
     * <!--set-->
90
     * <button type="button" igxButton [igxTooltipTarget]="tooltipRef" [tooltipDisabled]="true">Hover me</button>
91
     * <span #tooltipRef="tooltip" igxTooltip>Hello there, I am a tooltip!</span>
92
     * ```
93
     */
94
    @Input({ transform: booleanAttribute })
95
    public tooltipDisabled = false;
149✔
96

97
    /**
98
     * @hidden
99
     */
100
    @Input('igxTooltipTarget')
101
    public override set target(target: any) {
102
        if (target instanceof IgxTooltipDirective) {
149✔
103
            this._target = target;
149✔
104
        }
105
    }
106

107
    /**
108
     * @hidden
109
     */
110
    public override get target(): any {
111
        if (typeof this._target === 'string') {
157!
112
            return this._navigationService.get(this._target);
×
113
        }
114
        return this._target;
157✔
115
    }
116

117
    /**
118
    * @hidden
119
    */
120
    @Input()
121
    public set tooltip(content: any) {
UNCOV
122
        if (!this.target && (typeof content === 'string' || content instanceof String)) {
×
UNCOV
123
            const tooltipComponent = this._viewContainerRef.createComponent(IgxTooltipComponent);
×
UNCOV
124
            tooltipComponent.instance.content = content as string;
×
125

UNCOV
126
            this._target = tooltipComponent.instance.tooltip;
×
127
        }
128
    }
129

130
    /**
131
     * Gets the respective native element of the directive.
132
     *
133
     * ```typescript
134
     * let tooltipTargetElement = this.tooltipTarget.nativeElement;
135
     * ```
136
     */
137
    public get nativeElement() {
UNCOV
138
        return this._element.nativeElement;
×
139
    }
140

141
    /**
142
     * Indicates if the tooltip that is is associated with this target is currently hidden.
143
     *
144
     * ```typescript
145
     * let tooltipHiddenValue = this.tooltipTarget.tooltipHidden;
146
     * ```
147
     */
148
    public get tooltipHidden(): boolean {
UNCOV
149
        return !this.target || this.target.collapsed;
×
150
    }
151

152
    /**
153
     * Emits an event when the tooltip that is associated with this target starts showing.
154
     * This event is fired before the start of the countdown to showing the tooltip.
155
     *
156
     * ```typescript
157
     * tooltipShowing(args: ITooltipShowEventArgs) {
158
     *    alert("Tooltip started showing!");
159
     * }
160
     * ```
161
     *
162
     * ```html
163
     * <button type="button" igxButton [igxTooltipTarget]="tooltipRef" (tooltipShow)='tooltipShowing($event)'>Hover me</button>
164
     * <span #tooltipRef="tooltip" igxTooltip>Hello there, I am a tooltip!</span>
165
     * ```
166
     */
167
    @Output()
168
    public tooltipShow = new EventEmitter<ITooltipShowEventArgs>();
149✔
169

170
    /**
171
     * Emits an event when the tooltip that is associated with this target starts hiding.
172
     * This event is fired before the start of the countdown to hiding the tooltip.
173
     *
174
     * ```typescript
175
     * tooltipHiding(args: ITooltipHideEventArgs) {
176
     *    alert("Tooltip started hiding!");
177
     * }
178
     * ```
179
     *
180
     * ```html
181
     * <button type="button" igxButton [igxTooltipTarget]="tooltipRef" (tooltipHide)='tooltipHiding($event)'>Hover me</button>
182
     * <span #tooltipRef="tooltip" igxTooltip>Hello there, I am a tooltip!</span>
183
     * ```
184
     */
185
    @Output()
186
    public tooltipHide = new EventEmitter<ITooltipHideEventArgs>();
149✔
187

188
    private destroy$ = new Subject<void>();
149✔
189

190
    constructor(private _element: ElementRef,
149✔
191
        @Optional() private _navigationService: IgxNavigationService, private _viewContainerRef: ViewContainerRef) {
149✔
192
        super(_element, _navigationService);
149✔
193
    }
194

195
    /**
196
     * @hidden
197
     */
198
    @HostListener('click')
199
    public override onClick() {
200
        if (!this.target.collapsed) {
8!
UNCOV
201
            this.target.forceClose(this.mergedOverlaySettings);
×
202
        }
203
    }
204

205
    /**
206
     * @hidden
207
     */
208
    @HostListener('mouseenter')
209
    public onMouseEnter() {
UNCOV
210
        if (this.tooltipDisabled) {
×
UNCOV
211
            return;
×
212
        }
213

UNCOV
214
        this.checkOutletAndOutsideClick();
×
UNCOV
215
        const shouldReturn = this.preMouseEnterCheck();
×
UNCOV
216
        if (shouldReturn) {
×
217
            return;
×
218
        }
219

UNCOV
220
        const showingArgs = { target: this, tooltip: this.target, cancel: false };
×
UNCOV
221
        this.tooltipShow.emit(showingArgs);
×
222

UNCOV
223
        if (showingArgs.cancel) {
×
UNCOV
224
            return;
×
225
        }
226

UNCOV
227
        this.target.toBeShown = true;
×
UNCOV
228
        this.target.timeoutId = setTimeout(() => {
×
UNCOV
229
            this.target.open(this.mergedOverlaySettings); // Call open() of IgxTooltipDirective
×
UNCOV
230
            this.target.toBeShown = false;
×
231
        }, this.showDelay);
232
    }
233

234
    /**
235
     * @hidden
236
     */
237
    @HostListener('mouseleave')
238
    public onMouseLeave() {
UNCOV
239
        if (this.tooltipDisabled) {
×
240
            return;
×
241
        }
242

UNCOV
243
        this.checkOutletAndOutsideClick();
×
UNCOV
244
        const shouldReturn = this.preMouseLeaveCheck();
×
UNCOV
245
        if (shouldReturn || this.target.collapsed) {
×
UNCOV
246
            return;
×
247
        }
248

UNCOV
249
        this.target.toBeHidden = true;
×
UNCOV
250
        this.target.timeoutId = setTimeout(() => {
×
UNCOV
251
            this.target.close(); // Call close() of IgxTooltipDirective
×
UNCOV
252
            this.target.toBeHidden = false;
×
253
        }, this.hideDelay);
254

255

256
    }
257

258
    /**
259
     * @hidden
260
     */
261
    @HostListener('touchstart')
262
    public onTouchStart() {
UNCOV
263
        if (this.tooltipDisabled) {
×
UNCOV
264
            return;
×
265
        }
266

UNCOV
267
        this.showTooltip();
×
268
    }
269

270
    /**
271
     * @hidden
272
     */
273
    @HostListener('document:touchstart', ['$event'])
274
    public onDocumentTouchStart(event) {
UNCOV
275
        if (this.tooltipDisabled) {
×
UNCOV
276
            return;
×
277
        }
278

UNCOV
279
        if (this.nativeElement !== event.target &&
×
280
            !this.nativeElement.contains(event.target)
281
        ) {
UNCOV
282
            this.hideTooltip();
×
283
        }
284
    }
285

286
    /**
287
     * @hidden
288
     */
289
    public override ngOnInit() {
290
        super.ngOnInit();
149✔
291

292
        const positionSettings: PositionSettings = {
149✔
293
            horizontalDirection: HorizontalAlignment.Center,
294
            horizontalStartPoint: HorizontalAlignment.Center,
295
            openAnimation: useAnimation(scaleInCenter, { params: { duration: '150ms' } }),
296
            closeAnimation: useAnimation(fadeOut, { params: { duration: '75ms' } })
297
        };
298

299
        this._overlayDefaults.positionStrategy = new AutoPositionStrategy(positionSettings);
149✔
300
        this._overlayDefaults.closeOnOutsideClick = false;
149✔
301
        this._overlayDefaults.closeOnEscape = true;
149✔
302

303
        this.target.closing.pipe(takeUntil(this.destroy$)).subscribe((event) => {
149✔
UNCOV
304
            const hidingArgs = { target: this, tooltip: this.target, cancel: false };
×
UNCOV
305
            this.tooltipHide.emit(hidingArgs);
×
306

UNCOV
307
            if (hidingArgs.cancel) {
×
UNCOV
308
                event.cancel = true;
×
309
            }
310
        });
311
    }
312

313
    /**
314
     * @hidden
315
     */
316
    public ngOnDestroy() {
317
        this.destroy$.next();
149✔
318
        this.destroy$.complete();
149✔
319
    }
320

321
    /**
322
     * Shows the tooltip by respecting the 'showDelay' property.
323
     *
324
     * ```typescript
325
     * this.tooltipTarget.showTooltip();
326
     * ```
327
     */
328
    public showTooltip() {
UNCOV
329
        clearTimeout(this.target.timeoutId);
×
330

UNCOV
331
        if (!this.target.collapsed) {
×
332
            //  if close animation has started finish it, or close the tooltip with no animation
UNCOV
333
            this.target.forceClose(this.mergedOverlaySettings);
×
UNCOV
334
            this.target.toBeHidden = false;
×
335
        }
336

UNCOV
337
        const showingArgs = { target: this, tooltip: this.target, cancel: false };
×
UNCOV
338
        this.tooltipShow.emit(showingArgs);
×
339

UNCOV
340
        if (showingArgs.cancel) {
×
UNCOV
341
            return;
×
342
        }
343

UNCOV
344
        this.target.toBeShown = true;
×
UNCOV
345
        this.target.timeoutId = setTimeout(() => {
×
UNCOV
346
            this.target.open(this.mergedOverlaySettings); // Call open() of IgxTooltipDirective
×
UNCOV
347
            this.target.toBeShown = false;
×
348
        }, this.showDelay);
349
    }
350

351
    /**
352
     * Hides the tooltip by respecting the 'hideDelay' property.
353
     *
354
     * ```typescript
355
     * this.tooltipTarget.hideTooltip();
356
     * ```
357
     */
358
    public hideTooltip() {
UNCOV
359
        if (this.target.collapsed && this.target.toBeShown) {
×
360
            clearTimeout(this.target.timeoutId);
×
361
        }
362

UNCOV
363
        if (this.target.collapsed || this.target.toBeHidden) {
×
364
            return;
×
365
        }
366

UNCOV
367
        this.target.toBeHidden = true;
×
UNCOV
368
        this.target.timeoutId = setTimeout(() => {
×
UNCOV
369
            this.target.close(); // Call close() of IgxTooltipDirective
×
UNCOV
370
            this.target.toBeHidden = false;
×
371
        }, this.hideDelay);
372
    }
373

374
    private checkOutletAndOutsideClick() {
UNCOV
375
        if (this.outlet) {
×
UNCOV
376
            this._overlayDefaults.outlet = this.outlet;
×
377
        }
378
    }
379

380
    private get mergedOverlaySettings() {
UNCOV
381
        return Object.assign({}, this._overlayDefaults, this.overlaySettings);
×
382
    }
383

384
    // Return true if the execution in onMouseEnter should be terminated after this method
385
    private preMouseEnterCheck() {
386
        // If tooltip is about to be opened
UNCOV
387
        if (this.target.toBeShown) {
×
388
            clearTimeout(this.target.timeoutId);
×
389
            this.target.toBeShown = false;
×
390
        }
391

392
        // If Tooltip is opened or about to be hidden
UNCOV
393
        if (!this.target.collapsed || this.target.toBeHidden) {
×
UNCOV
394
            clearTimeout(this.target.timeoutId);
×
395

396
            //  if close animation has started finish it, or close the tooltip with no animation
UNCOV
397
            this.target.forceClose(this.mergedOverlaySettings);
×
UNCOV
398
            this.target.toBeHidden = false;
×
399
        }
400

UNCOV
401
        return false;
×
402
    }
403

404
    // Return true if the execution in onMouseLeave should be terminated after this method
405
    private preMouseLeaveCheck(): boolean {
UNCOV
406
        clearTimeout(this.target.timeoutId);
×
407

408
        // If tooltip is about to be opened
UNCOV
409
        if (this.target.toBeShown) {
×
UNCOV
410
            this.target.toBeShown = false;
×
UNCOV
411
            this.target.toBeHidden = false;
×
UNCOV
412
            return true;
×
413
        }
414

UNCOV
415
        return false;
×
416
    }
417
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc