Forms inputrating
Star Rating
Classic star-based feedback input.
Preview
Usage
Copy the full block below to use this component with its imports.
astro
---
import { StarRating } from 'astro-component-kit';
---
<RatingStars name="quality" initialValue={4} /> ---
import { StarRating } from 'astro-component-kit';
---
<RatingStars name="quality" initialValue={4} /> Manual Installation
If you are not using the npm package, create a new file src/components/lib/StarRating.astro and paste the following code:
astro
---
/**
* RatingStars — A classic star-rating input for user reviews and feedback.
*
* @param {string} name - HTML name for form submission. Default is "rating".
* @param {number} maxRating - Maximum number of stars. Default is 5.
* @param {string} idPrefix - Prefix used to generate unique IDs for radio buttons.
* @param {number} initialValue - Currently selected rating.
*/
interface Props {
name?: string;
maxRating?: number;
idPrefix?: string;
initialValue?: number;
}
const { name = "rating", maxRating = 5, idPrefix = "star", initialValue = 0 } = Astro.props;
---
<div class="rating-stars" data-rating-group>
{Array.from({ length: maxRating }).map((_, i) => {
const val = maxRating - i;
return (
<>
<input
type="radio"
name={name}
id={`${idPrefix}-${val}`}
value={val}
checked={initialValue === val}
class="rating-stars__input"
/>
<label for={`${idPrefix}-${val}`} class="rating-stars__star" aria-label={`${val} stars`}>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
</svg>
</label>
</>
);
})}
</div>
<style>
.rating-stars { display: flex; flex-direction: row-reverse; gap: 4px; width: fit-content; }
.rating-stars__input { display: none; }
.rating-stars__star {
width: 32px; height: 32px;
cursor: pointer; transition: all 0.2s ease;
color: var(--c-border, #334155);
}
.rating-stars__star svg { width: 100%; height: 100%; fill: transparent; transition: all 0.2s; }
/* Hover and check logic using sibling selectors (requires row-reverse) */
.rating-stars__star:hover,
.rating-stars__star:hover ~ .rating-stars__star,
.rating-stars__input:checked ~ .rating-stars__star {
color: #fbbf24;
}
.rating-stars__star:hover svg,
.rating-stars__star:hover ~ .rating-stars__star svg,
.rating-stars__input:checked ~ .rating-stars__star svg {
fill: #fbbf24;
filter: drop-shadow(0 0 5px rgba(251, 191, 36, 0.4));
}
.rating-stars__star:active { transform: scale(0.9); }
</style> ---
/**
* RatingStars — A classic star-rating input for user reviews and feedback.
*
* @param {string} name - HTML name for form submission. Default is "rating".
* @param {number} maxRating - Maximum number of stars. Default is 5.
* @param {string} idPrefix - Prefix used to generate unique IDs for radio buttons.
* @param {number} initialValue - Currently selected rating.
*/
interface Props {
name?: string;
maxRating?: number;
idPrefix?: string;
initialValue?: number;
}
const { name = "rating", maxRating = 5, idPrefix = "star", initialValue = 0 } = Astro.props;
---
<div class="rating-stars" data-rating-group>
{Array.from({ length: maxRating }).map((_, i) => {
const val = maxRating - i;
return (
<>
<input
type="radio"
name={name}
id={`${idPrefix}-${val}`}
value={val}
checked={initialValue === val}
class="rating-stars__input"
/>
<label for={`${idPrefix}-${val}`} class="rating-stars__star" aria-label={`${val} stars`}>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
</svg>
</label>
</>
);
})}
</div>
<style>
.rating-stars { display: flex; flex-direction: row-reverse; gap: 4px; width: fit-content; }
.rating-stars__input { display: none; }
.rating-stars__star {
width: 32px; height: 32px;
cursor: pointer; transition: all 0.2s ease;
color: var(--c-border, #334155);
}
.rating-stars__star svg { width: 100%; height: 100%; fill: transparent; transition: all 0.2s; }
/* Hover and check logic using sibling selectors (requires row-reverse) */
.rating-stars__star:hover,
.rating-stars__star:hover ~ .rating-stars__star,
.rating-stars__input:checked ~ .rating-stars__star {
color: #fbbf24;
}
.rating-stars__star:hover svg,
.rating-stars__star:hover ~ .rating-stars__star svg,
.rating-stars__input:checked ~ .rating-stars__star svg {
fill: #fbbf24;
filter: drop-shadow(0 0 5px rgba(251, 191, 36, 0.4));
}
.rating-stars__star:active { transform: scale(0.9); }
</style>
Quick Info
- Category
- Forms
- Filename
StarRating.astro- Dependencies
- None — pure Astro + CSS
- Tags
- inputrating