Search code examples
angular

Custom directive and [ngClass] on same element does not work


I have a custom Directive which puts a class when the mouse hovers an element :

@Directive({
  selector: '[hover-class]'
})
export class HoverClassDirective {

    @Input('hover-class') hoverClass: any;

  constructor(public elementRef: ElementRef) { }

    @HostListener('mouseenter') onMouseEnter() {
        this.elementRef.nativeElement.classList.add(this.hoverClass);
    }

    @HostListener('mouseleave') onMouseLeave() {
        this.elementRef.nativeElement.classList.remove(this.hoverClass);
    }
}

And I can put it on an element (typically a div), it works fine.

On a particular div, I have a [ngClass] which sets a class on some condition. This also works fine.

But I can't combine both my custom directive and [ngClass], in that case, only the custom directive works :

<div class="border-0" (contextmenu)="onRightClick($event)" (dblclick)="toggleState()" (click)="select()" [ngClass]="selected?'bg-primary-subtle':''" hover-class="bg-primary-subtle">

what am I missing here ?

Thank you :)


Solution

  • You can use HostBinding to add the class the angular way, since we are using JS method, angular ngClass does not work properly.

    import {
      Directive,
      ElementRef,
      HostBinding,
      HostListener,
      Input,
    } from '@angular/core';
    
    @Directive({
      selector: '[hover-class]',
    })
    export class HoverClassDirective {
      selected = false;
    
      @Input() selectedExternal = false;
    
      @Input('hover-class') hoverClass: any;
    
      @HostBinding('class')
      get class() {
        return this.selected || this.selectedExternal ? this.hoverClass : '';
      }
    
      constructor(public elementRef: ElementRef) {}
    
      @HostListener('mouseenter') onMouseEnter() {
        this.selected = true;
        //this.elementRef.nativeElement.classList.add(this.hoverClass);
      }
    
      @HostListener('mouseleave') onMouseLeave() {
        this.selected = false;
        //this.elementRef.nativeElement.classList.remove(this.hoverClass);
      }
    }
    

    Stackblitz Demo