Star Rating

Star Rating

Javascript/React Star Rater

Javascript

<div className="star-rating-zone">
 <p className="rating">
     <input className="star" type="radio" id="star5" name="rating" value="5" onChange={(e) => { this.setState({ rate: 5 }) }} />
     <label className="full" htmlFor="star5"></label>
     <input className="star" type="radio" id="star4" name="rating" value="4" onChange={(e) => { this.setState({ rate: 4 }) }} />
     <label className="full" htmlFor="star4"></label>
     <input className="star" type="radio" id="star3" name="rating" value="3" onChange={(e) => { this.setState({ rate: 3 }) }} />
     <label className="full" htmlFor="star3"></label>
     <input className="star" type="radio" id="star2" name="rating" value="2" onChange={(e) => { this.setState({ rate: 2 }) }} />
     <label className="full" htmlFor="star2" ></label>
     <input className="star" type="radio" id="star1" name="rating" value="1" onChange={(e) => { this.setState({ rate: 1 }) }} />
     <label className="full" htmlFor="star1"></label>
 </p>
</div>
@import url(//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css);

.star-rating-zone {
    width: 100%;
    text-align: center;

    p {
     margin-top: 17px;
     font-size: 12px;
     line-height: 1.67;
     color: #8a8a8a;
    }

    .rating {
     width: 170px;
     height: 25.5px;
     margin: 0 auto;
    }

    .rating > input { 
     display: none;
    }

    .rating > label:before { 
     margin: 5px;
     font-size: 25px;
     font-family: FontAwesome;
     // "\f005"는 꽉 찬 별모양
     content: "\f006";
    }
 
    .rating > label { 
     color: #51ddc5;
     float: right;
    }

    /* hover 했을 때 애니메이션 효과 */
    .rating > label.full:hover {
     transform: rotate(-15deg) scale(1.3);
    }

    /* 선텍헸을 때, 꽉 찬 별로 교체 */
    input.star:checked ~ label.full:before {
     content: '\f005';
     color: #51ddc5;
     transition: all .25s;
    }
}

React

// App.js
import Star from 'components/Star/Star';

<Star
    count={5}
    onChange={this.onChange}
/>

// Star.js
import React, { Component } from 'react';
import './Star.scss';

class Star extends Component {

  state = {
    rate: 0
  }

  renderStar() {
    const { count } = this.props;

    let arrStar = [];

    for (let i = count; i > 0; i--) {
        arrStar.push(
            <span key={i}>
                <input className="star"
                       type="radio"
                       id={"star" + i}
                       name="rating"
                       value={i}
                       onChange={(e) => {
                        this.props.onChange(i);
                        this.setState({ rate: i })
                        }}
                />
                <label
                    className={`full ${this.state.rate >= i ? 'on' : ''}`}
                    htmlFor={"star" + i}>
                </label>
            </span>
        )
    }
    return arrStar;
}

  render() {
    const { readonly } = this.props;

    return (
      <div className="star-component">
        <div className="star-rating-zone">
          <p className="rating">
            {this.renderStar()}
          </p>
        </div>
      </div>
    )
  }
}

export default Star;
/* Star.scss */
.star-component {
  .star-rating-zone {
 width: 100%;
 text-align: center;
  
    .rating {
      width: 175px;
      height: 25.5px;
      margin: 0 auto;
    }
  
    .rating span > input { 
      display: none;
    }
  
    .rating span > label.full:before { 
      margin-right: 8px;
      font-size: 25px;
      width: 27px;
      height: 25.5px;
      background: url("#{$cdn}/ratings/ratings-reviews-star@3x.png");
      background-size: 27px 25px;
      display: inline-block;
      content: "";
    }
  
    .rating span > label.full { 
      color: $theme;
      float: right;
    }
  
    /* hover 했을 때 애니메이션 효과 */
    .rating span > label.full:hover {
      transform: rotate(-15deg) scale(1.3);
    }
  
    /* 선텍헸을 때, 꽉 찬 별로 교체 */
    input.star:checked ~ label.full:before,
    .on:before {
      color: $theme;
      transition: all .25s;
      background-image: url("#{$cdn}/ratings/ratings-reviews-filled-star@3x.png") !important;
      background-size: 27px 25px;
      display: inline-block;
      width: 27px;
      height: 25.5px;
      content: "";
    }
  }

참고

댓글

가장 많이 본 글