Skip to content

Instantly share code, notes, and snippets.

@Akii
Created February 17, 2020 19:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Akii/1677d62494dd835b6e22ba2bdc98f94f to your computer and use it in GitHub Desktop.
Save Akii/1677d62494dd835b6e22ba2bdc98f94f to your computer and use it in GitHub Desktop.
Probably accessible star rating component for Vue.
<template>
<div>
<span class="visually-hidden" :aria-hidden="!readonly">{{ starLabel(value) }}</span>
<span v-for="i in [1, 2, 3, 4, 5]" :key="i" :aria-hidden="readonly">
<label class="visually-hidden">
{{ starLabel(i) }}
<input
type="radio"
:value="i"
v-model="internalValue"
v-on:input.prevent="rate($event.target.value)"
class="visually-hidden"
/>
</label>
<v-icon color="primary" @click="rate(i)" aria-hidden="true">{{ starAt(i) }}</v-icon>
</span>
</div>
</template>
<script>
export default {
name: 'StarRating',
props: {
readonly: { type: Boolean, default: false },
value: { type: Number }
},
data: () => ({
internalValue: 0
}),
created () {
this.internalValue = this.value
},
watch: {
value (newVal) {
this.internalValue = newVal
}
},
methods: {
rate (pos) {
if (!this.readonly) {
this.$emit('input', pos)
}
},
starAt (pos) {
if (this.value - pos >= 0) {
return 'mdi-star'
} else {
return 'mdi-star-outline'
}
},
starLabel (pos) {
switch (pos) {
case 1:
return 'ein Stern';
default:
return `${pos} Sterne`;
}
}
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment