11import {
2- Directive , OnInit , OnDestroy , Output , ElementRef , Optional , ViewContainerRef , HostListener ,
2+ Directive , OnInit , OnDestroy , Output , ElementRef , ViewContainerRef ,
33 Input , EventEmitter , booleanAttribute , TemplateRef , ComponentRef , Renderer2 ,
44 EnvironmentInjector ,
55 createComponent ,
66 AfterViewInit ,
7+ inject ,
78} from '@angular/core' ;
89import { Subject } from 'rxjs' ;
910import { takeUntil } from 'rxjs/operators' ;
@@ -14,7 +15,7 @@ import { IgxToggleActionDirective } from '../toggle/toggle.directive';
1415import { IgxTooltipComponent } from './tooltip.component' ;
1516import { IgxTooltipDirective } from './tooltip.directive' ;
1617import { IgxTooltipCloseButtonComponent } from './tooltip-close-button.component' ;
17- import { TooltipPositionSettings , TooltipPositionStrategy } from './tooltip.common' ;
18+ import { parseTriggers , TooltipPositionSettings , TooltipPositionStrategy } from './tooltip.common' ;
1819
1920export interface ITooltipShowEventArgs extends IBaseEventArgs {
2021 target : IgxTooltipTargetDirective ;
@@ -232,6 +233,46 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
232233 @Input ( { transform : booleanAttribute } )
233234 public tooltipDisabled = false ;
234235
236+ /**
237+ * Which event triggers will show the tooltip.
238+ * Expects a comma separate string of different event triggers.
239+ * Defaults to `pointerenter`.
240+ * ```html
241+ * <igx-icon [igxTooltipTarget]="tooltipRef" [showTriggers]="'click,focus'">info</igx-icon>
242+ * <span #tooltipRef="tooltip" igxTooltip>Hello there, I am a tooltip!</span>
243+ * ```
244+ */
245+ @Input ( )
246+ public get showTriggers ( ) : string {
247+ return Array . from ( this . _showTriggers ) . join ( ) ;
248+ }
249+
250+ public set showTriggers ( value : string ) {
251+ this . _showTriggers = parseTriggers ( value ) ;
252+ this . removeEventListeners ( ) ;
253+ this . addEventListeners ( ) ;
254+ }
255+
256+ /**
257+ * Which event triggers will hide the tooltip.
258+ * Expects a comma separate string of different event triggers.
259+ * Defaults to `pointerleave` and `click`.
260+ * ```html
261+ * <igx-icon [igxTooltipTarget]="tooltipRef" [hideTriggers]="'keypress,blur'">info</igx-icon>
262+ * <span #tooltipRef="tooltip" igxTooltip>Hello there, I am a tooltip!</span>
263+ * ```
264+ */
265+ @Input ( )
266+ public get hideTriggers ( ) : string {
267+ return Array . from ( this . _hideTriggers ) . join ( ) ;
268+ }
269+
270+ public set hideTriggers ( value : string ) {
271+ this . _hideTriggers = parseTriggers ( value ) ;
272+ this . removeEventListeners ( ) ;
273+ this . addEventListeners ( ) ;
274+ }
275+
235276 /**
236277 * @hidden
237278 */
@@ -253,8 +294,11 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
253294 }
254295
255296 /**
256- * @hidden
257- */
297+ * Specifies a plain text as tooltip content.
298+ * ```html
299+ * <igx-icon igxTooltipTarget [tooltip]="'Infragistics Inc. HQ'">info</igx-icon>
300+ * ```
301+ */
258302 @Input ( )
259303 public set tooltip ( content : any ) {
260304 if ( ! this . target && ( typeof content === 'string' || content instanceof String ) ) {
@@ -323,6 +367,12 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
323367 @Output ( )
324368 public tooltipHide = new EventEmitter < ITooltipHideEventArgs > ( ) ;
325369
370+ private _element = inject ( ElementRef ) ;
371+ private _navigationService = inject ( IgxNavigationService , { optional : true } ) ;
372+ private _viewContainerRef = inject ( ViewContainerRef ) ;
373+ private _renderer = inject ( Renderer2 ) ;
374+ private _envInjector = inject ( EnvironmentInjector ) ;
375+
326376 private _destroy$ = new Subject < void > ( ) ;
327377 private _autoHideDelay = 180 ;
328378 private _isForceClosed = false ;
@@ -331,25 +381,20 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
331381 private _closeTemplate : TemplateRef < any > ;
332382 private _sticky = false ;
333383 private _positionSettings : PositionSettings = TooltipPositionSettings ;
384+ private _showTriggers = new Set ( [ 'pointerenter' ] ) ;
385+ private _hideTriggers = new Set ( [ 'pointerleave' , 'click' ] ) ;
334386
335- constructor (
336- private _element : ElementRef ,
337- @Optional ( ) private _navigationService : IgxNavigationService ,
338- private _viewContainerRef : ViewContainerRef ,
339- private _renderer : Renderer2 ,
340- private _envInjector : EnvironmentInjector
341- ) {
342- super ( _element , _navigationService ) ;
343- }
387+ private _abortController = new AbortController ( ) ;
344388
345389 /**
346390 * @hidden
347391 */
348- @HostListener ( 'click' )
349392 public override onClick ( ) {
350- if ( ! this . target . collapsed ) {
351- this . _hideOnInteraction ( ) ;
352- } else if ( this . target . timeoutId ) {
393+ if (
394+ this . target . timeoutId &&
395+ this . target . collapsed &&
396+ ! this . _showTriggers . has ( 'click' )
397+ ) {
353398 clearTimeout ( this . target . timeoutId ) ;
354399 this . target . timeoutId = null ;
355400 }
@@ -358,16 +403,14 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
358403 /**
359404 * @hidden
360405 */
361- @HostListener ( 'mouseenter' )
362- public onMouseEnter ( ) {
406+ public onShow ( ) : void {
363407 this . _checksBeforeShowing ( ( ) => this . _showOnInteraction ( ) ) ;
364408 }
365409
366410 /**
367411 * @hidden
368412 */
369- @HostListener ( 'mouseleave' )
370- public onMouseLeave ( ) {
413+ public onHide ( ) : void {
371414 if ( this . tooltipDisabled ) {
372415 return ;
373416 }
@@ -376,28 +419,6 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
376419 this . _hideOnInteraction ( ) ;
377420 }
378421
379- /**
380- * @hidden
381- */
382- public onTouchStart ( ) {
383- this . _checksBeforeShowing ( ( ) => this . _showOnInteraction ( ) ) ;
384- }
385-
386- /**
387- * @hidden
388- */
389- public onDocumentTouchStart ( event ) {
390- if ( this . tooltipDisabled || this ?. target ?. tooltipTarget !== this ) {
391- return ;
392- }
393-
394- if ( this . nativeElement !== event . target &&
395- ! this . nativeElement . contains ( event . target )
396- ) {
397- this . _hideOnInteraction ( ) ;
398- }
399- }
400-
401422 /**
402423 * @hidden
403424 */
@@ -421,7 +442,8 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
421442 }
422443 } ) ;
423444
424- this . nativeElement . addEventListener ( 'touchstart' , this . onTouchStart = this . onTouchStart . bind ( this ) , { passive : true } ) ;
445+ this . removeEventListeners ( ) ;
446+ this . addEventListeners ( ) ;
425447 }
426448
427449 /**
@@ -438,7 +460,7 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
438460 */
439461 public ngOnDestroy ( ) {
440462 this . hideTooltip ( ) ;
441- this . nativeElement . removeEventListener ( 'touchstart' , this . onTouchStart ) ;
463+ this . removeEventListeners ( ) ;
442464 this . _destroyCloseButton ( ) ;
443465 this . _destroy$ . next ( ) ;
444466 this . _destroy$ . complete ( ) ;
@@ -470,6 +492,24 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen
470492 return Object . assign ( { } , this . _overlayDefaults , this . overlaySettings ) ;
471493 }
472494
495+ private addEventListeners ( ) : void {
496+ const options = { passive : true , signal : this . _abortController . signal } ;
497+
498+ this . onShow = this . onShow . bind ( this ) ;
499+ for ( const each of this . _showTriggers ) {
500+ this . nativeElement . addEventListener ( each , this . onShow , options ) ;
501+ }
502+ this . onHide = this . onHide . bind ( this ) ;
503+ for ( const each of this . _hideTriggers ) {
504+ this . nativeElement . addEventListener ( each , this . onHide , options ) ;
505+ }
506+ }
507+
508+ private removeEventListeners ( ) : void {
509+ this . _abortController . abort ( ) ;
510+ this . _abortController = new AbortController ( ) ;
511+ }
512+
473513 private _checkOutletAndOutsideClick ( ) : void {
474514 if ( this . outlet ) {
475515 this . _overlayDefaults . outlet = this . outlet ;
0 commit comments