Skip to main content

Rc Rate

A component for getting word of experience of the user.

Installation


  1. Install the rc-rate package.
npm i rc-rate
  1. Create a rate component, components/rate.tsx
import React, { forwardRef } from "react";
import RcRate from "rc-rate";
import type { RateProps as RcRateProps } from "rc-rate/lib/Rate";
import type { StarProps as RcStarProps } from "rc-rate/lib/Star";
import { StarIcon } from "@heroicons/react/24/outline";
import { cn, FieldError, FieldHelperText, Tooltip } from "rizzui";

const labelStyles = {
size: {
sm: "text-xs mb-1",
md: "text-sm mb-1.5",
lg: "text-sm mb-1.5",
xl: "text-base mb-2",
},
};

const rateStyles = {
base: "flex items-center [&>li]:cursor-pointer [&.rc-rate-disabled>li]:cursor-default [&>li]:relative [&>li]:mr-0.5 rtl:[&>li]:ml-0.5 [&>li]:inline-block text-muted",
size: {
sm: "h-5 w-5",
md: "h-6 w-6",
lg: "h-7 w-7",
xl: "h-8 w-8",
},
firstStar:
"[&>li>div>.rc-rate-star-first]:absolute [&>li>div>.rc-rate-star-first]:left-0 rtl:[&>li>div>.rc-rate-star-first]:right-0 [&>li>div>.rc-rate-star-first]:top-0 [&>li>div>.rc-rate-star-first]:w-1/2 [&>li>div>.rc-rate-star-first]:h-full [&>li>div>.rc-rate-star-first]:overflow-hidden",
color:
"[&>.rc-rate-star-half>div>.rc-rate-star-first]:text-orange [&>.rc-rate-star-full>div]:text-orange",
transition:
"[&>li>div]:transition-all [&>li>div]:duration-300 [&>.rc-rate-star:hover]:scale-110",
};

export interface RateProps
extends Omit<RcRateProps, "character" | "className"> {
label?: React.ReactNode;
size?: keyof typeof rateStyles.size;
character?: React.ReactNode | Array<React.ReactNode>;
characterClassName?: string;
tooltips?: Array<string>;
helperText?: React.ReactNode;
error?: string;
labelClassName?: string;
rateClassName?: string;
errorClassName?: string;
helperClassName?: string;
className?: string;
}

const Rate = forwardRef<any, RateProps>(
(
{
size = "md",
disabled = false,
character = <StarIcon />,
label,
tooltips,
error,
helperText,
labelClassName,
characterClassName,
errorClassName,
helperClassName,
rateClassName,
className,
...props
},
ref
) => {
const characterRender = (
node: React.ReactElement,
{ index }: RcStarProps
) => {
if (!tooltips) {
return node;
}

return (
<Tooltip content={tooltips[index as number]} placement="top">
{node}
</Tooltip>
);
};

return (
<div className={cn("aegon-rate", className)}>
{label && (
<div
className={cn(
"block font-medium",
labelStyles.size[size],
labelClassName
)}
>
{label}
</div>
)}

<RcRate
ref={ref}
disabled={disabled}
characterRender={characterRender}
character={({ index }: RcStarProps) => (
<div
className={cn(
"[&>svg]:fill-current",
rateStyles.size[size],
characterClassName
)}
>
{Array.isArray(character)
? character[index as number]
: character}
</div>
)}
className={cn(
rateStyles.base,
rateStyles.firstStar,
rateStyles.color,
!disabled && rateStyles.transition,
rateClassName
)}
{...props}
/>

{!error && helperText && (
<FieldHelperText tag="div" size={size} className={helperClassName}>
{helperText}
</FieldHelperText>
)}

{error && (
<FieldError size={size} error={error} className={errorClassName} />
)}
</div>
);
}
);

Rate.displayName = "Rate";

export default Rate;

Default

The default style of Rate component.

import { Rate } from "@components/rate";

export default function App() {
return <Rate />;
}

Sizes

You can set diffirent sizes of the Rate component using size property.

Small
Default
Large
Extra Large
import { Rate } from "@components/rate";

export default function App() {
return (
<>
<Rate size="sm" label="Small" />
<Rate label="Default" />
<Rate size="lg" label="Large" />
<Rate size="xl" label="Extra Large" />
</>
);
}

With Tooltips

You can add tooltip to the Rate component using tooltips property.

import { Rate } from "@components/rate";

export default function App() {
return (
<Rate
size="xl"
defaultValue={3}
tooltips={["terrible", "bad", "normal", "good", "wonderful"]}
/>
);
}

With Half Rate

User can select half star when you add allowHalf property to the Rate component.

import { Rate } from "@components/rate";

export default function App() {
return <Rate size="xl" allowHalf defaultValue={1.5} />;
}

With Custom Character

You can set custom charater to the Rate component using character property.

import { Rate } from "@components/rate";
import { HeartIcon } from "@heroicons/react/24/solid";

export default function App() {
return (
<Rate
character={<HeartIcon className="w-6" />}
defaultValue={1.5}
size="xl"
/>
);
}

With Character Emoji

Use any custom characker emoji to the Rate component using character property.

import { Rate } from "@components/rate";

const emoji = [
<svg
key="1"
viewBox="0 0 16 16"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<g clipPath="url(#clip0_1377_2673)">
<path d="M7.99998 16C12.4183 16 16 12.4183 16 7.99998C16 3.58171 12.4183 0 7.99998 0C3.58171 0 0 3.58171 0 7.99998C0 12.4183 3.58171 16 7.99998 16Z" />
<path
d="M12.0618 11.9771C9.83077 9.6716 6.16516 9.67171 3.9343 11.9773C3.65109 12.2699 4.09726 12.7171 4.38085 12.4239C6.37737 10.3605 9.61856 10.3604 11.6152 12.4236C11.8988 12.7167 12.3451 12.2697 12.0618 11.9771Z"
fill="#111111"
/>
<path
d="M5.56891 7.75891C6.2628 7.75891 6.82532 7.1964 6.82532 6.5025C6.82532 5.80861 6.2628 5.24609 5.56891 5.24609C4.87501 5.24609 4.3125 5.80861 4.3125 6.5025C4.3125 7.1964 4.87501 7.75891 5.56891 7.75891Z"
fill="#111111"
/>
<path
d="M10.3189 7.75891C11.0128 7.75891 11.5753 7.1964 11.5753 6.5025C11.5753 5.80861 11.0128 5.24609 10.3189 5.24609C9.62501 5.24609 9.0625 5.80861 9.0625 6.5025C9.0625 7.1964 9.62501 7.75891 10.3189 7.75891Z"
fill="#111111"
/>
<path
d="M10.6787 2.30807C9.71057 3.27607 8.74257 4.2442 7.77454 5.21223C7.92335 5.21223 8.07227 5.21223 8.22108 5.21223C7.25308 4.2441 6.28505 3.2761 5.31706 2.30807C5.02878 2.01979 4.58224 2.46633 4.87051 2.75461C5.83851 3.72274 6.80654 4.69074 7.77454 5.65877C7.89618 5.78041 8.09945 5.78041 8.22108 5.65877C9.18922 4.69077 10.1572 3.72264 11.1252 2.75461C11.4135 2.46633 10.9668 2.01966 10.6787 2.30807Z"
fill="#111111"
/>
</g>
<defs>
<clipPath id="clip0_1377_2673">
<rect width="16" height="16" fill="white" />
</clipPath>
</defs>
</svg>,

<svg
key="2"
viewBox="0 0 16 16"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<g clipPath="url(#clip0_1377_2667)">
<path d="M7.99998 16C12.4183 16 16 12.4183 16 7.99998C16 3.58171 12.4183 0 7.99998 0C3.58171 0 0 3.58171 0 7.99998C0 12.4183 3.58171 16 7.99998 16Z" />
<path
d="M12.0399 11.9536C9.80414 9.67085 6.15709 9.68034 3.9343 11.9774C3.65109 12.2699 4.09726 12.7171 4.38085 12.4239C6.36829 10.3703 9.5929 10.3577 11.5933 12.4002C11.8787 12.6916 12.325 12.2447 12.0399 11.9536Z"
fill="#111111"
/>
<path
d="M5.56891 6.49719C6.2628 6.49719 6.82532 5.93468 6.82532 5.24078C6.82532 4.54689 6.2628 3.98438 5.56891 3.98438C4.87501 3.98438 4.3125 4.54689 4.3125 5.24078C4.3125 5.93468 4.87501 6.49719 5.56891 6.49719Z"
fill="#111111"
/>
<path
d="M10.3189 6.49719C11.0128 6.49719 11.5753 5.93468 11.5753 5.24078C11.5753 4.54689 11.0128 3.98438 10.3189 3.98438C9.62501 3.98438 9.0625 4.54689 9.0625 5.24078C9.0625 5.93468 9.62501 6.49719 10.3189 6.49719Z"
fill="#111111"
/>
</g>
<defs>
<clipPath id="clip0_1377_2667">
<rect width="16" height="16" fill="white" />
</clipPath>
</defs>
</svg>,

<svg
key="3"
viewBox="0 0 16 16"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<g clipPath="url(#clip0_1377_2661)">
<path d="M8.00002 16C12.4183 16 16 12.4183 16 8.00002C16 3.58173 12.4183 0 8.00002 0C3.58173 0 0 3.58173 0 8.00002C0 12.4183 3.58173 16 8.00002 16Z" />
<path
d="M5.56892 6.49721C6.26282 6.49721 6.82534 5.9347 6.82534 5.24079C6.82534 4.54689 6.26282 3.98438 5.56892 3.98438C4.87502 3.98438 4.3125 4.54689 4.3125 5.24079C4.3125 5.9347 4.87502 6.49721 5.56892 6.49721Z"
fill="#111111"
/>
<path
d="M10.3189 6.49721C11.0128 6.49721 11.5753 5.9347 11.5753 5.24079C11.5753 4.54689 11.0128 3.98438 10.3189 3.98438C9.62502 3.98438 9.0625 4.54689 9.0625 5.24079C9.0625 5.9347 9.62502 6.49721 10.3189 6.49721Z"
fill="#111111"
/>
<path
d="M3.55554 11.0262C6.47195 11.0262 9.38849 11.0262 12.3049 11.0262C12.7123 11.0262 12.7123 10.3945 12.3049 10.3945C9.38849 10.3945 6.47195 10.3945 3.55554 10.3945C3.14815 10.3945 3.14815 11.0262 3.55554 11.0262Z"
fill="#111111"
/>
</g>
<defs>
<clipPath id="clip0_1377_2661">
<rect width="16" height="16" fill="white" />
</clipPath>
</defs>
</svg>,

<svg
key="4"
viewBox="0 0 16 16"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<g clipPath="url(#clip0_1377_2655)">
<path d="M7.99998 16C12.4183 16 16 12.4183 16 7.99998C16 3.58171 12.4183 0 7.99998 0C3.58171 0 0 3.58171 0 7.99998C0 12.4183 3.58171 16 7.99998 16Z" />
<path
d="M5.565 6.49719C6.2589 6.49719 6.82141 5.93468 6.82141 5.24078C6.82141 4.54689 6.2589 3.98438 5.565 3.98438C4.87111 3.98438 4.30859 4.54689 4.30859 5.24078C4.30859 5.93468 4.87111 6.49719 5.565 6.49719Z"
fill="#111111"
/>
<path
d="M10.3189 6.49719C11.0128 6.49719 11.5753 5.93468 11.5753 5.24078C11.5753 4.54689 11.0128 3.98438 10.3189 3.98438C9.62501 3.98438 9.0625 4.54689 9.0625 5.24078C9.0625 5.93468 9.62501 6.49719 10.3189 6.49719Z"
fill="#111111"
/>
<path
d="M11.5869 10.6983C9.58558 12.735 6.36549 12.7189 4.38085 10.668C4.09726 10.3748 3.65109 10.8219 3.9343 11.1145C6.15466 13.4092 9.79654 13.4217 12.0335 11.1448C12.319 10.8542 11.8726 10.4074 11.5869 10.6983Z"
fill="#111111"
/>
</g>
<defs>
<clipPath id="clip0_1377_2655">
<rect width="16" height="16" fill="white" />
</clipPath>
</defs>
</svg>,

<svg
key="5"
viewBox="0 0 16 16"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<g clipPath="url(#clip0_1377_2649)">
<path d="M8.00002 16C12.4183 16 16 12.4183 16 8.00002C16 3.58173 12.4183 0 8.00002 0C3.58173 0 0 3.58173 0 8.00002C0 12.4183 3.58173 16 8.00002 16Z" />
<path
d="M6.14904 3.71289C5.6719 3.71289 5.22867 3.94557 4.96223 4.33516L4.90727 4.40501L4.8705 4.35815C4.60711 3.95431 4.16309 3.71303 3.68106 3.71303C2.85857 3.71303 2.26172 4.31004 2.26172 5.13227C2.26172 6.34635 4.45974 8.13585 4.62004 8.26468C4.69569 8.33706 4.79475 8.37686 4.89984 8.37686C5.00494 8.37686 5.10399 8.33719 5.17965 8.26457C5.34045 8.1347 7.56828 6.31719 7.56828 5.13227C7.56828 4.30991 6.9714 3.71289 6.14904 3.71289Z"
fill="#111111"
/>
<path
d="M12.3795 3.71289C11.9024 3.71289 11.4591 3.94557 11.1927 4.33516L11.1377 4.40501L11.101 4.35815C10.8376 3.95431 10.3936 3.71303 9.91153 3.71303C9.08903 3.71303 8.49219 4.31004 8.49219 5.13227C8.49219 6.34635 10.6902 8.13585 10.8505 8.26468C10.9262 8.33706 11.0252 8.37686 11.1303 8.37686C11.2353 8.37686 11.3343 8.33719 11.4101 8.26457C11.5708 8.13483 13.7986 6.31719 13.7986 5.13227C13.7987 4.30991 13.2019 3.71289 12.3795 3.71289Z"
fill="#111111"
/>
<path
d="M11.5869 10.6963C9.58559 12.7329 6.36551 12.7169 4.38085 10.666C4.09726 10.3729 3.65109 10.8199 3.9343 11.1125C6.15468 13.4072 9.79656 13.4194 12.0335 11.1428C12.3191 10.8523 11.8727 10.4055 11.5869 10.6963Z"
fill="#111111"
/>
</g>
<defs>
<clipPath id="clip0_1377_2649">
<rect width="16" height="16" fill="white" />
</clipPath>
</defs>
</svg>,
];

export default function App() {
return (
<Rate
character={emoji}
defaultValue={1.5}
size="xl"
characterClassName="[&>svg]:mr-2"
/>
);
}

Disabled

The disabled state of the Rate component.

import { Rate } from "@components/rate";

export default function App() {
return <Rate disabled />;
}

With Helper Text

You can add helper text message to the Rate component using helperText property.

import { Rate } from "@components/rate";

export default function App() {
return <Rate defaultValue={2} helperText="This is helperText." />;
}

With Error Message

You can show the validation error message using error property.

import { Rate } from "@components/rate";

export default function App() {
return <Rate error="This field is required.." />;
}

API Reference


Rate Props

Here is the API documentation of the Rate component.

PropsTypeDescriptionDefault
labelReactNodeSet field label__
sizeRateSizesThe size of the component"DEFAULT"
characterReactNode ReactNode[]Pass single custom character or an array of custom characters<StarIcon />
characterClassNamestringCustom className for custom character__
tooltipsstring[]Provide tooltip texts for each character__
helperTextReactNodeAdd helper text. It could be string or a React component__
errorstringShow error message using this prop__
labelClassNamestringUse labelClassName prop to do some addition style for the field label__
rateClassNamestringUse rateClassName prop to do some addition style for the rate field__
errorClassNamestringThis prop allows you to customize the error message style__
helperClassNamestringThis prop allows you to customize the helper message style__
classNamestringAdd custom classes into the component wrapper for extra style like spacing__

Rate Sizes

type RateSizes = "sm" | "md" | "lg" | "xl";

Rate Character Render

type RateCharacterRender = (
origin: ReactElement<any, string | JSXElementConstructor<any>>,
props: StarProps
) => ReactNode;