article

Sunday, October 10, 2021

ReactJS Star Rating

ReactJS Star Rating
scr/index.js
//scr/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
public/index.html
//public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>ReactJS </title>
  </head>
  <body>
    <div id="root"></div>
</body>
</html>
src/App.js
//src/App.js
import React, { useState, useEffect } from "react";
import './App.css';
import { ReactComponent as Logo } from "./logo.svg";

const Star = ({ starId, rating, onMouseEnter, onMouseLeave, onClick }) => {
  let styleClass = "star-rating-blank";
  if (rating && rating >= starId) {
    styleClass = "star-rating-filled";
  }

  return (
    <div
      className="star"
      onMouseEnter={onMouseEnter}
      onMouseLeave={onMouseLeave}
      onClick={onClick}
    >
      <svg
        height="55px"
        width="53px"
        class={styleClass}
        viewBox="0 0 25 23"
        data-rating="1"
      >
        <polygon
          stroke-width="0"
          points="9.9, 1.1, 3.3, 21.78, 19.8, 8.58, 0, 8.58, 16.5, 21.78"
        />
      </svg>
    </div>
  );
};

function App() {
  const [rating, setRating] = useState(0);
  const [hoverRating, setHoverRating] = useState(0);
  const stars = [1, 2, 3, 4, 5];

  return (
    <div className="App">
      <div class="header">
        <h1>Star Rating</h1>
        <Logo />
        <div class="logo"></div>
      </div>
      <div class="flex-container">
        {stars.map((star, i) => (
          <Star
            key={i}
            starId={i}
            rating={hoverRating || rating}
            onMouseEnter={() => setHoverRating(i)}
            onMouseLeave={() => setHoverRating(0)}
            onClick={() => setRating(i)}
          />
        ))}
      </div>
    </div>
  );
}

export default App;
src/App.css
//src/App.css
.App {
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

body {
  background-color: rgb(244, 236, 244);
}

.star-rating-filled {
  fill: gold;
}

.star-rating-blank {
  fill: #d8d8d8;
}

.logo {
  background-image: url('./logo.png');
  height: 70px;
  width: 200px;
  background-size: contain;
  background-repeat: no-repeat;
}

.flex-container {
  display: flex;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

Related Post