Giter VIP home page Giter VIP logo

vue-stars-rating's Introduction

vue-dynamic-star-rating

A Highly Customizable, easy-to-use elegant stars rating component (similar to Google Play)

MIT License view on npm

For a walkthrough blogpost about how I implemented this component you can head to my medium post

Demo

4.8 star rating

Edit Vue Template

Usage

Install via NPM npm i vue-dynamic-star-rating

Then require in your project:

var StarRating = require('vue-dynamic-star-rating');

or ES6 syntax:

import StarRating from 'vue-dynamic-star-rating'

Then you can register the component globally:

Vue.component('star-rating', StarRating);

Or in your Vue component:

components: {
  StarRating
}

You can then use the following selector anywhere in your project:

  • To get up and running quick the package now supports rendering just the selector with default values
<star-rating></star-rating>

Docs

The component <star-rating></star-rating> support various property. You can use either :

  • rating to define the default rating value
  • star-style to define the style that applies to the rating. If not provided, the default values are used.
  • is-indicator-active to determine if an indicator should be enabled.

Basics

Property Type Description Default
rating Number A number between 0.0-5.0 that will determine the fullness of the 5-stars rating polygons 1
isIndicatorActive Boolean A property that deteremines weather a rating indicator would show to the right true
starStyle Object See the following "Customized Styling" section below { "fullStarColor" : "#ed8a19", "emptyStarColor" : "#737373", "starWidth" : 20, "starHeight" : 20 }

Customized Styling

Property Type Description Default
fullStarColor string Set the full or partially-full star color #ed8a19
emptyStarColor string Set the empty or partially-empty star color #737373
starWidth number Set the star width 20
starHeight number Set the star height 20

Implementation Example

Define your config options object in the component importing StarRating e.g

data: function() {
    return {
        rating: 4.7,
        starStyle: {
            fullStarColor: '#ed8a19',
            emptyStarColor: '#737373',
            starWidth: 30,
            starHeight: 30
        }
    }
}

And bind it to the selector like so

<star-rating :rating="rating" :star-style="starStyle"></star-rating>

Feedback would be much appreciated, questions, suggestions, issues are more than welcome.


👨‍💻 Follow me on Twitter.

vue-stars-rating's People

Contributors

blair2004 avatar diegologs avatar jonathandn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

vue-stars-rating's Issues

Bind config Object directoly to v-bind - better performance & default values

When binding it directly to v-bind, performance would be better,
And I would be able to declarre default values in the props rather than have to set them during mount/created.

To sum up this refactor will grant:

  1. Better Performance - a more flatten mapping of the binded props compared to a Watch Deep mapping that is more resource consumable for vue virtual DOM
  2. Easyness of Usage - Access to default values, types and more on each binded prop without need to declare and use setters
  3. Readability & Cleanness of code - Less code in the template & more readible.

Example:
Instead of this:
<selector v-bind:configData=configData">

Write this

And declare each prop object in the props of the selector component

Duplicate svg defs ids may cause issues

This issue is a bit harder to reproduce.

The generated stars svgs have a linearGradient with an id:

<linearGradient :id="`gradient${star.raw}`">

This id is supposed to be unique, but with 5 stars in a star rating, you will get at least 3 duplications of ids. But the browser can handle it.

Now if this component is used two times on the same page, the second component could use an id that was already defined in the <defs> of the first component. But the browser can still handle it.

Now ! Still with this component used twice, if the first one is rendered in the html, but isn't displayed (put a display: none; on it), this will break the second one. The gradient url reference is resolved to the defs of the first one and breaks: the stars aren't filled at all.

Sadly, with svgs there are no alternatives to id/url(#id)... The best solution I found is to prefix the gradient id with the _uid property of the vue component (which is different for each rating instance).

Include Interactive UI (Slider/Input box) for changing rating in Code Sandbox Demo

Motivation: Code Sandbox demo for testing stars could be made more fun by having a 0-5 slider below the stars or an input field to dynamically change the rating and test the rating stars. This could very well highlight the dynamic nature of the plugin which this plugin excels at.

Work: Addition of input slider/ input box to take interactive input from user and binding the value to star ratings

This could make the demo more polished thereby making the plugin more appealing for adoption by developers

Enable Interactive Stars - Ability to change Rate

  1. On Hover - see coverage of ratings(from fill color to empty left to right)

  2. On Click - set the new rating between 0.0-5.0 with a click

  3. Click Emits Event - emit an event/hook for parent component to become "aware" of change in rating

  4. isInteractive - boolean property - that allows to change from a "static" rating to "interactive" rating - can be changed

Updating `rating` prop doesn't update stars

initStars and setStars are only called in the created function. Updating the rating prop of the component will not trigger an update of the data stars array.

There are many use cases where this component could have a rating with updates (for example: if the rating of a selected item of a list is displayed, and the user selects another item).

An easy but dirty solution would be to watch the rating prop and to call setStars.

In my opinion, it would be a lot cleaner to use directly a computed stars attribute (which would depend on the rating prop). This way, no need for initStars, setStars and even created: the computed property will update automatically when rating is updated.

Here is my version of the computed attribute:

computed: {
    stars: function() {
      const stars = []
      for (let i = 0; i < this.totalStars; i++) {
        const raw = Math.max(Math.min(this.rating - i, 1), 0)
        stars.push({
          raw: raw,
          percent: raw * 100 + "%"
        });
      }
      return stars
    }
  }

The Math.max(Math.min(this.rating - i, 1), 0) is a bit hacky (and may induce float issues like 0.8999999999999999 instead of 0.9) but won't noticable on the stars display. Not sure what's the best solution to avoid float issues.

Use svg viewBox ?

Hello,

First of all thank you for this component and for the nice medium post :) Very interesting to read.

However I didn't understand why you wrote a star drawing algorithm instead of using the "static" svg resized. From your blog post:

Once done with building the logic I realized it was not possible to alter the star’s width/height dynamically due to it’s hard-coded values — I had to draw the star programmatically in order to achieve a more dynamic star with width & height that are easily adjustable.

Indeed it is, I mean the S of SVG stands for scalable 😅

I managed to do pretty much what your component does using the viewBox svg property:
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox

You could just put viewBox="0 0 200 200" on your svg tag, and use the initial polygon <polygon points="100,10 40,198 190,78 10,78 160,198">, and voilà. The polygon is drawn in the viewBox, and is then scaled to fit the svg width/height.

Thanks again,

Add support for CSS variables

It is not currently possible to pass a CSS variable for fullStarColor or emptyStarColor.

Is it possible to add support for that please ?

Show Tooltip for rating on hover over ratings

Motivation: Since there is also functionality to have stars as dynamic as 3.7 and 3.8, it is hard to distinguish just by looking and hence need a tooltip on hover over stars which tells the rating in text.

User Interaction: User gets an idea of rating by looking, and if interested can view the exact rating by hovering over it.

Work: Hover event either CSS or JS and display tooltip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.