import React from "react" import classnames from "classnames" import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props' import { globalProps, GlobalProps } from '../utilities/globalProps' import Caption from '../pb_caption/_caption' import Body from '../pb_body/_body' import Title from '../pb_title/_title' import Icon from '../pb_icon/_icon' import Flex from '../pb_flex/_flex' type StarRatingProps = { aria?: {[key: string]: string}, className?: string, data?: object, dark?: boolean, fixedWidth?: boolean, layoutOption?: "default" | "number" | "onestar", htmlOptions?: {[key: string]: string | number | boolean | (() => void)}, icon?: string, id?: string, rating: number, denominator: number, colorOption?: "yellow" | "primary" | "subtle" | "outline", backgroundType?: "fill" | "outline", size?: "xs" | "sm" | "md" | "lg"; } & GlobalProps const StarRating = (props: StarRatingProps) => { const { aria = {}, className, data = {}, dark = false, layoutOption = "default", htmlOptions = {}, id, rating = 0, denominator = 5, colorOption = "yellow", backgroundType = "fill", size = "sm", } = props const classes = classnames(buildCss('pb_star_rating_kit'), globalProps(props), className) const ariaProps = buildAriaProps(aria) const dataProps = buildDataProps(data) const htmlProps = buildHtmlProps(htmlOptions) const denominatorStyle = layoutOption === "onestar" ? 1 : denominator const activeStars = Math.round(rating) > denominatorStyle ? denominatorStyle : Math.round(rating) const emptyStars = denominatorStyle - Math.round(rating) < 0 ? 0 : denominatorStyle - Math.round(rating) const oneDecimalRating = rating.toFixed(1) let iconSize = `pb_star_${size}` const starYellow = ( ) const starPrimary = ( ); const starSubtle = ( ); const starBackground = ( ) const starOutline = ( ) return (
{layoutOption === "number" && ( <> {size === 'xs' && ( )} {size === 'sm' && ( )} {size === 'md' && ( )} {size === 'lg' && ( )} </> )} <Flex className="star_flex_area"> {[...Array(activeStars)].map((_, index) => ( <React.Fragment key={index}> {colorOption === 'yellow' && ( <Icon // @ts-ignore customIcon={starYellow} className={iconSize} /> ) } {colorOption === 'primary' && ( <Icon // @ts-ignore customIcon={starPrimary} className={iconSize} /> ) } {colorOption === 'subtle' && ( <Icon // @ts-ignore customIcon={starSubtle} className={iconSize} /> ) } </React.Fragment> ))} {[...Array(emptyStars)].map((_, index) => ( <React.Fragment key={index}> {backgroundType === 'outline' && ( <Icon // @ts-ignore customIcon={starOutline} className={iconSize} /> ) } {backgroundType !== 'outline' && ( <Icon // @ts-ignore customIcon={starBackground} className={iconSize} /> ) } </React.Fragment> ))} </Flex> {layoutOption === "onestar" && ( <> {size === 'xs' && ( <Caption text={`${rating.toString()} of ${denominator}`} size="xs" dark={dark} className="pb_star_rating_number_sm" /> )} {size === 'sm' && ( <Caption text={`${rating.toString()} of ${denominator}`} size="xs" dark={dark} className="pb_star_rating_number_sm" /> )} {size === 'md' && ( <Body text={`${rating.toString()} of ${denominator}`} dark={dark} color="light" className="pb_star_rating_number_md" /> )} {size === 'lg' && ( <Title text={`${rating.toString()} of ${denominator}`} size={2} dark={dark} color="light" bold={false} className="pb_star_rating_number_lg" /> )} </> )} </div> ) } export default StarRating