Search code examples
angularfont-awesomeangular8ng-classproperty-binding

How to mix conditions and concatenation in [ngClass]


I have a div which needs to be blurred/reduced opacity on mouseenter.

I've created 2 css class called .blur and .less-opacity

Component.css

.blur {
    -webkit-filter: blur(10px);
    -moz-filter: blur(10px);
    -o-filter: blur(10px);
    -ms-filter: blur(10px);
    filter: blur(10px);
}

.less-opacity {
    opacity: 0.5;
}

I have variables in the TS to switch from blurred to non-blurred. There also are Input() variables and one of those is the name of a FontAwesome Icon.

Component.ts

...

  @Input() iconName: string; //Contains for example 'bed'
  @Input() subTitle: string;
  @Input() info: string;
  private isVisible: boolean = true;
  private isBlurred: boolean = false;

...

  switchVisible() {
    this.isVisible = !this.isVisible;
    this.isBlurred = !this.isBlurred;
  }


I can't figure out how to properly code the [ngClass] to have both conditions for .blur and .less-opacity and at the same time a concatenation for the FontAwesome Icon name.

Component.html

<div class="vignette d-flex flex-column justify-content-center align-items-center" (mouseenter)="switchVisible()" (mouseleave)="switchVisible()">
    <i [ngClass]="{ 'blur' : isBlurred, 'less-opacity' : !isVisible, 'fa-' + iconName : true }" class="vignette-icon fal fa-3x"></i>
    <p [ngClass]="{ 'blur' : isBlurred, 'less-opacity' : !isVisible}" class="vignette-subtitle px-3">{{ subTitle }}</p>
    <p class="vignette-info px-3"></p>
</div>

As you can see i've tried with the following method [ngClass]="{'my-class': expression, 'my-class2': expression }"

I don't have console errors but the icon class isn't properly set and result with an error icon.

Here's the result I have when the mouseenter event is fired

enter image description here

The .blur and .less-opacity classes are properly added to the <p>, but the <i> isn't properly set.

My question is : How should I code the [ngClass] for the <i> which needs concatenation in the classname ?


Solution

  • To achieve this, I had to find a workaround as long as I couldn't find any way to make it work properly with only one [ngClass].

    I have wrapped the <i> in a span and apply .blurred and .less-opacity to the span. Additionally, I have a simple [ngClass] for the <i> tag with the iconName set as wanted.

    Component.html

    ...
    <span class="vignette-icon" [ngClass]="{ 'blur' : isBlurred, 'less-opacity' : !isVisible }">
     <i [ngClass]="'fa-3x fal ' + iconName"></i>
    </span>
    ...
    

    Component.ts

    ...
    @Input() iconName: string;
    
    ...
    
    ngOnInit() {
     this.setIconName(this.iconName);
    }
    
    ...
    
    setIconName(iconName: string) {
     if(!iconName.includes('fa-')) {
       this.iconName = 'fa-' + iconName;
     }
    }
    
    ...
    

    It works fine like this!