Home > other >  Unable to remove active box shadow after clicking outside of Angular component
Unable to remove active box shadow after clicking outside of Angular component

Time:05-17

I'm working on this blog which has a page which lists all the posts. So I added custom hover and active styles to each of the posts so when hovered it will show a different color and box-shadow intensity based on each post post.

Suppose Post1 has a red color associated with it so its default box-shadow color will be red and its blur will be 10px. But when hovered or clicked, it's box-shadow will also be red but blur will be 30px to focus that it is being hovered/clicked.

Now for Post2 if the associated color is blue, then it will have default and hover/active box-shadow color to be blue and blur will be 10px and 30px respectively.

When clicked outside a post or on another post the active box-shadow on the current post will go back to default (10px). And this is what I am unable to achieve right now. The active shadow on the current post doesn't go away.

This is the component:

@Component({
  selector: 'post',
  templateUrl: './post.component.html', 
  styleUrls: ['./post.component.scss']
})
class Post {
  hoverPostId: number;
  clickedPostId: number;

  constructor() {}

  defaultStyle( color ) {
    const boxShadow = `1px 10px 1px ${color}`;    

    return {
      'box-shadow': boxShadow
    };
  }

  hoverActiveStyle( color ) {
    const boxShadow = `1px 30px 1px ${color}`;    

    return {
      'box-shadow': boxShadow
    };
  }

  postActive( postId: number ) {

    if ( this.post.id === postId ) {
      this.clickedPostId = postId;
    } else {
      this.clickedPostId = null;
    }

  }

  mouseEnter( postId: number ) {
    this.hoverPostId = postId;
  }

  mouseLeave() {
    this.hoverPostId = null;
  }

}

export default Post;

This is the template:

<div 
   
  [ngStyle]="hoverPostId === post.id || clickedPostId === post.id ? hoverActiveStyle(post.color) : defaultStyle(post.color)"
  (mouseenter)="mouseEnter(post.id)"
  (mouseleave)="mouseLeave()"
  (click)="postActive(post.id)"
>

   // post content
  
</div>

Please note that I can't hardcode the styles in scss file for hover and active class because each of the posts color will be unique. So please don't suggest that.

=======UPDATE========

It is also worth mentioning that in my Post component I have access to the post that is selected. Something like this.posts.selected which returns an array of only one post which has been selected. It returns empty if unselected.

CodePudding user response:

Try to put a tabindex atribute to the div

<div 
  tabindex="0"
   
  [ngStyle]="hoverPostId === post.id || clickedPostId === post.id ? hoverActiveStyle(post.color) : defaultStyle(post.color)"
  (mouseenter)="mouseEnter(post.id)"
  (mouseleave)="mouseLeave()"
  (click)="postActive(post.id)"
  (blur)="onBlur()"
>

   // post content
  
</div>

If you have this inside an *ngFor you could use the index of the iteration

  [tabindex]="i"

The (blur) event fires when the element lose focus. With the tabindex the focus is setted.

  onBlur() {
    this.clickedPostId = null;
    // Or do your thing here
  }
  • Related