A guide to filling an irregular shape (such as a star) based on a percentage using CSS in a React project

I am currently working on developing a React component that showcases a rating percentage using a star icon with two different shades.

For example, if the input rating is 79%, I want to display a star with 79% of it in gold color and the remaining 21% in grey.

At this point, I have managed to place two separate stars from the Font Awesome library in the same location (one in gold and one in grey).

You can find my code in this sandbox and below:

import React from 'react';
import { FaStar } from "react-icons/fa";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
    starFill: {
        cursor: 'pointer',
        transition: 'color 200ms',
        position: 'absolute',
        top: '25%',
        left: '50%',
        transform: 'translate(-50%, -75%)',
        zIndex: 1
    },
    starContainer: {
        cursor: 'pointer',
        transition: 'color 200ms',
        position: 'absolute',
        top: '25%',
        left: '50%',
        transform: 'translate(-50%, -75%)',
        zIndex: 2
    }
}));

const StarRating = (percentRating) => {

    const classes = useStyles();
    
    console.log(percentRating);

    return (
        <React.Fragment>
            <div className={classes.starFill}>
                <FaStar color='#ffc107' size={200} />
            </div>
            <div className={classes.starContainer}>
                <FaStar color='#e4e5e9' size={200} />
            </div>
        </React.Fragment>
    )
}

export default StarRating;

Answer №1

After some experimentation, I successfully achieved my objective by adjusting the star's zIndexes and modifying its width to a percentage while adding overflow:hidden to the style.

You can view my sandbox here and find the code below:

import React from 'react';
import { FaStar } from "react-icons/fa";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
    starFill: {
        cursor: 'pointer',
        transition: 'color 200ms',
        position: 'absolute',
        top: '25%',
        left: '50%',
        transform: 'translate(-50%, -75%)',
        zIndex: 2,
    },
    starContainer: {
        cursor: 'pointer',
        transition: 'color 200ms',
        position: 'absolute',
        top: '25%',
        left: '50%',
        transform: 'translate(-50%, -75%)',
        zIndex: 1,
    }
}));

const StarRating = ({ rating = 100, size = 200, ...props }) => {

    const classes = useStyles();

    rating = (rating / 100) * size;

    return (
        <React.Fragment>
            <div className={classes.starFill}>
                <div style={{ width: rating, overflow: 'hidden' }}>
                    <FaStar color='#ffc107' size={size} />
                </div>
                {/* transparent div to reserve the complementary spacing */}
                <div style={{ width: size }}>
                </div>
            </div>
            <div className={classes.starContainer}>
                <FaStar color='#e4e5e9' size={size} />
            </div>
        </React.Fragment>
    )
}

export default StarRating;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Changing React Phone Number input field's default style: A step-by-step guide

Is there a way to modify the appearance of the react-phone-number-input component using this npm package: https://www.npmjs.com/package/react-phone-number-input? I am working with React Hook Form and Tailwind CSS alongside this component. However, I' ...

A layout featuring a grid design that includes spacing and gutters between items, however, there is no spacing between the items

I am looking to create a grid layout where each child element represents an individual grid square. However, I am facing an issue with spacing between the children and the parent container, which is not desired. How can I eliminate this unwanted space? U ...

The method of importing overrides in Storybook

My component 'ReportWrapper' is structured as shown below. It imports 'getReportData', which asynchronously returns data. import { getReportData } from "../dataFecther"; export const ReportWrapper = ({ query }) => { con ...

Issues with React - Material UI Menu functionality

I'm encountering an issue with the menu/menu item component from material ui when trying to render it based on a condition. Here is my code snippet... const AddSelectItemButton = () => { return ( <> <Fab ar ...

The React Material UI Select component shows an issue where the selected value does not update after choosing an item from the dropdown menu

This snippet represents a portion of the code I have been working on. My approach involves fetching drug data and categorizing them based on their class. I then proceed to map these categories, checking if a drug belongs to a certain category. If it does, ...

Keeping track of both the search query and the results

I have stored the current search term in a state using e.target.value as searchField, but when I clear the input value, I can no longer use it. I want to display a message in the body informing the user that their specific searched term yielded no results, ...

Where should API keys be securely stored in a React application?

Currently working on a collaborative React project where we are utilizing various third-party services that require API keys. The challenge is that we have been storing these keys directly in the code, which I am aware is not secure. Seeking recommendatio ...

Having difficulties uploading images to an existing entry in Strapi version 4

Having trouble identifying the issue here. The upload process is successful, as the image is added to both the media library and cloudinary. However, the data does not seem to be getting added to the entry. Below is the code snippet in question: const for ...

I am puzzled as to why my DataGrid MUI component is not functioning properly

I am taking my first steps with MUI, the MaterialUI React Component library. After following the installation instructions in the documentation, I am now attempting to integrate the DataGrid component into my React project. My goal is to replicate the fir ...

Eliminate the dimming background on a discussion thread in Discourse

Working on customizing a theme for my blog using the Discourse engine has been quite interesting. I have noticed that every post, or "topic," loads with a blue background that quickly transitions to the main background color. You can take a look at an exam ...

Implementing multiSelect feature in Material-Ui on a react js application

I have implemented multi-select in my project. The selected values are displayed using the renderValue prop of the Select component. Below is the code snippet: <Select labelId="demo-mutiple-checkbox-label" id="demo-mutiple-che ...

Returning to the previous state in React Hooks after searching a table involves implementing a specific logic within

My current objective is: To search a table using the search bar and display filtered patients in real-time. To revert back to displaying all patients if the search bar is empty or if the user cancels the search. The problem I'm facing: I am unable ...

Measure with an "em" unit indicated by a dot

Could you clarify if there is a distinction between writing padding:.6em and padding:0.6em; and if they have the same value, why not just use padding:0.6em; ? Thank you ...

When the object reference remains the same, useState will accept updates

My understanding was that useState required a new value to accept updates: To demonstrate this, I have created a codesandbox. In my scenario, I have a nested data structure like the following: const state = { name: "parent", data: { ...

ts:Accessing the state within a Redux store

In my rootReducer, I have a collection of normal reducers and slice reducers. To access the state inside these reducers, I am using the useSelector hook. Here is my store setup : const store = configureStore({reducer : rootReducer}); Main Reducer: const ...

Creating a large and spacious modal in Angular using ngx-bootstrap

I need help with resizing the ngx-modal to cover a large area of the screen. Currently, I am trying to make it so that when something is clicked, the modal should overlay an 80% width grid on a full desktop screen. Despite my attempts at using .modal-xl an ...

How to Keep MUI Draggable Dialog Within Screen Boundaries in React

Currently, I am utilizing the MUI library and focusing on the Draggable Dialog component available here. My main inquiry revolves around how to restrict the dialog from being dragged beyond the screen boundaries. Even after attempting to implement the fo ...

How can we efficiently loop through all the icons in React Material-UI?

I am looking to iterate over all the icons from @material-ui/icons in a React application. If I want to import a single icon, I can do so like this import IconNameIcon from '@material-ui/icons/IconName' and then use it in my component like th ...

Showing a hidden div after an unsuccessful AJAX call

Encountering an issue with displaying a div notification using the code snippet below: $.ajax({ url: url, cache: false, async: false, success: function (data) { response = jQuery.parseJSON(data); }, error: functi ...

Receiving an error while passing properties to a React component: "Property 'firstName' is not found on type 'Readonly<{}>'."

As a beginner in React, I need some patience I'm attempting to create a simple component where users can input their first and last names, update the values, and see them displayed after clicking a button. However, I keep encountering TypeScript comp ...