DEV Community

Cover image for vue-star-rate: Zero-Dependency Vue 3.5+ Star Rating Component
Pooya Golchian
Pooya Golchian

Posted on • Originally published at pooya.blog

vue-star-rate: Zero-Dependency Vue 3.5+ Star Rating Component

Star ratings sound simple until you ship them to production. Then you need half-star precision, accessible keyboard navigation, RTL layouts, flexible icon sources, and correct ARIA semantics. I built vue-star-rate to handle all of that in a single zero-dependency Vue 3.5+ component.

Documentation & Live Demo

Installation

pnpm add vue-js-star-rating
Enter fullscreen mode Exit fullscreen mode

Requires Vue 3.5+. Uses defineModel and useTemplateRef, both stable in Vue 3.5. Zero runtime dependencies.

Basic Usage

<script setup lang="ts">

import 'vue-js-star-rating/dist/style.css';

const rating = ref(0);
</script>

<template>

</template>
Enter fullscreen mode Exit fullscreen mode

Half-Star Ratings


Enter fullscreen mode Exit fullscreen mode

The visual renderer fills exactly half of a star glyph. The emitted value is a decimal like 3.5.

Size Presets

  <!-- 16px -->
  <!-- 20px -->
  <!-- 24px, default -->
  <!-- 32px -->
  <!-- 40px -->
  <!-- Custom pixels -->
Enter fullscreen mode Exit fullscreen mode

Custom Colors


Enter fullscreen mode Exit fullscreen mode

Icon Providers

<!-- Lucide (requires lucide-vue-next) -->

<!-- FontAwesome (requires @fortawesome/fontawesome-free) -->

<!-- Fully custom SVG via slot -->

Enter fullscreen mode Exit fullscreen mode

Read-Only Mode

For review cards, dashboards, and product pages:


Enter fullscreen mode Exit fullscreen mode

Keyboard Navigation

Key Action
Arrow Right / Up Increase rating
Arrow Left / Down Decrease rating
Home Set to minimum
End Set to maximum
1โ€“9 Jump to specific value
0 Reset to minimum

The component uses role="group", aria-pressed on each star, and an aria-live counter, fully WCAG 2.2 compliant.

Tooltips and Counters


Enter fullscreen mode Exit fullscreen mode

Full Configuration Example

<VueStarRate
  v-model="rating"
  :max-stars="5"
  :allow-half="true"
  :show-counter="true"
  :show-tooltip="true"
  size="lg"
  :colors="{ empty: '#27272a', filled: '#fbbf24', hover: '#fcd34d', half: '#fbbf24' }"
  :animation="{ enabled: true, duration: 200, type: 'scale' }"
  :clearable="true"
  @change="(val, old) => console.log(val, old)"
/>
Enter fullscreen mode Exit fullscreen mode

Props Reference

Prop Type Default Description
v-model number 0 Rating value
maxStars number 5 Maximum stars
allowHalf boolean false Half-star precision
size xs / sm / md / lg / xl md Size preset
readonly boolean false Display-only mode
clearable boolean false Clear button
showCounter boolean false Numeric counter
showTooltip boolean false Hover tooltips
rtl boolean false Right-to-left layout
iconProvider custom / lucide / fontawesome custom Icon source

Programmatic Control

const ratingRef = ref<InstanceType<typeof VueStarRate>>();

ratingRef.value?.reset();
ratingRef.value?.setRating(3.5);
ratingRef.value?.getRating();
ratingRef.value?.focus();
Enter fullscreen mode Exit fullscreen mode

Migration from v2

v2 v3
lucideIcons prop icon-provider="lucide"
role="slider" role="group" (WCAG 2.2)
animation: { scale: 1.15 } animation: { type: 'scale' }
Vue ^3.3.0 peer dep Vue ^3.5.0 peer dep

GitHub ยท npm ยท Full Documentation

Top comments (0)