Star Review

by Paco86

HTML

<div id="root">
</div>

CSS

.star-review {
  display: flex;
}

.star:before {
  content: '★';
  font-size: 1.5rem; 
  opacity: 0.1;
}

.star--active:before {
  color: #3c74ff;
  opacity: 1;
}

JavaScript

class StarReview {
	constructor(root) {
  	this.root = root;
    this.rating = 0;
    this.stars = null;
    this.onMouseOver = this.onMouseOver.bind(this);
    this.onMouseLeave = this.onMouseLeave.bind(this);
    this.onClick = this.onClick.bind(this);
  }
  
  init() {
  	this.generateStars();
    this.stars = this.root.querySelectorAll('.star');
    this.root.addEventListener('mouseover', this.onMouseOver);
    this.root.addEventListener('mouseleave', this.onMouseLeave);
    this.root.addEventListener('click', this.onClick);
  }
  
  generateStars() {
  	const stars = new Array(5).fill(null).map((_, index) => {
    	const activeClass = index + 1 <= this.rating ? 'star--active' : '';
    	return `
        <div 
        	class="star ${ activeClass }" 
          data-value="${ index + 1 }" 
          aria-label="Set star review to ${index + 1}"
          aria-select="${ this.rating === index + 1 }">
        </div>
      `;
    }).join('');
    
    this.root.innerHTML =  `
    	<div class="star-review">
      	${ stars }
    	</div>
    `;
  }
  
  onMouseOver(event) {
  	this.rating = +event.target.dataset.value;
    this.selectStar();
  }
  
  onMouseLeave() {
  	this.rating = 0;
    this.selectStar();
  }
  
  onClick(event) {debugger
  	this.rating = +event.target.dataset.value;
    
    this.root.removeEventListener('mouseover', this.onMouseOver);
    this.root.removeEventListener('mouseleave', this.onMouseLeave);
    this.root.removeEventListener('click', this.onClick);
  }
  
  selectStar() {
  	this.stars.forEach((starEl, index) => {
    	if (index < this.rating) {
      	starEl.classList.add('star--active');
      } else {
      	starEl.classList.remove('star--active');
      }
    });
  }
}

const starReview = new StarReview(document.querySelector('#root'));
starReview.init();