Rate
freeRate captures a star or symbol score for reviews, feedback, and quality ratings.
Preview
Dark
How was your experience?
Your rating helps us improve future orders.
3 out of 5
import { useState } from 'react';
import Rate from '@/components/ui/Rate';
export default function UsageDemo() {
const [score, setScore] = useState(3);
return (
<div className="flex flex-col gap-4">
<div>
<div className="text-base font-semibold text-foreground">
How was your experience?
</div>
<p className="text-muted-foreground">
Your rating helps us improve future orders.
</p>
</div>
<Rate
value={score}
onChange={setScore}
label={score > 0 ? `${score} out of 5` : 'Tap a star to rate'}
/>
</div>
);
}Installation
Add this component with the NateUI CLI.
npx nateui@latest add RateExamples
Basic
Preview
Dark
import Rate from '@/components/ui/Rate';
export default function BasicDemo() {
return <Rate defaultValue={3} />;
}Half Ratings
Preview
Dark
3.5 stars
import { useState } from 'react';
import Rate from '@/components/ui/Rate';
export default function HalfRatingsDemo() {
const [value, setValue] = useState(3.5);
return (
<Rate
allowHalf
value={value}
onChange={setValue}
label={`${value.toFixed(1)} stars`}
/>
);
}Count
Preview
Dark
import Rate from '@/components/ui/Rate';
export default function CountDemo() {
return <Rate count={10} defaultValue={7} />;
}Custom Character
Preview
Dark
import Rate from '@/components/ui/Rate';
import { PiHeart } from 'react-icons/pi'
const sentiments = ['Poor', 'Fair', 'Good', 'Very Good', 'Excellent'];
export default function CustomCharacterDemo() {
return (
<Rate
defaultValue={4}
tooltips={sentiments}
character={<PiHeart fill="currentColor" />}
/>
);
}States
Preview
Dark
Read only
4.0 average
Disabled
import Rate from '@/components/ui/Rate';
export default function StatesDemo() {
return (
<div className="flex flex-col gap-8">
<div className="flex flex-col gap-2">
<span className="text-xs uppercase tracking-wide text-muted-foreground">
Read only
</span>
<Rate value={4} readOnly label="4.0 average" />
</div>
<div className="flex flex-col gap-2">
<span className="text-xs uppercase tracking-wide text-muted-foreground">
Disabled
</span>
<Rate value={3} disabled />
</div>
</div>
);
}Controlled
Preview
Dark
Current rating: 2
import { useState } from 'react';
import Rate from '@/components/ui/Rate';
import Button from '@/components/ui/Button';
export default function ControlledDemo() {
const [value, setValue] = useState(2);
return (
<div className="flex flex-col gap-4">
<Rate value={value} onChange={setValue} />
<div className="flex items-center gap-4">
<span className="text-xs text-muted-foreground">
Current rating: <span className="font-medium">{value}</span>
</span>
<Button size="sm" onClick={() => setValue(0)}>
Reset
</Button>
</div>
</div>
);
}API
Rate renders a single div with role="slider" and full keyboard support: arrow keys adjust the value by one step, and Home / End jump to the minimum and maximum.
| Prop | Description | Type | Default |
|---|---|---|---|
value | Current rating for controlled usage. | number | - |
defaultValue | Initial rating for uncontrolled usage. | number | 0 |
count | Number of rating items rendered. | number | 5 |
allowHalf | Enables half-step precision by splitting each item into two halves. | boolean | false |
allowClear | Clicking the current value again resets the rating to 0. | boolean | true |
disabled | Dims the control and blocks all interaction. | boolean | false |
readOnly | Displays the value at full opacity but blocks interaction. | boolean | false |
name | Renders a hidden input so the value submits with a native form. | string | - |
character | Custom rating symbol, either a node or a render function per item. | RateCharacter | StarIcon |
tooltips | Native title text per item, indexed from the first item. | string[] | - |
label | Trailing content rendered after the last item, such as a live readout. | ReactNode | - |
classNames | Class name overrides for the item, icon, and label slots. | RateClassNames | - |
onChange | Called with the next value when the rating is committed. | (value: number) => void | - |
onHoverChange | Called with the previewed value as the pointer moves across items. | (value: number) => void | - |
className | Class names applied to the root element. | string | - |
ref | Ref forwarded to the root div. | Ref<HTMLDivElement> | - |
...nativeDivProps | Native props for the root div. | NativeRateDivProps | - |
Types
type RateCharacter =
| ReactNode
| ((props: {
index: number;
value: number;
active: boolean;
}) => ReactNode);
type RateClassNames = {
item?: string;
icon?: string;
label?: string;
};
type NativeRateDivProps = Omit<
ComponentPropsWithRef<'div'>,
'children' | 'onChange'
>;