fix(frontend): star rating hover via StarInput, retire overlay slider

The vendored overlay-slider Stars.svelte never responded under
Svelte 5 - a runes port plus an explicit value/oninput rewrite both
left it inert, which convicted the mechanism rather than its
syntax. Replace it with StarInput.svelte: per-star hover zones with
fractional math (preserves the full 0-10 granularity),
snapshot-and-revert on mouseleave, commit on click, arrow-key
nudging, disabled mode. It reuses the Star SVG leaf so output is
pixel-identical, stays dumb (value in/out, no stores) for the
planned inline-grid editing, and Rating.svelte keeps owning the
words/score math locally. Legacy on:change forwarding and the
slider CSS go with the old file.
This commit is contained in:
John O'Keefe
2026-09-16 14:00:44 -04:00
parent 8d5d8ac2d7
commit f63563ce16
3 changed files with 140 additions and 94 deletions
+6 -31
View File
@@ -1,30 +1,9 @@
<script lang="ts">
import StarRatting from "../star-rating/Stars.svelte";
import StarInput from "../star-rating/StarInput.svelte";
export let score
let { score = $bindable(0) }: { score: number } = $props();
let config = {
readOnly: false,
countStars: 5,
range: {
min: 0,
max: 5,
step: 0.5
},
score: score / 2,
showScore: false,
name: "rating",
scoreFormat: function(){ return `(${this.score.toFixed(0)}/${this.countStars})` },
starConfig: {
size: 32,
fillColor: '#F9ED4F',
strokeColor: "#e2c714",
unfilledColor: '#FFF',
strokeUnfilledColor: '#000'
}
}
const ratingInWords = {
const ratingInWords: Record<number, string> = {
0: "Not Reviewed",
1: "Appalling",
2: "Horrible",
@@ -37,14 +16,10 @@
9: "Great",
10: "Masterpiece",
}
const changeRating = (e: any) => {
score = e.target.valueAsNumber * 2
}
</script>
<div>
<StarRatting bind:config on:change={changeRating}/>
<p>Rating: {config.score * 2}</p>
<p>{ratingInWords[config.score * 2]}</p>
<StarInput bind:value={score} min={0} max={10} step={1} />
<p>Rating: {score}</p>
<p>{ratingInWords[score]}</p>
</div>