Rating

The LemonadeJS Star Rating plugin is a micro JavaScript component that provides a customizable five-star rating system. It enables expressive and flexible ratings for products or services, going beyond basic numeric feedback.

Documentation

Installation

npm install @lemonadejs/rating

Material icons

It requires Google Material Icons.

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

Attributes

Attribute Description
name?: String The name of the component.
number?: Number The number of stars. The default is 5.
value?: Number The initial value. The default is null.

Events

Event Description
onchange: Function Triggered when the component’s value changes.

Example JS

<html>
<script src="https://cdn.jsdelivr.net/npm/lemonadejs/dist/lemonade.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/rating/dist/index.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<div id='root'></div>

<script>
let { onchange } = lemonade;

function Component() {

    const plus = () => {
        this.number++;
    }
    const minus = () => {
        this.number--;
    }
    const reset = () => {
        this.value = 1;
    }
    const change = (newValue) => {
        console.log('New value', newValue);
    }

    this.number = 5;
    this.value = 3;

    return render => render`<>
        <Rating value="${this.value}" number="${this.number}" onchange="${change}" />
        <br>
        <input type="button" value="Value=1" onclick="${reset}" />
        <input type="button" value="Add star" onclick="${plus}" />
        <input type="button" value="Remove star" onclick="${minus}" />
    </>`;
}
// Render component
lemonade.render(Component, document.getElementById('root'));
</script>
</html>

Example JS

Example Lemonade

import lemonade from "lemonadejs";
import Rating from "@lemonadejs/rating";

export default function Component() {
    const plus = () => {
        this.number++;
    }
    const minus = () => {
        this.number--;
    }
    const reset = () => {
        this.value = 1;
    }
    const change = (newValue) => {
        console.log('New value', newValue);
    }

    this.number = 5;
    this.value = 3;

    return render => render`<>
        <Rating value="${this.value}" number="${this.number}" onchange="${change}" />
        <br>
        <input type="button" value="Value=1" onclick="${reset}" />
        <input type="button" value="Add star" onclick="${plus}" />
        <input type="button" value="Remove star" onclick="${minus}" />
    </>`;
}

Example React

// Add to your HTML: <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
import React, { useRef } from "react";
import Rating from "@lemonadejs/rating/dist/react";

export default function Component() {
    const component = useRef();

    const reset = function () {
        component.current.value = 1;
    };

    const plus = function () {
        component.current.number++;
    };

    const minus = function () {
        component.current.number--;
    };

    const handleChange = function (v) {
        console.log('New value: ', v);
    }
    
    return (<div>
        <Rating value={3} number={5} onchange={handleChange} ref={component} />
        <button onClick={reset}>Value=1</button>
        <button onClick={plus}>Add Star</button>
        <button onClick={minus}>Remove Star</button>
    </div>)
}

Example VueJs

<!-- Add to your HTML: <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> -->
<template>
    <Rating :value="3" :number="5" :onchange="handleChange" ref="component" />
    <button @click="reset">Value=1</button>
    <button @click="plus">Add Star</button>
    <button @click="minus">Remove Star</button>
</template>

<script>
import Rating from '@lemonadejs/rating/dist/vue';

export default {
name: 'App',
components: {
    Rating,
},
methods: {
    reset: function () {
        this.$refs.component.current.value = 1;
    },
    plus: function () {
        this.$refs.component.current.number++;
    },
    minus: function () {
        this.$refs.component.current.number--;
    },
    handleChange: function (v) {
        console.log('New value: ', v)
    }
}
};
</script>

Example Rating

<html>
<script src="https://cdn.jsdelivr.net/npm/lemonadejs/dist/lemonade.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/rating/dist/index.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<style>
.stars > i::after {
font-family: 'material icons',serif;
font-size: 24px;
content: 'star_outline';
cursor: pointer;
}

.stars > i[data-selected='true']::after {
content: 'star';
color: red;
}
</style>
<div id='root'></div>
<script>
function Rating() {
// Current clicked star self
let current = null;
// Five stars
this.stars = [{},{},{},{},{}];
// Click event
this.click = (e, s) => {
// If the self of the clicked item is not selected reset the null
if (! s.selected) {
current = null;
}
// Get the position of the self of the clicked item
let index = this.stars.indexOf(s);
// Go through all stars and define select or non selected
for (let i = 0; i < this.stars.length; i++) {
// Apply value to the self of the child
this.stars[i].selected = (i <= index && s !== current);
}
// Keep the self of the last item clicked
current = s;
}

return render => render`<div :loop="${this.stars}" class="stars">
<i class="material-icons" onclick="this.parent.click" data-selected="{{self.selected}}"></i>
</div>`;
}
lemonade.render(Rating, document.getElementById('root'));
</script>
</html>