import { cx } from "emotion"; import * as React from "react"; import { disabledStyle, selectedStar, unSelectedStar, wrapStyle } from "./styles/Rating.styles"; import { RatingProps, RatingState } from "./typings/Rating"; function generateStars(maxRating: number, selectedValue: number) { return Array.from({ length: maxRating }, (_, i) => { return { active: i + 1 <= selectedValue }; }); } class Rating extends React.PureComponent { constructor(props: RatingProps) { super(props); this.state = { stars: generateStars(props.maxRating, props.value) }; } componentDidUpdate(prevProps: RatingProps) { const { maxRating, value } = this.props; if (prevProps.maxRating !== maxRating) { this.setState({ stars: generateStars(maxRating, value) }); } } setRating = (rating: number) => { const { maxRating, disabled } = this.props; if (disabled) { return; } this.setState({ stars: generateStars(maxRating, rating) }); }; render() { const { name, value, onChange, disabled, className } = this.props; const { stars } = this.state; const _className = cx(wrapStyle, className, disabled && disabledStyle); return (
{stars.map((star, starIndex) => { const rating = starIndex + 1; return ( this.setRating(rating)} onMouseLeave={() => this.setRating(value)} onClick={() => { if (disabled) { return; } this.setRating(rating); onChange(rating); }} > ); })}
); } } export default Rating;