Vuetify Rating Component Half Stars with all mdi icons

1.9k Views Asked by At

I'm setting up a rating component and would like to be able to pass a mdi icon, example "star", and that icon will populate the empty/half/full icons props.

Case 1:

With the star mdi icons this works nicely, as seen in heart screenshot and codepan .

Half star shows up correctly, and the half empty part has a outline around the empty part.

new Vue({
      el: '#app',
      vuetify: new Vuetify(),
      data: () => ({
        rating: 3.5,
        emptyIcon: 'mdi-star-outline',
        fullIcon: 'mdi-star',
        halfIcon: 'mdi-star-half'
      }),
    })

enter image description here Caes 2:

With heart icon, It shows half a heart, but no outline around the empty half as seen in screenshot Codepen

new Vue({
      el: '#app',
      vuetify: new Vuetify(),
      data: () => ({
        rating: 3.5,
        emptyIcon: 'mdi-heart-outline',
        fullIcon: 'mdi-heart',
        halfIcon: 'mdi-heart-half'
     }),
    })

enter image description here Cae 3:

If I use any other mdi icon, seems like there is no half version so no star seen at all if half rated. Codepen

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data: () => ({
    rating: 3.5,
    emptyIcon: 'mdi-check-outline',
      fullIcon: 'mdi-check',
      halfIcon: 'mdi-check-half'
  }),
})

Codepen

How can I code that component will receive any mdi-icon, and will render rating view like case 1. With half star of the right empty part outlined, and support icons that do not have "half" version?

1

There are 1 best solutions below

0
On

The problem becomes immediately apparent if you look at the icons:

star and heart icons

In the second row both icon names end in -half, but star-half and heart-half are very different. The star has its left half filled, and the other outlined, whereas the heart is really just the solid left half.

The heart icon you need to use here is heart-half-full.

If no such half-full variant of an icon is provided, then you can't render it in the desired way (like your checkmark example), unless you change how the component draws the "half" icon. A quite generic solution would be to render the left half of the solid variant, and the right half of the outlined variant. I can think of different methods:

  • using two elements with some positioning and restricted width,
  • or maybe better by using the icon as background image
  • CSS clip-path is also possible but varying support in browsers for SVG

In case of the checkmark it would look a bit strange however (for both check and check-bold). Simulation:

checkmark example enter image description here