Rating
A headless rating component for building star/icon rating inputs with hover preview, keyboard navigation, and half-step support. Uses createRating internally for value management.
Usage
Rating supports whole and half-star modes. Items expose their state via data attributes for CSS-only styling.
Rating: 0
<script setup lang="ts">
import { Rating } from '@vuetify/v0'
import { shallowRef } from 'vue'
const rating = shallowRef(0)
</script>
<template>
<div class="flex flex-col items-center gap-4">
<Rating.Root v-slot="{ attrs }" v-model="rating" class="flex gap-1 focus:outline-none">
<div v-bind="attrs" class="flex gap-0.5">
<Rating.Item
v-for="i in 5"
:key="i"
as="button"
class="size-8 text-xl cursor-pointer focus:outline-none [&[data-state=full]]:text-amber-500 [&[data-state=empty]]:text-on-surface-variant/40"
:index="i"
>
<template #default="{ state }">
{{ state === 'full' ? '★' : '☆' }}
</template>
</Rating.Item>
</div>
</Rating.Root>
<p class="text-sm text-on-surface-variant">
Rating: {{ rating }}
</p>
</div>
</template>
Anatomy
<script setup lang="ts">
import { Rating } from '@vuetify/v0'
</script>
<template>
<Rating.Root>
<Rating.Item />
<Rating.HiddenInput />
</Rating.Root>
</template>Examples
Basic
Click a star to set the rating. Hover to preview. Keyboard: Arrow keys to adjust, Home for 0, End for max.
Rating: 0
Half Stars
Enable half prop for 0.5-step precision. Hover over the left or right half of a star to preview half values.
Rating: 2.5
Accessibility
Keyboard
| Key | Action |
|---|---|
| ArrowRight / ArrowUp | Increment by step (1 or 0.5) |
| ArrowLeft / ArrowDown | Decrement by step |
| Home | Set to 0 |
| End | Set to size |
ARIA
Rating.Root provides role="slider" with aria-valuenow, aria-valuemin, aria-valuemax, and aria-valuetext (e.g. “3 out of 5”). When disabled or readonly, the corresponding aria-disabled and aria-readonly attributes are set.
Data Attributes
Root:
| Attribute | Description |
|---|---|
data-disabled | Present when disabled |
data-readonly | Present when readonly |
data-hovering | Present during hover |
Item:
| Attribute | Values | Description |
|---|---|---|
data-state | full | half | empty | Fill state |
data-highlighted | present/absent | Within hover range |
data-disabled | present/absent | Inherited from root |
data-readonly | present/absent | Inherited from root |
Slot into Rating.Item and use the state slot prop to choose your icon:
<Rating.Item :index="i" v-slot="{ state }">
<StarFull v-if="state === 'full'" />
<StarHalf v-if="state === 'half'" />
<StarEmpty v-if="state === 'empty'" />
</Rating.Item>Use the readonly prop. The value displays but cannot be changed:
<Rating.Root :model-value="3.5" readonly half>
<Rating.Item v-for="i in 5" :key="i" :index="i" />
</Rating.Root>Set the name prop on Root. A hidden input is auto-rendered with the current value:
<Rating.Root v-model="rating" name="review-rating">
<Rating.Item v-for="i in 5" :key="i" :index="i" />
</Rating.Root>Rating.Root
Props
Slots
default
RatingRootSlotPropsRating.HiddenInput
Props
namespace
string | undefinedNamespace for context injection from parent Rating.Root
Default: "v0:rating:root"
Rating.Item
Props
namespace
string | undefinedNamespace for context injection from parent Rating.Root
Default: "v0:rating:root"
Slots
default
RatingItemSlotProps