Search code examples
javascriptangularangular-materialangular-material2

How to add mattooltip by custom directive in Angular


I am creating a custom directive called TooltipDirective whihc is going to add matTooltip to every host element, code is like below

import { Directive, ElementRef, Input, OnInit, Renderer } from '@angular/core';

@Directive({
    selector: '[tooltip]'
})
export class TooltipDirective implements OnInit
{
    @Input() tooltip: string;
    constructor(private hostElement: ElementRef, private renderer: Renderer)
    {

    }

    ngOnInit()
    {
        this.renderer.setElementAttribute(this.hostElement.nativeElement, 'matTooltip', this.tooltip);
    }
}

In my html I have two elements to compare the result

<i class="material-icons" tooltip="Test Tooltip">reply_all</i>
<i class="material-icons" matTooltip="Test Tooltip">reply_all</i>

in the result html tooltip and mattooltip attributes are added but it doesn't show the tooltip.

and rendered html is like below

<i _ngcontent-c10="" class="material-icons" tooltip="Test Tooltip" mattooltip="Test Tooltip" ng-reflect-tooltip="Test Tooltip">reply_all</i>
<i _ngcontent-c10="" class="material-icons" mattooltip="Test Tooltip" aria-describedby="cdk-describedby-message-1" cdk-describedby-host="" ng-reflect-message="Test Tooltip">reply_all</i>

I tried adding other extra attributes but still doesn't work.


Solution

  • The other answer and comments are correct, btw finally I made it like this and it's working

    import { Directive, ElementRef, Inject, Input, NgZone, Optional, ViewContainerRef } from '@angular/core';
    import
    {
        MAT_TOOLTIP_DEFAULT_OPTIONS,
        MAT_TOOLTIP_SCROLL_STRATEGY,
        MatTooltip,
        MatTooltipDefaultOptions
    } from '@angular/material/tooltip';
    import { AriaDescriber, FocusMonitor } from '../../../../../node_modules/@angular/cdk/a11y';
    import { Directionality } from '../../../../../node_modules/@angular/cdk/bidi';
    import { Overlay, ScrollDispatcher } from '../../../../../node_modules/@angular/cdk/overlay';
    import { Platform } from '../../../../../node_modules/@angular/cdk/platform';
    
    @Directive({
        selector: '[tooltip]',
        exportAs: 'tooltip'
    })
    export class TooltipDirective extends MatTooltip
    {
        @Input()
        get tooltip()
        {
            return this.message;
        }
        set tooltip(value: string)
        {
            this.message = value;
        }
    
        constructor(
            _overlay: Overlay,
            _elementRef: ElementRef,
            _scrollDispatcher: ScrollDispatcher,
            _viewContainerRef: ViewContainerRef,
            _ngZone: NgZone,
            _platform: Platform,
            _ariaDescriber: AriaDescriber,
            _focusMonitor: FocusMonitor,
            @Inject(MAT_TOOLTIP_SCROLL_STRATEGY) _scrollStrategy: any,
            @Optional() _dir: Directionality,
            @Optional() @Inject(MAT_TOOLTIP_DEFAULT_OPTIONS)
            _defaultOptions: MatTooltipDefaultOptions)
        {
            super(
                _overlay,
                _elementRef,
                _scrollDispatcher,
                _viewContainerRef,
                _ngZone,
                _platform,
                _ariaDescriber,
                _focusMonitor,
                _scrollStrategy,
                _dir,
                _defaultOptions
            );
        }
    }