summaryrefslogtreecommitdiffstats
path: root/toolkit/content/widgets/moz-five-star/moz-five-star.mjs
blob: e95c74e0ed7c4335bc0fbdc0ce1ee29114ab04da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { ifDefined, html } from "../vendor/lit.all.mjs";
import { MozLitElement } from "../lit-utils.mjs";

window.MozXULElement?.insertFTLIfNeeded("toolkit/global/mozFiveStar.ftl");

/**
 * The visual representation is five stars, each of them either empty,
 * half-filled or full. The fill state is derived from the rating,
 * rounded to the nearest half.
 *
 * @tagname moz-five-star
 * @property {number} rating - The rating out of 5.
 * @property {string} title - The title text.
 */
export default class MozFiveStar extends MozLitElement {
  static properties = {
    rating: { type: Number, reflect: true },
    title: { type: String },
  };

  static get queries() {
    return {
      starEls: { all: ".rating-star" },
      starsWrapperEl: ".stars",
    };
  }

  getStarsFill() {
    let starFill = [];
    let roundedRating = Math.round(this.rating * 2) / 2;
    for (let i = 1; i <= 5; i++) {
      if (i <= roundedRating) {
        starFill.push("full");
      } else if (i - roundedRating === 0.5) {
        starFill.push("half");
      } else {
        starFill.push("empty");
      }
    }
    return starFill;
  }

  render() {
    let starFill = this.getStarsFill();
    return html`
      <link
        rel="stylesheet"
        href="chrome://global/content/elements/moz-five-star.css"
      />
      <div
        class="stars"
        role="img"
        data-l10n-id=${ifDefined(
          this.title ? undefined : "moz-five-star-rating"
        )}
        data-l10n-args=${ifDefined(
          this.title ? undefined : JSON.stringify({ rating: this.rating ?? 0 })
        )}
      >
        ${starFill.map(
          fill => html`<span class="rating-star" fill="${fill}"></span>`
        )}
      </div>
    `;
  }
}
customElements.define("moz-five-star", MozFiveStar);