star component react code example

Example: reusable star rating component in react

import {
  Box,
  createStyles,
  Grid,
  Input,
  makeStyles,
  Theme,
  FormHelperText
} from '@material-ui/core';
import React from 'react';
import StarIcon from '@material-ui/icons/Star';
import clsx from 'clsx';

//---------------------------------------------------
const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    unCheckedIcon: {
      color: 'grey',
      fontSize: '50px'
    },
    poorRating: {
      color: '#ff2824',
      fontSize: '50px'
    },
    badRating: {
      color: '#F7680C',
      fontSize: '50px'
    },
    averageRating: {
      color: '#FF9529',
      fontSize: '50px'
    },
    goodRating: {
      color: '#FDCC0D',
      fontSize: '50px'
    },
    greatRating: {
      color: '#FFDF00',
      fontSize: '50px'
    }
  })
);

export default function StarRating({
  register,
  error,
  helperText,
  name
}: {
  register: any;
  error: any;
  helperText: any;
  name: any;
}) {
  const classes = useStyles();
  const [rating, setRating] = React.useState(0);
  const [hover, setHover] = React.useState(0);

  return (
    <Grid item xs={12}>
      <Box >
        <div>
          {[...Array(5)].map((s, i) => {
            const ratingValue = i + 1;

            return (
              <label key={i}>
                <Input
                  type="radio"
                  name={name}
                  inputRef={register}
                  error={error}
                  hidden
                  value={ratingValue}
                  onClick={() => setRating(ratingValue)}
                />
                <StarIcon
                  className={
                    ratingValue <= (hover || rating)
                      ? clsx({
                          [classes.poorRating]: ratingValue === 1,
                          [classes.badRating]: ratingValue === 2,
                          [classes.averageRating]: ratingValue === 3,
                          [classes.goodRating]: ratingValue === 4,
                          [classes.greatRating]: ratingValue === 5
                        })
                      : classes.unCheckedIcon
                  }
                  onMouseEnter={() => setHover(ratingValue)}
                  onMouseLeave={() => setHover(rating)}
                  fontSize="large"
                />
              </label>
            );
          })}
          {error && helperText && (
            <FormHelperText error={true}>{helperText}</FormHelperText>
          )}
        </div>
      </Box>
    </Grid>
  );
}