Rating
An interactive component for displaying star ratings and allowing users to provide ratings with customizable appearance.
Source
LLM docs
Package
Examples
7
Properties
68
Playground
Basics
Capture a single rating value with an interactive control and mirror the current score in helper text.
Loading demo…
import { useState } from 'react';
import { Block, Rating, Text } from '@plocks/ui';
export function Demo() {
const [score, setScore] = useState<number>(3);
return (
<Block>
<Rating
value={score}
onChange={setScore}
size="lg"
label="Rate the broadcast quality"
/>
<Text variant="small" c="muted">
Current score: {score} out of 5.
</Text>
</Block>
);
}Sizes
Compare the available
size tokens side by side to pick the right scale for your scene.Loading demo…
import { Block, Rating, Row, Text } from '@plocks/ui';
const SIZES = ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'] as const;
export function Demo() {
return (
<Block fullWidth direction="row" align="center" justify="space-evenly">
{SIZES.map((size) => (
<Rating
key={size}
size={size}
value={1}
readOnly
count={1}
label={size}
labelPosition="left"
/>
))}
</Block>
);
}Colors
Derive filled, hover, and empty colors from the theme palette to align ratings with product semantics.
Loading demo…
import { useState } from 'react';
import { Block, Rating, Text, useTheme } from '@plocks/ui';
const COLOR_CONFIG = [
{
key: 'primary',
label: 'Primary accent',
getColors: (palette: string[]) => ({
color: palette[5],
emptyColor: palette[1],
hoverColor: palette[6]
})
},
{
key: 'success',
label: 'Success feedback',
getColors: (palette: string[]) => ({
color: palette[5],
emptyColor: palette[1],
hoverColor: palette[6]
})
},
{
key: 'warning',
label: 'Warning feedback',
getColors: (palette: string[]) => ({
color: palette[5],
emptyColor: palette[1],
hoverColor: palette[6]
})
}
] as const;
type PaletteKey = (typeof COLOR_CONFIG)[number]['key'];
export function Demo() {
const theme = useTheme();
const [values, setValues] = useState<Record<PaletteKey, number>>({
primary: 4,
success: 3.5,
warning: 2.5
});
return (
<Block>
{COLOR_CONFIG.map(({ key, label, getColors }) => {
const palette = theme.colors[key as keyof typeof theme.colors] ?? theme.colors.gray;
const { color, emptyColor, hoverColor } = getColors(palette);
return (
<Block key={key}>
<Rating
value={values[key]}
onChange={(next) =>
setValues((prev) => ({ ...prev, [key]: next }))
}
color={color}
emptyColor={emptyColor}
hoverColor={hoverColor}
size="lg"
labelPosition="right"
label={
<Text variant="small" c="muted">
{label}
</Text>
}
/>
</Block>
);
})}
</Block>
);
}Fractions
Enable fractional ratings with configurable
precision values to capture nuanced feedback.Loading demo…
import { useState } from 'react';
import { Block, Rating, Text, useTheme } from '@plocks/ui';
const FRACTION_SETTINGS = [
{
key: 'match',
label: 'Match excitement',
precision: 0.1,
helper: 'Set scores in 0.1 increments to capture precise fan sentiment.'
},
{
key: 'broadcast',
label: 'Broadcast quality',
precision: 0.5,
helper: 'Use half-star increments when quick feedback is enough.'
}
] as const;
type FractionKey = (typeof FRACTION_SETTINGS)[number]['key'];
export function Demo() {
const theme = useTheme();
const [values, setValues] = useState<Record<FractionKey, number>>({
match: 4.2,
broadcast: 3.5
});
return (
<Block>
{FRACTION_SETTINGS.map(({ key, label, precision, helper }) => (
<Block key={key}>
<Text variant="small" c="muted">
{label}
</Text>
<Rating accessibilityLabel="Rating"
value={values[key]}
onChange={(next) => setValues((prev) => ({ ...prev, [key]: next }))}
allowFraction
precision={precision}
size="lg"
color={theme.colors.highlight[5]}
emptyColor={theme.colors.highlight[1]}
hoverColor={theme.colors.highlight[6]}
showTooltip
/>
<Text variant="small" c="muted">
{helper}
</Text>
</Block>
))}
</Block>
);
}Custom Icons
Swap the default star for any registry icon with
icon, pair it with a different emptyIcon for the unfilled state, or fall back to plain text glyphs through character and emptyCharacter.Loading demo…
import { useState } from 'react';
import { Block, Rating, Text, useTheme } from '@plocks/ui';
export function Demo() {
const theme = useTheme();
const [hearts, setHearts] = useState<number>(4);
const [bolts, setBolts] = useState<number>(3);
return (
<Block>
<Rating
value={hearts}
onChange={setHearts}
icon="heart"
size="lg"
color={theme.colors.error[5]}
emptyColor={theme.colors.error[2]}
hoverColor={theme.colors.error[6]}
label="Registry icon via `icon`"
/>
<Rating
value={bolts}
onChange={setBolts}
icon="bolt"
emptyIcon="circle"
size="lg"
label="Different empty icon via `emptyIcon`"
/>
<Rating
value={3.5}
readOnly
allowFraction
icon="moon"
size="lg"
label="Custom icons support fractions"
/>
<Rating
value={4}
readOnly
character="♥"
emptyCharacter="♡"
size="lg"
label="Text glyphs via `character`"
/>
</Block>
);
}Variants
Contrast interactive, read-only, and tooltip-enabled ratings to decide which fits your feedback flow.
Loading demo…
import { useState } from 'react';
import { Block, Rating } from '@plocks/ui';
export function Demo() {
const [interactiveValue, setInteractiveValue] = useState<number>(4);
return (
<Block>
<Rating
value={interactiveValue}
onChange={setInteractiveValue}
size="lg"
label="Interactive rating"
/>
<Rating
value={4.5}
readOnly
size="lg"
label="Read-only rating"
disclaimer="Use `readOnly` to show aggregated scores."
/>
<Rating
defaultValue={3}
showTooltip
size="lg"
label="Tooltip rating"
disclaimer="Tooltips show numeric value on hover."
/>
<Rating
defaultValue={4}
showTooltip
getTooltipLabel={(value, count) => `${value} out of ${count} stars`}
size="lg"
label="Custom tooltip text"
disclaimer="Pass `getTooltipLabel` to format the tooltip."
/>
<Rating
value={3}
disabled
size="lg"
label="Disabled rating"
disclaimer="`disabled` blocks input and dims the control."
/>
</Block>
);
}Form Field
Use
required, description, and error to drop a rating into a form like any other field, and clearable to let people undo a score by selecting it again.Loading demo…
import { useState } from 'react';
import { Block, Button, Rating, Text } from '@plocks/ui';
export function Demo() {
const [score, setScore] = useState<number>(0);
const [submitted, setSubmitted] = useState(false);
const error = submitted && score === 0 ? 'Please choose a rating' : undefined;
return (
<Block>
<Rating
value={score}
onChange={setScore}
clearable
required
size="lg"
label="Overall experience"
description="Select a star again to clear your rating."
error={error}
/>
<Button onPress={() => setSubmitted(true)}>Submit</Button>
<Text variant="small" c="muted">
{score === 0 ? 'No rating selected.' : `You rated ${score} out of 5.`}
</Text>
</Block>
);
}React Native design for iOS, Android, and Web.
Quick Links
Resources