1# Rating
2
3The **Rating** component provides a rating bar.
4
5>  **NOTE**
6>
7>  This component is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version.
8
9
10## Child Components
11
12Not supported
13
14
15## APIs
16
17Rating(options?: RatingOptions)
18
19**Widget capability**: This API can be used in ArkTS widgets since API version 9.
20
21**Atomic service API**: This API can be used in atomic services since API version 11.
22
23**System capability**: SystemCapability.ArkUI.ArkUI.Full
24
25**Parameters**
26
27| Name| Type                                     | Mandatory| Description          |
28| ------ | ----------------------------------------- | ---- | -------------- |
29| rating | [RatingOptions](#ratingoptions13) | No  | Rating bar options.|
30
31## Attributes
32
33### stars
34
35stars(value: number)
36
37Sets the total number of ratings (stars). If the value set is less than or equal to 0, the default value is used.
38
39**Widget capability**: This API can be used in ArkTS widgets since API version 9.
40
41**Atomic service API**: This API can be used in atomic services since API version 11.
42
43**System capability**: SystemCapability.ArkUI.ArkUI.Full
44
45**Parameters**
46
47| Name| Type  | Mandatory| Description                        |
48| ------ | ------ | ---- | ---------------------------- |
49| value  | number | Yes  | Total number of ratings.<br>Default value: **5**|
50
51### stepSize
52
53stepSize(value: number)
54
55Sets the step for rating. A value less than 0.1 evaluates to the default value.
56
57**Widget capability**: This API can be used in ArkTS widgets since API version 9.
58
59**Atomic service API**: This API can be used in atomic services since API version 11.
60
61**System capability**: SystemCapability.ArkUI.ArkUI.Full
62
63**Parameters**
64
65| Name| Type  | Mandatory| Description                                                       |
66| ------ | ------ | ---- | ----------------------------------------------------------- |
67| value  | number | Yes  | Step for rating.<br>Default value: **0.5**<br>Value range: [0.1, stars]|
68
69### starStyle
70
71starStyle(options: StarStyleOptions)
72
73Sets the star style. For details about the supported image types, see [Image](ts-basic-components-image.md).
74
75Local and online images are supported, but not **PixelMap** and **Resource** objects.
76
77By default, the image is loaded in asynchronous mode. Synchronous loading is not supported.
78
79**Widget capability**: This API can be used in ArkTS widgets since API version 9.
80
81**Atomic service API**: This API can be used in atomic services since API version 11.
82
83**System capability**: SystemCapability.ArkUI.ArkUI.Full
84
85**Parameters**
86
87| Name | Type                                           | Mandatory| Description                                                        |
88| ------- | ----------------------------------------------- | ---- | ------------------------------------------------------------ |
89| options | [StarStyleOptions](#starstyleoptions13) | Yes  | Star style.<br>**NOTE**<br>If the path specified for **backgroundUri**, **foregroundUri**, or **secondaryUri** is incorrect, no image is displayed.<br>If **backgroundUri** or **foregroundUri** is set to **undefined** or an empty string, the **Rating** component loads the default star image source.<br>If **secondaryUri** is set to **undefined** or an empty string or is not set, **backgroundUri** is prioritized, which is equivalent to where only **foregroundUri** and **backgroundUri** are set.|
90
91>  **NOTE**
92>
93>  The drawing area of each rating image is [width/stars, height], wherein **width** and **height** indicate the width and height of the **Rating** component, respectively.
94>
95>  To specify the drawing area as a square, you are advised to customize the width and height in this format: [height * stars, height], width = height * stars.
96
97### contentModifier<sup>12+</sup>
98
99contentModifier(modifier: ContentModifier\<RatingConfiguration>)
100
101Creates a content modifier.
102
103**Atomic service API**: This API can be used in atomic services since API version 12.
104
105**System capability**: SystemCapability.ArkUI.ArkUI.Full
106
107**Parameters**
108
109| Name| Type                                         | Mandatory| Description                                            |
110| ------ | --------------------------------------------- | ---- | ------------------------------------------------ |
111| modifier  | [ContentModifier\<RatingConfiguration>](#ratingconfiguration12) | Yes  | Content modifier to apply to the current component.<br>**modifier**: content modifier. You need a custom class to implement the **ContentModifier** API.|
112
113
114## Events
115
116### onChange
117
118onChange(callback:(value: number) =&gt; void)
119
120Triggered when the rating value changes.
121
122**Widget capability**: This API can be used in ArkTS widgets since API version 9.
123
124**Atomic service API**: This API can be used in atomic services since API version 11.
125
126**System capability**: SystemCapability.ArkUI.ArkUI.Full
127
128**Parameters**
129
130| Name| Type  | Mandatory| Description          |
131| ------ | ------ | ---- | -------------- |
132| value  | number | Yes  | Rating value.|
133
134## Sequential Keyboard Navigation Specifications
135| Key        | Description                       |
136|------------|-----------------------------|
137| Tab        | Switch the focus between components.                   |
138| Left and right arrow keys  | Increase or decrease the rating on preview at the specified step, without changing the actual rating.|
139| Home       | Move the focus to the first star, without changing the actual rating.         |
140| End        | Move the focus to the last star, without changing the actual rating.        |
141| Space/Enter | Submit the rating result based on the current rating.              |
142
143## RatingConfiguration<sup>12+</sup>
144
145You need a custom class to implement the **ContentModifier** API.
146
147**Atomic service API**: This API can be used in atomic services since API version 12.
148
149**System capability**: SystemCapability.ArkUI.ArkUI.Full
150
151| Name | Type   |    Read Only   |    Optional     |  Description             |
152| ------ | ------ | ------ |-------------------------------- |-------------------------------- |
153| rating | number | No| No|Value to rate.<br>Default value: **0**|
154| indicator | boolean | No| No| Whether the component is used only as an indicator.<br>Default value: **false**|
155| stars | number | No| No|Total number of ratings.<br>Default value: **5**|
156| stepSize | number | No| No|Step of an operation.<br>Default value: **0.5**|
157| triggerChange | Callback\<number> | No| No|Callback triggered when the rating value changes.|
158
159## RatingOptions<sup>13+</sup>
160
161**Widget capability**: This API can be used in ArkTS widgets since API version 13.
162
163**Atomic service API**: This API can be used in atomic services since API version 13.
164
165**System capability**: SystemCapability.ArkUI.ArkUI.Full
166
167| Name     | Type   | Mandatory| Description                                                        |
168| --------- | ------- | ---- | ------------------------------------------------------------ |
169| rating    | number  | Yes  | Value to rate.<br>Default value: **0**<br>Value range: [0, stars]<br>Values less than 0 are treated as **0**, and values greater than the value of **stars** are treated as the value of **stars**.<br>This parameter supports two-way binding through [$$](../../../quick-start/arkts-two-way-sync.md).|
170| indicator | boolean | No  | Whether the component is used only as an indicator.<br>Default value: **false**<br>**NOTE**<br>When **indicator** is set to **true**, the default component height is 12.0 vp, and the component width is calculated as follows: Height x Value of **stars**.<br>When **indicator** is set to **false**, the default component height is 28.0 vp, and the component width is calculated as follows: Height x Value of **stars**.|
171
172## StarStyleOptions<sup>13+</sup>
173
174**Widget capability**: This API can be used in ArkTS widgets since API version 13.
175
176**Atomic service API**: This API can be used in atomic services since API version 13.
177
178**System capability**: SystemCapability.ArkUI.ArkUI.Full
179
180| Name         | Type  | Mandatory| Description                                                        |
181| ------------- | ------ | ---- | ------------------------------------------------------------ |
182| backgroundUri | string | Yes  | Image path for the unselected star. You can use the default system image or a custom image.  |
183| foregroundUri | string | Yes  | Image path for the selected star. You can use the default system image or a custom image.    |
184| secondaryUri  | string | No  | Image path for the partially selected star. You can use the default system image or a custom image.|
185
186## Example
187
188### Example 1
189
190```ts
191// xxx.ets
192@Entry
193@Component
194struct RatingExample {
195  @State rating: number = 3.5
196
197  build() {
198    Column() {
199      Column() {
200        Rating({ rating: this.rating, indicator: false })
201          .stars(5)
202          .stepSize(0.5)
203          .margin({ top: 24 })
204          .onChange((value: number) => {
205            this.rating = value
206          })
207        Text('current score is ' + this.rating)
208          .fontSize(16)
209          .fontColor('rgba(24,36,49,0.60)')
210          .margin({ top: 16 })
211      }.width(360).height(113).backgroundColor('#FFFFFF').margin({ top: 68 })
212
213      Row() {
214        Image('common/testImage.jpg')
215          .width(40)
216          .height(40)
217          .borderRadius(20)
218          .margin({ left: 24 })
219        Column() {
220          Text('Yue')
221            .fontSize(16)
222            .fontColor('#182431')
223            .fontWeight(500)
224          Row() {
225            Rating({ rating: 3.5, indicator: false }).margin({ top: 1, right: 8 })
226            Text('2021/06/02')
227              .fontSize(10)
228              .fontColor('#182431')
229          }
230        }.margin({ left: 12 }).alignItems(HorizontalAlign.Start)
231
232        Text('1st Floor')
233          .fontSize(10)
234          .fontColor('#182431')
235          .position({ x: 295, y: 8 })
236      }.width(360).height(56).backgroundColor('#FFFFFF').margin({ top: 64 })
237    }.width('100%').height('100%').backgroundColor('#F1F3F5')
238  }
239}
240```
241
242![rating](figures/rating.gif)
243
244### Example 2
245
246```ts
247// xxx.ets
248@Entry
249@Component
250struct RatingExample {
251  @State rating: number = 3.5
252
253  build() {
254    Column() {
255      Rating({ rating: this.rating, indicator: false })
256        .stars(5)
257        .stepSize(0.5)
258        .starStyle({
259          backgroundUri: '/common/imag1.png', // The common folder is at the same level as pages.
260          foregroundUri: '/common/imag2.png',
261          secondaryUri: '/common/imag3.png'
262        })
263        .margin({ top: 24 })
264        .onChange((value: number) => {
265          this.rating = value
266        })
267      Text('current score is ' + this.rating)
268        .fontSize(16)
269        .fontColor('rgba(24,36,49,0.60)')
270        .margin({ top: 16 })
271    }.width('100%').height('100%').backgroundColor('#F1F3F5')
272  }
273}
274```
275
276![rating1](figures/rating1.gif)
277
278### Example 3
279This example implements a custom rating bar, with each circle representing 0.5 point. If **ratingIndicator** is set to **true**, the rating bar is used only as an indicator, and the rating cannot be changed.
280if it is set to **false**, the rating can be changed. **ratingStars** sets the rating value. **ratingStepsize** sets the step for rating.
281
282```ts
283// xxx.ets
284class MyRatingStyle implements ContentModifier<RatingConfiguration> {
285  name: string = ""
286  style: number = 0
287  constructor(value1: string, value2: number) {
288    this.name = value1
289    this.style = value2
290  }
291  applyContent() : WrappedBuilder<[RatingConfiguration]> {
292    return wrapBuilder(buildRating)
293  }
294}
295
296@Builder function buildRating(config: RatingConfiguration) {
297  Column() {
298    Row() {
299      Circle({ width: 25, height: 25 })
300        .fill(config.rating >= 0.4 ? Color.Black : Color.Red)
301        .onClick((event: ClickEvent) => {
302          if (!config.indicator) {
303            if (config.stepSize = 0.5) {
304              config.triggerChange(0.5);
305              return
306            }
307            if (config.stepSize = 1) {
308              config.triggerChange(1);
309              return
310            }
311          }
312        }).visibility(config.stars >= 1 ? Visibility.Visible : Visibility.Hidden)
313      Circle({ width: 25, height: 25 })
314        .fill(config.rating >= 0.9 ? Color.Black : Color.Red)
315        .onClick((event: ClickEvent) => {
316          if (!config.indicator) {
317            config.triggerChange(1);
318          }
319        }).visibility(config.stars >= 1 ? Visibility.Visible : Visibility.Hidden)
320      Circle({ width: 25, height: 25 })
321        .fill(config.rating >= 1.4 ? Color.Black : Color.Red)
322        .onClick((event: ClickEvent) => {
323          if (!config.indicator) {
324            if (config.stepSize = 0.5) {
325              config.triggerChange(1.5);
326              return
327            }
328            if (config.stepSize = 1) {
329              config.triggerChange(2);
330              return
331            }
332          }
333        }).visibility(config.stars >= 2 ? Visibility.Visible : Visibility.Hidden).margin({left:10})
334      Circle({ width: 25, height: 25 })
335        .fill(config.rating >= 1.9 ? Color.Black : Color.Red)
336        .onClick((event: ClickEvent) => {
337          if (!config.indicator) {
338            config.triggerChange(2);
339          }
340        }).visibility(config.stars >= 2 ? Visibility.Visible : Visibility.Hidden)
341      Circle({ width: 25, height: 25 })
342        .fill(config.rating >= 2.4 ? Color.Black : Color.Red)
343        .onClick((event: ClickEvent) => {
344          if (!config.indicator) {
345            if (config.stepSize = 0.5) {
346              config.triggerChange(2.5);
347              return
348            }
349            if (config.stepSize = 1) {
350              config.triggerChange(3);
351              return
352            }
353          }
354        }).visibility(config.stars >= 3 ? Visibility.Visible : Visibility.Hidden).margin({left:10})
355      Circle({ width: 25, height: 25 })
356        .fill(config.rating >= 2.9 ? Color.Black : Color.Red)
357        .onClick((event: ClickEvent) => {
358          if (!config.indicator) {
359            config.triggerChange(3);
360          }
361        }).visibility(config.stars >= 3 ? Visibility.Visible : Visibility.Hidden)
362      Circle({ width: 25, height: 25 })
363        .fill(config.rating >= 3.4 ? Color.Black : Color.Red)
364        .onClick((event: ClickEvent) => {
365          if (!config.indicator) {
366            if (config.stepSize = 0.5) {
367              config.triggerChange(3.5);
368              return
369            }
370            if (config.stepSize = 1) {
371              config.triggerChange(4);
372              return
373            }
374          }
375        }).visibility(config.stars >= 4 ? Visibility.Visible : Visibility.Hidden).margin({left:10})
376      Circle({ width: 25, height: 25 })
377        .fill(config.rating >= 3.9 ? Color.Black : Color.Red)
378        .onClick((event: ClickEvent) => {
379          if (!config.indicator) {
380            config.triggerChange(4);
381          }
382        }).visibility(config.stars >= 4 ? Visibility.Visible : Visibility.Hidden)
383      Circle({ width: 25, height: 25 })
384        .fill(config.rating >= 4.4 ? Color.Black : Color.Red)
385        .onClick((event: ClickEvent) => {
386          if (!config.indicator) {
387            if (config.stepSize = 0.5) {
388              config.triggerChange(4.5);
389              return
390            }
391            if (config.stepSize = 1) {
392              config.triggerChange(5);
393              return
394            }
395          }
396        }).visibility(config.stars >= 5 ? Visibility.Visible : Visibility.Hidden).margin({left:10})
397      Circle({ width: 25, height: 25 })
398        .fill(config.rating >= 4.9 ? Color.Black : Color.Red)
399        .onClick((event: ClickEvent) => {
400          if (!config.indicator) {
401            config.triggerChange(5);
402          }
403        }).visibility(config.stars >= 5 ? Visibility.Visible : Visibility.Hidden)
404    }
405    Text("Rating: "+ config.rating)
406  }
407}
408
409@Entry
410@Component
411struct ratingExample {
412  @State rating: number = 0;
413  @State ratingIndicator: boolean = true;
414  @State ratingStars: number = 0;
415  @State ratingStepsize: number = 0.5;
416  @State ratingEnabled: boolean = true;
417  build() {
418    Row() {
419      Column() {
420        Rating({
421          rating: 0,
422          indicator: this.ratingIndicator
423        })
424          .stepSize(this.ratingStepsize)
425          .stars(this.ratingStars)
426          .backgroundColor(Color.Transparent)
427          .width('100%')
428          .height(50)
429          .onChange((value: number) => {
430            console.info('Rating change is'+ value);
431            this.rating = value
432          })
433          .contentModifier(new MyRatingStyle("hello", 3))
434        Button(this.ratingIndicator ? "ratingIndicator : true" : "ratingIndicator : false")
435          .onClick((event) => {
436            if (this.ratingIndicator) {
437              this.ratingIndicator = false
438            } else {
439              this.ratingIndicator = true
440            }
441          }).margin({top : 5})
442
443        Button(this.ratingStars < 5 ? "ratingStars + 1, ratingStars = " + this.ratingStars : "Maximum value of ratingStars: 5")
444          .onClick((event) => {
445            if (this.ratingStars < 5) {
446              this.ratingStars += 1
447            }
448          }).margin({top : 5})
449
450        Button(this.ratingStars > 0 ? "ratingStars - 1, ratingStars = " + this.ratingStars : "Values less than or equal to 0 are handled as 5")
451          .onClick((event) => {
452            if (this.ratingStars > 0) {
453              this.ratingStars -= 1
454            }
455          }).margin({top : 5})
456
457        Button(this.ratingStepsize == 0.5 ? "ratingStepsize : 0.5" : "ratingStepsize : 1")
458          .onClick((event) => {
459            if (this.ratingStepsize == 0.5) {
460              this.ratingStepsize = 1
461            } else {
462              this.ratingStepsize = 0.5
463            }
464          }).margin({top : 5})
465      }
466      .width('100%')
467      .height('100%')
468      .justifyContent(FlexAlign.Center)
469    }
470    .height('100%')
471  }
472}
473```
474
475![rating2](figures/rating2.gif)
476