Demos
How to import
<script setup lang="ts">
import { Rating } from '@fibrous/semi-ui-vue';
</script>
Basic Usage
Support two sizes: default, small.
Supports customized size if pass in a number. Refer to Customize
Code
<script setup lang="ts">
import { Rating } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Rating :defaultValue="5" />
<br />
<br />
<Rating :defaultValue="5" size="small" />
</div>
</template>Half Star
Use allowHalf to support selection of half stars. Support to display decimals ratings other than 0.5.
Code
<script setup lang="ts">
import { Rating } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Rating allowHalf :defaultValue="3.5" />
<br />
<Rating allowHalf :defaultValue="3.65" disabled />
</div>
</template>Disabled
Use disabled to disabled interaction.
Code
<script setup lang="ts">
import { Rating } from '@fibrous/semi-ui-vue';
</script>
<template>
<Rating :defaultValue="3" disabled />
</template>Click to Clear
allowClear Property allows you to clear the value when you click on the component again. By default it is set to true.
禁止再次点击清除
Code
<script setup lang="ts">
import { Rating } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<span>允许再次点击清除</span>
<br />
<Rating allowClear :defaultValue="3" />
<br />
<br />
<span>禁止再次点击清除</span>
<br />
<Rating :allowClear="false" :defaultValue="3" />
</div>
</template>Text Description
Use tooltips to add description to Rating.
Code
<script setup lang="ts">
import { ref } from 'vue';
import { Rating } from '@fibrous/semi-ui-vue';
const value = ref(0);
const desc = ['极差', '较差', '一般', '满意', '非常满意'];
</script>
<template>
<div>
<span>
你对获得的帮助是否满意:
<span v-if="value">{{ desc[value - 1] }}</span>
</span>
<br />
<Rating v-model="value" :tooltips="desc" />
</div>
</template>Customize
You can customize characters, numbers of rating and size.
Note that customized size could only work with customized characters.
Use the #character slot to customize the character.
Code
<script setup lang="ts">
import { IconLikeHeart } from '@fibrous/semi-icons-vue';
import { Rating } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Rating :defaultValue="3" :style="{ color: 'red' }">
<template #character>
<IconLikeHeart size="extra-large" />
</template>
</Rating>
<br />
<br />
<Rating allowHalf :defaultValue="3" :size="48" :style="{ color: 'red' }">
<template #character>
<IconLikeHeart :style="{ fontSize: '48px' }" />
</template>
</Rating>
<br />
<br />
<Rating :defaultValue="3" :size="18">
<template #character>赞</template>
</Rating>
<br />
<br />
<Rating :count="10" :defaultValue="6" />
</div>
</template>API Reference
Props
| Property | Description | Type | Default |
|---|---|---|---|
| modelValue | Current value, used with v-model. When given, this value decides what is shown; back to undefined it returns to defaultValue and becomes uncontrolled. | number | undefined |
| defaultValue | Initial value when uncontrolled. | number | semiDefault("Rating", "defaultValue", 0) |
| count | Total number of stars. | number | semiDefault("Rating", "count", 5) |
| allowHalf | Whether half stars can be selected. | boolean | semiDefault("Rating", "allowHalf", false) |
| allowClear | Whether clicking the selected star again clears the value. | boolean | semiDefault("Rating", "allowClear", true) |
| disabled | Read-only: no interaction and no focus. | boolean | semiDefault("Rating", "disabled", false) |
| size | Size: default or small, or a number for a custom size. | number | "small" | "default" | semiDefault("Rating", "size", "default") |
| tooltips | Prompt text for each item. | string[] | semiGlobalDefault("Rating", "tooltips") |
| prefixCls | Class name prefix of the component. | string | semiDefault("Rating", "prefixCls", cssClasses.PREFIX) |
| autofocus | Whether to focus on mount. | boolean | semiGlobalDefault("Rating", "autofocus") |
| preventScroll | Whether the browser should avoid scrolling the document to show the newly focused element, for focus inside the component. | boolean | semiGlobalDefault("Rating", "preventScroll") |
| ariaLabel | Accessible name of the radiogroup; without it the name summarizes the value. | string | semiGlobalDefault("Rating", "ariaLabel") |
Events
| Event | Description | Callback parameters |
|---|---|---|
| update:modelValue | Emitted when the selection changes, for v-model to write back. | [value: number] |
| change | Emitted when the selection changes, with the new value. | [value: number] |
| hoverChange | Emitted when the hovered value changes; receives undefined when the pointer leaves or a click clears the value. | [value: number | undefined] |
| click | Emitted when a star is clicked or selected with Enter or Space, with the event and the star index. It shadows a native click listener on the root element. | [event: MouseEvent | KeyboardEvent, index: number] |
| focus | Emitted when focus enters the rating; moving between stars does not emit it. | [event: FocusEvent] |
| blur | Emitted when focus leaves the rating. | [event: FocusEvent] |
| keydown | Emitted only for an arrow key that moved the value. | [event: KeyboardEvent] |
Slots
| Slot | Description | Scope parameters |
|---|---|---|
| character | Character drawn in every star. When it is plain text, that text is the unit in each star's accessible name and the group summary; otherwise the locale's unit is used. | any |
Exposes
| Name | Description | Type |
|---|---|---|
| focus | Focuses the radio that Tab reaches, the same one autofocus uses. Does nothing when disabled. | Type() => void |
| blur | Blurs the focused element inside the rating. Does nothing when focus is elsewhere or the rating is disabled. | Type() => void |
class, style and native attributes (id, aria-labelledby, aria-invalid, aria-required, data-* and so on) land on the role="radiogroup" root element through attrs. tabindex and name are discarded and the list is fixed at tabindex="-1", so only the checked radio can be reached with Tab. Once click is declared as an event, @click is no longer a native click listener on the root element.
Accessibility
ARIA
- Rating has
aria-checkedto indicate whether it is currently selected,aria-posinsetto indicate the position in the list, andaria-setsizeto indicate the length of the list. - Semi supports custom Rating semantics
aria-labelis used as is for the accessible name of the radiogroup;- If the custom character is plain text (the
characterprop as a string in React, a text-only#characterslot in Vue), each star's name uses that text as the unit, otherwise the locale's default unit; - The two are independent and can be passed together.
Keyboard and Focus
- Initial focus settings for Rating (the Tab stop, following the APG radio group):
- If there is a selection item in Rating, the initial focus is set to the last selection item (for example: if 3 stars are lit, the initial focus is set on the third lit star);
- If Rating has no selected item (value is 0), the initial focus is on the empty-star radio that stands for 0 stars;
- When the value matches no radio (for example 2.5 without
allowHalf), the first radio is the Tab stop, so the keyboard can still enter; an arrow key then selects the adjacent radio (3 with the right arrow and 2 with the left arrow for 2.5).
- On a Rating group, use the
down arroworright arrowto select the next star (the value increases, and wraps to 0 after the last star) and theup arroworleft arrowto select the previous star (the value decreases, and wraps from 0 to the last star); in RTL only the left and right arrows are mirrored;- The user sets the
allowHalfproperty, and presses the arrow keys to select or deselect only half a star;
- The user sets the
Spaceselects the focused star when it is not selected; pressingSpaceon a selected star does not clear it. Clear withEnteror a click (controlled byallowClear);- The list itself is not a Tab stop, so Rating used as a Tooltip trigger adds no extra Tab stop;
- Calling
focus()on the instance focuses the radio that Tab reaches; - With
tooltips, keyboard focus on a star shows that star's tip, linked througharia-describedby; - A disabled Rating cannot get the focus.
Design Tokens
| Sass variable | Value | Usage |
|---|---|---|
| $transition_duration-rating-color | var(--semi-transition_duration-none) | 评分-背景色-动画持续时间 |
| $transition_function-rating-color | var(--semi-transition_function-easeIn) | 评分-背景色-过渡曲线 |
| $transition_delay-rating-color | var(--semi-transition_delay-none) | 评分-背景色-延迟时间 |
| $transform_scale-rating | var(--semi-transform_scale-none) | 评分-变大 |
| $color-rating-icon-default | var(--semi-yellow-5) | 评分图标按钮颜色 - 已填 |
| $color-rating-bg-default | var(--semi-color-fill-0) | 评分图标按钮颜色 - 未填 |
| $color-rating-outline-focus | $color-focus-ring | 聚焦轮廓颜色 |
| $spacing-rating-margin | 0px | 整体外边距 |
| $spacing-rating-padding | 0px | 整体内边距 |
| $spacing-rating_item-marginRight | 6px | 评分项右侧外边距 |
| $width-rating_item_small | 16px | 小尺寸评分项宽度 |
| $font-rating_item_small-fontSize | $width-rating_item_small | 小尺寸评分项文本字体大小 |
| $width-rating_item_default | 24px | 评分项宽度 |
| $font-rating_item_default-fontSize | $width-rating_item_default | 评分项文本字体大小 |
| $width-rating-outline-focus | $width-focus-ring | 聚焦轮廓宽度 |