From 8b00c4104d6c34226d6f9813446f303d5da61854 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Wed, 3 Jun 2020 16:00:18 +0300 Subject: [PATCH 01/17] feat(ui5-rating-indicator): initial implementation --- packages/main/bundle.esm.js | 1 + packages/main/src/BusyIndicator.js | 9 +- packages/main/src/RatingIndicator.hbs | 19 ++ packages/main/src/RatingIndicator.js | 219 ++++++++++++++++++ packages/main/src/themes/RatingIndicator.css | 36 +++ .../types/{BusyIndicatorSize.js => Size.js} | 20 +- packages/main/test/pages/RatingIndicator.html | 80 +++++++ .../test/samples/RatingIndicator.sample.html | 53 +++++ .../main/test/specs/RatingIndicator.spec.js | 77 ++++++ packages/playground/Gemfile.lock | 2 + .../build-scripts/samples-prepare.js | 3 +- 11 files changed, 505 insertions(+), 14 deletions(-) create mode 100644 packages/main/src/RatingIndicator.hbs create mode 100644 packages/main/src/RatingIndicator.js create mode 100644 packages/main/src/themes/RatingIndicator.css rename packages/main/src/types/{BusyIndicatorSize.js => Size.js} (52%) create mode 100644 packages/main/test/pages/RatingIndicator.html create mode 100644 packages/main/test/samples/RatingIndicator.sample.html create mode 100644 packages/main/test/specs/RatingIndicator.spec.js diff --git a/packages/main/bundle.esm.js b/packages/main/bundle.esm.js index 7b6e7ed4f0e9..54d06b8634ca 100644 --- a/packages/main/bundle.esm.js +++ b/packages/main/bundle.esm.js @@ -48,6 +48,7 @@ import Select from "./dist/Select.js"; import Switch from "./dist/Switch.js"; import MessageStrip from "./dist/MessageStrip.js"; import MultiComboBox from "./dist/MultiComboBox.js"; +import RatingIndicator from "./dist/RatingIndicator.js"; import TabContainer from "./dist/TabContainer.js"; import Tab from "./dist/Tab.js"; import TabSeparator from "./dist/TabSeparator.js"; diff --git a/packages/main/src/BusyIndicator.js b/packages/main/src/BusyIndicator.js index 7c20cb6028de..fe75dcfdbf1f 100644 --- a/packages/main/src/BusyIndicator.js +++ b/packages/main/src/BusyIndicator.js @@ -1,7 +1,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import BusyIndicatorSize from "./types/BusyIndicatorSize.js"; +import Size from "./types/Size.js"; import Label from "./Label.js"; // Template @@ -48,11 +48,14 @@ const metadata = { *

* Note: Available options are "Small", "Medium", and "Large". * - * @type {BusyIndicatorSize} + * @type {Size} * @defaultvalue "Medium" * @public */ - size: { type: BusyIndicatorSize, defaultValue: BusyIndicatorSize.Medium }, + size: { + type: Size, + defaultValue: Size.Medium, + }, /** * Defines if the busy indicator is visible on the screen. By default it is not. diff --git a/packages/main/src/RatingIndicator.hbs b/packages/main/src/RatingIndicator.hbs new file mode 100644 index 000000000000..9b1bc5fc9341 --- /dev/null +++ b/packages/main/src/RatingIndicator.hbs @@ -0,0 +1,19 @@ +
+
+ {{#each _stars}} + {{#if this.selected}} +
+ {{else}} +
+ {{/if}} + {{/each}} +
+
\ No newline at end of file diff --git a/packages/main/src/RatingIndicator.js b/packages/main/src/RatingIndicator.js new file mode 100644 index 000000000000..1e5874a9c5f0 --- /dev/null +++ b/packages/main/src/RatingIndicator.js @@ -0,0 +1,219 @@ +import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; +import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; +import { + isDown, + isUp, + isLeft, + isRight, + isSpace, + isEnter, +} from "@ui5/webcomponents-base/dist/Keys.js"; +import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; +import Size from "./types/Size.js"; +import RatingIndicatorTemplate from "./generated/templates/RatingIndicatorTemplate.lit.js"; + +// Styles +import RatingIndicatorCss from "./generated/themes/RatingIndicator.css.js"; + +/** + * @public + */ +const metadata = { + tag: "ui5-rating-indicator", + properties: /** @lends sap.ui.webcomponents.main.RatingIndicator.prototype */ { + + /** + * The indicated value of the rating + * @type {Integer} + * @defaultvalue 0 + * @public + */ + value: { + type: Integer, + defaultValue: 0, + }, + + /** + * The number of displayed rating symbols + * @type {Integer} + * @defaultvalue 5 + * @public + */ + maxValue: { + type: Integer, + defaultValue: 5, + }, + + /** + * Defines the size of the ui5-rating-indicator. + *

+ * Note: Available options are "Small", "Medium", and "Large". + * + * @type {Size} + * @defaultvalue "Medium" + * @public + */ + size: { + type: Size, + defaultValue: Size.Medium, + }, + + /** + * Defines whether the ui5-rating-indicator is disabled. + */ + /** + * @type {Boolean} + * @defaultvalue false + * @public + */ + disabled: { + type: Boolean, + }, + + /** + * @private + */ + _stars: { + type: Integer, + multiple: true, + }, + + _focused: { + type: Boolean, + }, + }, + slots: /** @lends sap.ui.webcomponents.main.RatingIndicator.prototype */ { + // + }, + events: /** @lends sap.ui.webcomponents.main.RatingIndicator.prototype */ { + + /** + * This event is triggered each time the rating value changes. + * + * @event + * @public + */ + input: {}, + + /** + * The event is fired on focuseout if the value has changed. + * + * @event + * @public + */ + change: {}, + }, +}; + +/** + * @class + * + *

Overview

+ * + * + *

Usage

+ * + * For the ui5-rating-indicator + *

ES6 Module Import

+ * + * import @ui5/webcomponents/dist/RatingIndicator.js"; + * + * @constructor + * @author SAP SE + * @alias sap.ui.webcomponents.main.RatingIndicator + * @extends UI5Element + * @tagname ui5-rating-indicator + * @public + */ +class RatingIndicator extends UI5Element { + static get metadata() { + return metadata; + } + + static get render() { + return litRender; + } + + static get styles() { + return RatingIndicatorCss; + } + + static get template() { + return RatingIndicatorTemplate; + } + + constructor() { + super(); + this._prevValue = undefined; + } + + onBeforeRendering() { + this._stars = []; + + for (let i = 1; i < this.maxValue + 1; i++) { + this._stars.push({ + selected: i <= this.value, + index: i, + }); + } + } + + _onclick(event) { + if (this.disabled) { + return; + } + + this.value = parseInt(event.target.getAttribute("data-value")); + if (this.value === 1 && this._prevValue === 1) { + this.value = 0; + } + + if (this._prevValue !== this.value) { + this.fireEvent("input"); + } + } + + _onkeydown(event) { + if (this.disabled) { + return; + } + + const down = isDown(event) || isLeft(event); + const up = isRight(event) || isUp(event) || isSpace(event) || isEnter(event); + + if (down || up) { + event.preventDefault(); + + if (down && this.value > 0) { + --this.value; + this.fireEvent("input"); + } else if (up && this.value < this.maxValue) { + ++this.value; + this.fireEvent("input"); + } + } + } + + _onfocusin(event) { + if (!this.disabled) { + this._focused = true; + this._prevValue = this.value; + } + } + + _onfocusout(event) { + if (this._focused && !this.disabled && this._prevValue !== this.value) { + this.fireEvent("change"); + } + + this._focused = false; + } + + get tabIndex() { + return this.disabled ? "-1" : "0"; + } +} + +RatingIndicator.define(); + +export default RatingIndicator; diff --git a/packages/main/src/themes/RatingIndicator.css b/packages/main/src/themes/RatingIndicator.css new file mode 100644 index 000000000000..0262c21a475d --- /dev/null +++ b/packages/main/src/themes/RatingIndicator.css @@ -0,0 +1,36 @@ +:host(:not([hidden])) { + display: inline-block; + font-size: 1.5rem; + cursor: pointer; +} + +:host([disabled]) { + opacity: .8; + cursor: initial; + outline: none; +} + +:host([size="Large"]) { + font-size: 2rem; +} + +:host([_focused]) { + outline: 1px dotted var(--sapContent_FocusColor); +} + +.ui5-rating-indicator-root { + outline: none; +} + +.icon { + user-select: none; + color: var(--sapContent_UnratedColor); +} + +.icon.ui5-rating-indicator-active-icon { + color: var(--sapContent_RatedColor); +} + +.ui5-rating-indicator-stars-wrapper { + display: flex; +} diff --git a/packages/main/src/types/BusyIndicatorSize.js b/packages/main/src/types/Size.js similarity index 52% rename from packages/main/src/types/BusyIndicatorSize.js rename to packages/main/src/types/Size.js index 713c0158c883..02c425fad2fc 100644 --- a/packages/main/src/types/BusyIndicatorSize.js +++ b/packages/main/src/types/Size.js @@ -1,26 +1,26 @@ import DataType from "@ui5/webcomponents-base/dist/types/DataType.js"; /** - * @lends sap.ui.webcomponents.main.types.BusyIndicatorSize.prototype + * @lends sap.ui.webcomponents.main.types.Size.prototype * @public */ -const BusyIndicatorSizes = { +const Sizes = { /** - * small size + * Small size * @public * @type {Small} */ Small: "Small", /** - * medium size + * Medium size * @public * @type {Medium} */ Medium: "Medium", /** - * large size + * Large size * @public * @type {Large} */ @@ -32,16 +32,16 @@ const BusyIndicatorSizes = { * Different types of BusyIndicator. * @constructor * @author SAP SE - * @alias sap.ui.webcomponents.main.types.BusyIndicatorSize + * @alias sap.ui.webcomponents.main.types.Size * @public * @enum {string} */ -class BusyIndicatorSize extends DataType { +class Size extends DataType { static isValid(value) { - return !!BusyIndicatorSizes[value]; + return !!Sizes[value]; } } -BusyIndicatorSize.generataTypeAcessors(BusyIndicatorSizes); +Size.generataTypeAcessors(Sizes); -export default BusyIndicatorSize; +export default Size; diff --git a/packages/main/test/pages/RatingIndicator.html b/packages/main/test/pages/RatingIndicator.html new file mode 100644 index 000000000000..692f6e398c12 --- /dev/null +++ b/packages/main/test/pages/RatingIndicator.html @@ -0,0 +1,80 @@ + + + + + + + + Rating Indicator + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + diff --git a/packages/main/test/samples/RatingIndicator.sample.html b/packages/main/test/samples/RatingIndicator.sample.html new file mode 100644 index 000000000000..12620c011a71 --- /dev/null +++ b/packages/main/test/samples/RatingIndicator.sample.html @@ -0,0 +1,53 @@ +
+
Rating Indicator
+
+ + +
@ui5/webcomponents
+ +
<ui5-rating-indicator>
+ +
+

Basic Rating Indicator

+
+ + +
+

+<ui5-rating-indicator></ui5-rating-indicator>
+<ui5-rating-indicator value="3"></ui5-rating-indicator>
+	
+
+ +
+

Rating Indicator With Different Max Value

+
+ + +
+

+<ui5-rating-indicator max-value="10" value="5"></ui5-rating-indicator>
+<ui5-rating-indicator max-value="3" value="3"></ui5-rating-indicator>
+	
+
+ +
+

Disabled Rating Indicator

+
+ + + +
+

+<ui5-rating-indicator value="4" disabled></ui5-rating-indicator>
+<ui5-rating-indicator max-value="10" value="5" disabled></ui5-rating-indicator>
+<ui5-rating-indicator max-value="3" value="3" disabled></ui5-rating-indicator>
+	
+
+ + + \ No newline at end of file diff --git a/packages/main/test/specs/RatingIndicator.spec.js b/packages/main/test/specs/RatingIndicator.spec.js new file mode 100644 index 000000000000..1717faf41444 --- /dev/null +++ b/packages/main/test/specs/RatingIndicator.spec.js @@ -0,0 +1,77 @@ +const assert = require("chai").assert; + + +describe("Button general interaction", () => { + browser.url("http://localhost:8080/test-resources/pages/RatingIndicator.html"); + + it("Tests basic rating indicator rendering", () => { + const ratingIndicator = browser.$("#rating-indicator1"); + + assert.strictEqual(ratingIndicator.shadow$$(".icon").length, 5, "Basic rating indicator renders 5 stars"); + }); + + it("Tests max-value property", () => { + const ratingIndicator = browser.$("#rating-indicator2"); + + assert.strictEqual(ratingIndicator.shadow$$(".icon").length, 10, "Basic rating indicator renders 5 stars"); + }); + + it("Tests clicking on star", () => { + const ratingIndicator = browser.$("#rating-indicator3"); + const thirdStar = ratingIndicator.shadow$$(".icon")[2]; + + assert.strictEqual(ratingIndicator.getProperty("value"), 6, "Initial value is applied"); + + thirdStar.click(); + + assert.strictEqual(ratingIndicator.getProperty("value"), 3, "Value is changed on click"); + }); + + it("Tests input event", () => { + const ratingIndicator = browser.$("#rating-indicator4"); + const thirdStar = ratingIndicator.shadow$$(".icon")[2]; + const input = browser.$("#input-event"); + + assert.strictEqual(ratingIndicator.getProperty("value"), 6, "Initial value is applied"); + + thirdStar.click(); + + assert.strictEqual(ratingIndicator.getProperty("value"), 3, "Value is changed on click"); + + browser.keys("Enter"); + + assert.strictEqual(ratingIndicator.getProperty("value"), 4, "Value is changed on key press"); + + browser.keys("Space"); + + assert.strictEqual(ratingIndicator.getProperty("value"), 5, "Value is changed on key press"); + + browser.keys("ArrowUp"); + browser.keys("ArrowRight"); + + assert.strictEqual(ratingIndicator.getProperty("value"), 7, "Value is changed on key press"); + + browser.keys("ArrowLeft"); + browser.keys("ArrowLeft"); + browser.keys("ArrowDown"); + browser.keys("ArrowDown"); + browser.keys("ArrowDown"); + browser.keys("ArrowDown"); + browser.keys("ArrowDown"); + + assert.strictEqual(ratingIndicator.getProperty("value"), 0, "Value is changed on key press"); + + assert.strictEqual(input.getProperty("value"), "12", "Input event is always fired") + }); + + it("Tests change event", () => { + const ratingIndicator = browser.$("#rating-indicator5"); + const thirdStar = ratingIndicator.shadow$$(".icon")[2]; + const input = browser.$("#change-event"); + + thirdStar.click(); + browser.keys("Tab"); + + assert.strictEqual(input.getProperty("value"), "1", "Change event is thrown once"); + }); +}); diff --git a/packages/playground/Gemfile.lock b/packages/playground/Gemfile.lock index 2c1a5fa5d5dd..b069c5ca3dc4 100644 --- a/packages/playground/Gemfile.lock +++ b/packages/playground/Gemfile.lock @@ -16,7 +16,9 @@ GEM em-websocket (0.5.1) eventmachine (>= 0.12.9) http_parser.rb (~> 0.6.0) + eventmachine (1.2.7) eventmachine (1.2.7-x64-mingw32) + ffi (1.11.1) ffi (1.11.1-x64-mingw32) forwardable-extended (2.6.0) http_parser.rb (0.6.0) diff --git a/packages/playground/build-scripts/samples-prepare.js b/packages/playground/build-scripts/samples-prepare.js index 213cb64a40c8..a2f1e580a216 100644 --- a/packages/playground/build-scripts/samples-prepare.js +++ b/packages/playground/build-scripts/samples-prepare.js @@ -17,7 +17,8 @@ const newComponents = [ "NotificationListItem", "NotificationListGroupItem", "UploadCollection", - "Tree" + "Tree", + "RatingIndicator", ]; packages.forEach(package => { From 3426abe028cba29a2e57dae4e5083d6f7b76c819 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Thu, 4 Jun 2020 10:56:54 +0300 Subject: [PATCH 02/17] implement acc --- packages/main/src/RatingIndicator.hbs | 8 +++++ packages/main/src/RatingIndicator.js | 33 ++++++++++++++++--- .../main/src/i18n/messagebundle.properties | 3 ++ packages/main/src/themes/RatingIndicator.css | 3 +- packages/main/test/pages/RatingIndicator.html | 2 +- 5 files changed, 43 insertions(+), 6 deletions(-) diff --git a/packages/main/src/RatingIndicator.hbs b/packages/main/src/RatingIndicator.hbs index 9b1bc5fc9341..11b1331c484f 100644 --- a/packages/main/src/RatingIndicator.hbs +++ b/packages/main/src/RatingIndicator.hbs @@ -1,4 +1,12 @@

- +


From 180611eddbfdfb352bc0a214e2478aabc5f32870 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Thu, 4 Jun 2020 11:58:24 +0300 Subject: [PATCH 03/17] spaces to tabs --- packages/main/src/RatingIndicator.hbs | 46 +++++++++---------- packages/main/src/themes/RatingIndicator.css | 24 +++++----- packages/main/test/pages/RatingIndicator.html | 2 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/packages/main/src/RatingIndicator.hbs b/packages/main/src/RatingIndicator.hbs index 11b1331c484f..ebfe70ac1f7b 100644 --- a/packages/main/src/RatingIndicator.hbs +++ b/packages/main/src/RatingIndicator.hbs @@ -1,27 +1,27 @@
-
- {{#each _stars}} - {{#if this.selected}} -
- {{else}} -
- {{/if}} - {{/each}} -
+
+ {{#each _stars}} + {{#if this.selected}} +
+ {{else}} +
+ {{/if}} + {{/each}} +
\ No newline at end of file diff --git a/packages/main/src/themes/RatingIndicator.css b/packages/main/src/themes/RatingIndicator.css index 8340d8d72da4..445df79f37a0 100644 --- a/packages/main/src/themes/RatingIndicator.css +++ b/packages/main/src/themes/RatingIndicator.css @@ -1,18 +1,18 @@ :host(:not([hidden])) { - display: inline-block; - font-size: 1.5rem; - cursor: pointer; + display: inline-block; + font-size: 1.5rem; + cursor: pointer; } :host([disabled]), :host([read-only]) { - opacity: .8; - cursor: initial; - outline: none; + opacity: .8; + cursor: initial; + outline: none; } :host([size="Large"]) { - font-size: 2rem; + font-size: 2rem; } :host([_focused]) { @@ -20,18 +20,18 @@ } .ui5-rating-indicator-root { - outline: none; + outline: none; } .icon { - user-select: none; - color: var(--sapContent_UnratedColor); + user-select: none; + color: var(--sapContent_UnratedColor); } .icon.ui5-rating-indicator-active-icon { - color: var(--sapContent_RatedColor); + color: var(--sapContent_RatedColor); } .ui5-rating-indicator-stars-wrapper { - display: flex; + display: flex; } diff --git a/packages/main/test/pages/RatingIndicator.html b/packages/main/test/pages/RatingIndicator.html index 35379242f5dc..4fada51b744d 100644 --- a/packages/main/test/pages/RatingIndicator.html +++ b/packages/main/test/pages/RatingIndicator.html @@ -2,7 +2,7 @@ - + Rating Indicator From c271d0ab90f7b4ac9783d6beaf140fdfd662a8c5 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Thu, 4 Jun 2020 12:31:32 +0300 Subject: [PATCH 04/17] fix linter --- packages/main/src/RatingIndicator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/main/src/RatingIndicator.js b/packages/main/src/RatingIndicator.js index c7c51aeaba8f..9737c89683b6 100644 --- a/packages/main/src/RatingIndicator.js +++ b/packages/main/src/RatingIndicator.js @@ -9,10 +9,10 @@ import { isEnter, } from "@ui5/webcomponents-base/dist/Keys.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; +import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; import { RATING_INDICATOR_TEXT, } from "./generated/i18n/i18n-defaults.js"; -import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; import Size from "./types/Size.js"; import RatingIndicatorTemplate from "./generated/templates/RatingIndicatorTemplate.lit.js"; From 5e3e0c46c2d6083720f674ee1298d0a020d86dac Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Fri, 5 Jun 2020 12:54:12 +0300 Subject: [PATCH 05/17] add support for float numbers --- packages/base/src/UI5Element.js | 4 +++ packages/base/src/types/Float.js | 10 ++++++ packages/main/src/RatingIndicator.hbs | 6 ++-- packages/main/src/RatingIndicator.js | 36 ++++++++++++++++--- packages/main/src/themes/RatingIndicator.css | 18 ++++++++-- packages/main/test/pages/RatingIndicator.html | 5 +++ .../main/test/specs/RatingIndicator.spec.js | 12 +++---- 7 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 packages/base/src/types/Float.js diff --git a/packages/base/src/UI5Element.js b/packages/base/src/UI5Element.js index eb9eac2a8e1a..bb2a1a2ac675 100644 --- a/packages/base/src/UI5Element.js +++ b/packages/base/src/UI5Element.js @@ -10,6 +10,7 @@ import getConstructableStyle from "./theming/getConstructableStyle.js"; import createComponentStyleTag from "./theming/createComponentStyleTag.js"; import getEffectiveStyle from "./theming/getEffectiveStyle.js"; import Integer from "./types/Integer.js"; +import Float from "./types/Float.js"; import { kebabToCamelCase, camelToKebabCase } from "./util/StringHelper.js"; import isValidPropertyName from "./util/isValidPropertyName.js"; import isSlot from "./util/isSlot.js"; @@ -303,6 +304,9 @@ class UI5Element extends HTMLElement { if (propertyTypeClass === Integer) { newValue = parseInt(newValue); } + if (propertyTypeClass === Float) { + newValue = parseFloat(newValue); + } this[nameInCamelCase] = newValue; } } diff --git a/packages/base/src/types/Float.js b/packages/base/src/types/Float.js new file mode 100644 index 000000000000..37508022a7fc --- /dev/null +++ b/packages/base/src/types/Float.js @@ -0,0 +1,10 @@ +import DataType from "./DataType.js"; + +class Float extends DataType { + static isValid(value) { + // Assuming that integers are floats as well! + return Number(value) === value; + } +} + +export default Float; diff --git a/packages/main/src/RatingIndicator.hbs b/packages/main/src/RatingIndicator.hbs index ebfe70ac1f7b..cd5dd8396204 100644 --- a/packages/main/src/RatingIndicator.hbs +++ b/packages/main/src/RatingIndicator.hbs @@ -18,9 +18,11 @@ > {{#each _stars}} {{#if this.selected}} -
+
+ {{else if this.halfStar}} +
{{else}} -
+
{{/if}} {{/each}}
diff --git a/packages/main/src/RatingIndicator.js b/packages/main/src/RatingIndicator.js index 9737c89683b6..52af3428ddab 100644 --- a/packages/main/src/RatingIndicator.js +++ b/packages/main/src/RatingIndicator.js @@ -10,6 +10,7 @@ import { } from "@ui5/webcomponents-base/dist/Keys.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; +import Float from "@ui5/webcomponents-base/dist/types/Float.js"; import { RATING_INDICATOR_TEXT, } from "./generated/i18n/i18n-defaults.js"; @@ -28,12 +29,19 @@ const metadata = { /** * The indicated value of the rating - * @type {Integer} + *

+ * Note: If you set a number which is not round, it would be shown as follows: + *