Inputs
Average Summary
A read-only average with the review count and a per-star breakdown: 4.5 built from fours and fives is a different product from 4.5 built from fives and ones.
- rating
- readonly
- reviews
- summary
Preview
Use it with AI
- 1. Copy the link.
- 2. Write to your agent in your own words and drop the link into the sentence.
- 3. The agent opens the link and installs the component from the registry.
put this in the header: https://vibeui.ru/c/rating-007?lang=en
5★66%
4★21%
3★8%
2★3%
1★2%
Show the full instructions
What the link says, spelled out. Use it when your agent cannot open links — paste this text instead.
# Install and place "rating-007" (Average Summary) from VibeUI
## 1. Install first — do not skip, do not recreate
Run this exact command before writing any code:
npx shadcn@latest add https://vibeui.ru/r/rating-007.json
Registry item: https://vibeui.ru/r/rating-007.json
Installs to: components/vibeui/rating-007.tsx (the exact path follows this project's components.json aliases).
npm dependencies: none.
Registry dependencies: none.
Install it from the registry. Do not recreate it from the description,
do not substitute a similar component from another library, and do not
rewrite it to match the project's existing style.
## 2. What it is
A read-only average with the review count and a per-star breakdown: 4.5 built from fours and fives is a different product from 4.5 built from fives and ones.
An average-rating display: a large number, fractional star fill, a review counter and a breakdown per score. Server component, zero dependencies, one file.
## 3. How to use it
import { Rating007 } from "@/components/vibeui/rating-007"
<Rating007 value={4.7} count={1284} breakdown={[842, 271, 98, 41, 32]} />
Read the installed file for the full prop list.
## 4. Where to place it
This is a small inline component. Put it exactly where the user asked,
inside the existing markup. Do not create a new page, section or
wrapper for it. If a similar control already sits in that spot,
replace it instead of adding a second one.
Placement: ___
(The user fills this line in. If it is still blank, ask where to put it
instead of guessing.)
## 5. Keep exactly as installed
- the local --vibeui-rating-007-* palette — do not swap it for your theme tokens
- its own light surface: the card gets shown over any background
- the fractional fill without rounding: 4.7 rounded up to five stars is advertising, not a rating
- the per-score breakdown: the same average is built from completely different reviews
- role="img" with a full aria-label on the star row: otherwise a screen reader reads five identical glyphs
- the Russian plural agreement for "review": it is what a live product looks like
- the absence of interactive elements: this is a display, not a form, and there is nothing to click
## 6. You may change
- value — the average score itself
- count — the number of reviews
- breakdown — the per-score distribution from five down to one
- the size of the large number
- the accent through the accent prop
## 7. Rules
- Breakdown percentages are computed from the breakdown sum, not from count: those differ when some reviews carry no score.
- The value is not capped at five — pass a consistent value and star row if your scale differs.
- The decimal separator is switched to a comma for Russian typography.
- Do not lift the CSS variables into globals.css: the component has to stay a single file.
## 8. Verify
- it renders with no console errors;
- it looks like the preview on the VibeUI page you copied this from;
- if it does not, you changed something listed in section 5 — put it back.For developers
npx shadcn@latest add https://vibeui.ru/r/rating-007.jsonhttps://vibeui.ru/r/rating-007.jsonКомпонент самодостаточен: один файл, ноль зависимостей, палитра в локальных переменных --vibeui-rating-007-*. Серверный: тут нечего нажимать, поэтому нет ни кнопок, ни радиокнопок — только текст и полосы. Дробная средняя показана полосой закраски поверх серого ряда через переменную --vibeui-rating-007-fill: округлять 4.7 до пяти звёзд значит врать в пользу товара. Ряд звёзд помечен role="img" с полным aria-label, поэтому скринридер читает одну фразу вместо пяти символов. Число отзывов склоняется по правилу русских числительных.
Component source
The same file your agent installs. Here in case you would rather copy it by hand.
import type { ComponentPropsWithoutRef, CSSProperties } from "react"
export type Rating007Props = Omit<
ComponentPropsWithoutRef<"div">,
"children" | "defaultValue"
> & {
value?: number
count?: number
breakdown?: number[]
accent?: string
}
// Идея компонента: показ средней оценки, а не её ввод. Тут нечего нажимать,
// поэтому нет ни кнопок, ни радиокнопок — только текст и полосы, и компонент
// остаётся серверным. Дробная средняя показана полосой закраски поверх серого
// ряда: округлять 4.7 до пяти звёзд — врать в пользу товара. Рядом разбивка по
// оценкам: средняя 4.5 из двух пятёрок и двух четвёрок и средняя 4.5 из
// пятёрок и единиц — это разные товары, и видно это только по разбивке.
const STYLES = `
:where([data-vibeui-block="rating-007"]){
--vibeui-rating-007-surface:oklch(1 0 0);
--vibeui-rating-007-shell:oklch(0.9 0.006 265);
--vibeui-rating-007-fg:oklch(0.23 0.014 265);
--vibeui-rating-007-muted:oklch(0.55 0.014 265);
--vibeui-rating-007-empty:oklch(0.9 0.008 265);
--vibeui-rating-007-track:oklch(0.94 0.005 265);
--vibeui-rating-007-accent:oklch(0.75 0.16 78);
--vibeui-rating-007-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
--vibeui-rating-007-fill:0%;
}
/* Своя светлая подложка: карточку оценки показывают поверх любого фона. */
[data-vibeui-block="rating-007"]{
display:flex;flex-direction:column;gap:0.75rem;
width:100%;max-width:20rem;box-sizing:border-box;padding:0.875rem;
background:var(--vibeui-rating-007-surface);
border:1px solid var(--vibeui-rating-007-shell);border-radius:0.875rem;
font-family:var(--vibeui-rating-007-font);color:var(--vibeui-rating-007-fg);
}
[data-vibeui-block="rating-007"] [data-part="head"]{display:flex;align-items:center;gap:0.75rem}
[data-vibeui-block="rating-007"] [data-part="score"]{
font-size:2.25rem;font-weight:750;line-height:1;letter-spacing:-0.03em;
font-variant-numeric:tabular-nums;
}
[data-vibeui-block="rating-007"] [data-part="meta"]{display:flex;flex-direction:column;gap:0.1875rem;min-width:0}
/* Дробная средняя — полоса поверх серого ряда: округление врёт в пользу товара. */
[data-vibeui-block="rating-007"] [data-part="stars"]{
position:relative;display:inline-block;font-size:1rem;line-height:1;letter-spacing:0.0625rem;
color:var(--vibeui-rating-007-empty);
}
[data-vibeui-block="rating-007"] [data-part="fill"]{
position:absolute;inset:0 auto 0 0;overflow:hidden;white-space:nowrap;
width:var(--vibeui-rating-007-fill);color:var(--vibeui-rating-007-accent);
}
[data-vibeui-block="rating-007"] [data-part="count"]{font-size:0.75rem;color:var(--vibeui-rating-007-muted)}
/* Разбивка: одинаковая средняя складывается из очень разных отзывов. */
[data-vibeui-block="rating-007"] [data-part="rows"]{display:flex;flex-direction:column;gap:0.25rem}
[data-vibeui-block="rating-007"] [data-part="row"]{
display:grid;grid-template-columns:1.25rem 1fr 2.25rem;align-items:center;gap:0.5rem;
font-size:0.6875rem;color:var(--vibeui-rating-007-muted);font-variant-numeric:tabular-nums;
}
[data-vibeui-block="rating-007"] [data-part="bar"]{
height:0.375rem;border-radius:9999px;background:var(--vibeui-rating-007-track);overflow:hidden;
}
[data-vibeui-block="rating-007"] [data-part="bar"] span{display:block;height:100%;background:var(--vibeui-rating-007-accent)}
[data-vibeui-block="rating-007"] [data-part="share"]{text-align:right}
@media (prefers-reduced-motion:reduce){[data-vibeui-block="rating-007"] *{animation:none!important;transition:none!important}}
`
const DEFAULT_BREAKDOWN = [842, 271, 98, 41, 32]
function reviewsWord(count: number) {
const tail = count % 10
const teen = count % 100
if (teen > 10 && teen < 20) return "отзывов"
if (tail === 1) return "отзыв"
if (tail > 1 && tail < 5) return "отзыва"
return "отзывов"
}
/**
* Показ средней оценки с числом отзывов и разбивкой по звёздам, только чтение.
* Один файл, ноль зависимостей, собственная палитра.
*/
export function Rating007({
value = 4.7,
count = 1284,
breakdown = DEFAULT_BREAKDOWN,
accent,
className,
style,
...props
}: Rating007Props) {
const total = breakdown.reduce((sum, item) => sum + item, 0) || 1
const palette = {
"--vibeui-rating-007-fill": `${(value / 5) * 100}%`,
...(accent ? { "--vibeui-rating-007-accent": accent } : null),
...style,
} as CSSProperties
return (
<>
<style href="vibeui-rating-007" precedence="medium">
{STYLES}
</style>
<div
{...props}
data-vibeui-block="rating-007"
className={className}
style={palette}
>
<div data-part="head">
<span data-part="score">{value.toString().replace(".", ",")}</span>
<span data-part="meta">
<span
data-part="stars"
role="img"
aria-label={`${value} из 5 на основе ${count} отзывов`}
>
<span aria-hidden="true">★★★★★</span>
<span data-part="fill" aria-hidden="true">
★★★★★
</span>
</span>
<span data-part="count">
{count.toLocaleString("ru-RU")} {reviewsWord(count)}
</span>
</span>
</div>
<div data-part="rows">
{breakdown.map((amount, index) => {
const stars = 5 - index
const share = Math.round((amount / total) * 100)
return (
<p key={stars} data-part="row">
<span>{stars}★</span>
<span data-part="bar">
<span style={{ width: `${share}%` }} />
</span>
<span data-part="share">{share}%</span>
</p>
)
})}
</div>
</div>
</>
)
}