import React, {
forwardRef,
type HTMLAttributes,
type ReactNode,
useState,
} from 'react'
import { Icon, IconButton } from '../..'
import List from '../../atoms/List'
export interface RatingProps
extends Omit, 'onChange'> {
/**
* ID to find this component in testing tools (e.g.: cypress, testing library, and jest).
*/
testId?: string
/**
* The length of child elements.
*/
length?: number
/**
* The current value of the rating, based on the quantity of child elements.
*/
value: number
/**
* Icon to represent the rating score unit (e.g.: a component)
*/
icon?: ReactNode
/**
* Function to be triggered when Rating option change. This should only be used if you and an actionable rating list.
*/
onChange?: (value: number) => void
/**
* Specifies that the actionable rating should be disabled.
*/
disabled?: boolean
}
export interface RatingItemProps {
'data-fs-rating-item'?: 'full' | 'partial' | 'empty'
'data-testid'?: string
}
const Rating = forwardRef(function Rating(
{
children,
testId = 'fs-rating',
length = 5,
value = 0,
icon,
onChange,
disabled,
...otherProps
},
ref
) {
const [hover, setHover] = useState(0)
const outlineProps = { 'data-fs-rating-icon-outline': true }
const ratingIcon = React.isValidElement(icon) ? icon :
return (
{Array.from({ length }).map((_, index: number) => {
const tempIndex = index + 1
const fillCheck = () => {
if (tempIndex <= (hover || value)) {
return 'full'
}
if (tempIndex - value > 0 && tempIndex - value < 1) {
return 'partial'
}
return 'empty'
}
return (
{onChange ? (
{
onChange(tempIndex)
}}
onMouseEnter={() => setHover(tempIndex)}
onMouseLeave={() => setHover(value)}
disabled={disabled}
/>
) : (
<>
{ratingIcon}
{React.isValidElement(icon) ? (
React.cloneElement(icon, outlineProps)
) : (
)}
>
)}
)
})}
)
})
export default Rating