importReact,{ useState }from"react";importReactDOMfrom"react-dom/client";// import './index.css';// import App from './App';importStarRatingfrom"./StarRating";/* ------------------------------------------------------ */// If we want to use the "rating number" that was set using the star valuefunctionTest(){const[movieRating, setMovieRating]=useState(0);return(<><StarRating
maxRating={5}
color={"#900fff"}
size={30}
className={"test"}
defaultRating={3}
onSetRating={setMovieRating}/><p>This movie was rated {movieRating} stars </p></>);}/* ------------------------------------------------------ */const root =ReactDOM.createRoot(document.getElementById("root"));
root.render(<React.StrictMode>{/* <App /> */}<StarRating
maxRating={5}
color={"#fcc419"}
size={48}
className={"test"}
messages={["Very Bad","Bad","Okay","Good","Amazing"]}/><StarRating
maxRating={5}
color={"#fc2419"}
size={30}
className={"test"}
defaultRating={3}/><Test/></React.StrictMode>);
StarRating.js
/* TO USE THIS COMPONENT : →
<StarRating maxRating={5} color = {"#fcc419"} size = {48} className={"test"} messages={["Very Bad", "Bad", "Okay", "Good", "Amazing"]}/>
<StarRating maxRating={5} color = {"#fc2419"} size = {30} className={"test"} defaultRating={3}/>
... */import{ useState }from"react";importPropTypesfrom"prop-types"// used to specify the type of value (integer, string, ...) that we expect the consumer of the component to pass in for each of the props. For e.g. the maxRating should only be a number and nothing else.const containerStyle ={display:"flex",alignItems:"center",gap:"16px",};const starContainerStyle ={display:"flex",gap:"4px",};StarRating.propTypes={maxRating:PropTypes.number,// if we now enter a string instead of a number in maxRating then we'll get an error in the console of the web browserdefaultRating:PropTypes.number,color:PropTypes.string,size:PropTypes.number,messages:PropTypes.array,className:PropTypes.string,onSetRating:PropTypes.func,// we also have .bool and .object }// {maxRating = 5} : we are destructuring and setting the default value in case the object doesn't exist or is not specified by the userexportdefaultfunctionStarRating({
maxRating =1,
color ="#fcc419",
size =48,
className ="",
messages =[],
defaultRating=0,
onSetRating,}){const[rating, setRating]=useState(defaultRating);const[tempRating, setTempRating]=useState(0);functionhandleRating(rating){setRating(rating);if(onSetRating)onSetRating(rating);}const textStyle ={lineHeight:"1",margin:"0",color: color,fontSize:`${size /1.5}px`,};return(<div className={className} style={containerStyle}><div style={starContainerStyle}>{Array.from({length: maxRating },(_, i)=>(<Star
key={i}
full={tempRating ? tempRating >= i +1: rating >= i +1}
onRate={()=>handleRating(i +1)}
onHoverIn={()=>setTempRating(i +1)}
onHoverOut={()=>setTempRating(0)}
color={color}
size={size}/>))}</div><p style={textStyle}>{messages.length===maxRating ? messages[tempRating ? tempRating-1: rating-1]:(tempRating || rating ||"")}</p></div>);}functionStar({ onRate, full, onHoverIn, onHoverOut, color, size }){const starStyle ={width:`${size}px`,height:`${size}px`,display:"block",cursor:"pointer",color: color,fontSize:`${size /1.5}px`,};return(// onMouseEnter and onMouseLeave below are used for Hover Recognition<span
role="button"
style={starStyle}
onMouseEnter={onHoverIn}
onMouseLeave={onHoverOut}
onClick={onRate}>{full ?(<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill={color}
stroke={color}><path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/></svg>):(<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke={color}><path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="{2}"
d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"/></svg>)}</span>);}