Demos
How to import
import { Rating } from '@fibrous/semi-ui-react';
Basic Usage
Support two sizes: default, small.
Supports customized size if pass in a number. Refer to Customize
Code
import { Rating } from '@fibrous/semi-ui-react';
export default function RatingDemo() {
return (
<div>
<Rating defaultValue={5} />
<br />
<br />
<Rating size="small" defaultValue={5} />
</div>
);
}Half Star
Use allowHalf to support selection of half stars. Support to display decimals ratings other than 0.5.
Code
import { Rating } from '@fibrous/semi-ui-react';
export default function RatingDemo() {
return (
<div>
<Rating allowHalf defaultValue={3.5} />
<br />
<Rating allowHalf defaultValue={3.65} disabled />
</div>
);
}Disabled
Use disabled to disabled interaction.
Code
import { Rating } from '@fibrous/semi-ui-react';
export default function RatingDemo() {
return <Rating disabled defaultValue={3} />;
}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
import { Rating } from '@fibrous/semi-ui-react';
export default function RatingDemo() {
return (
<div>
<span>允许再次点击清除</span>
<br />
<Rating allowClear defaultValue={3} />
<br />
<br />
<span>禁止再次点击清除</span>
<br />
<Rating allowClear={false} defaultValue={3} />
</div>
);
}Text Description
Use tooltips to add description to Rating.
Code
import { useState } from 'react';
import { Rating } from '@fibrous/semi-ui-react';
export default function RatingDemo() {
const [value, setValue] = useState(0);
const change = (val: number) => setValue(val);
const desc = ['极差', '较差', '一般', '满意', '非常满意'];
return (
<div>
<span>
你对获得的帮助是否满意:
{value ? <span>{desc[value - 1]}</span> : ''}
</span>
<br />
<Rating tooltips={desc} onChange={change} value={value} />
</div>
);
}Customize
You can customize characters, numbers of rating and size.
Note that customized size could only work with customized characters.
Code
import { IconLikeHeart } from '@fibrous/semi-icons-react';
import { Rating } from '@fibrous/semi-ui-react';
export default function RatingDemo() {
return (
<div>
<Rating style={{ color: 'red' }} character={<IconLikeHeart size="extra-large" />} defaultValue={3} />
<br />
<br />
<Rating style={{ color: 'red' }} size={48} allowHalf character={<IconLikeHeart style={{ fontSize: 48 }} />} defaultValue={3} />
<br />
<br />
<Rating character="赞" size={18} defaultValue={3} />
<br />
<br />
<Rating count={10} defaultValue={6} />
</div>
);
}API Reference
Props
| Property | Description | Type | Default |
|---|---|---|---|
| allowClear | Whether clicking the selected star again clears the value. | boolean | true |
| allowHalf | Whether half stars can be selected. | boolean | false |
| aria-invalid | Whether validation failed, set as aria-invalid on the root element. | boolean | - |
| aria-required | Whether a value is required, set as aria-required on the root element. | boolean | - |
| autoFocus | Focuses the rating on mount, on the same radio that focus() picks. | boolean | - |
| character | Character drawn in every star, a React node such as <IconLikeHeart />; the star icon when not set. When it is a plain text string, that text is the unit in each star's accessible name and the group summary. | React.ReactNode | - |
| className | Class name of the root element. | string | - |
| count | Total number of stars. | number | 5 |
| defaultValue | Initial value when uncontrolled. | number | 0 |
| disabled | Read-only: no interaction and no focus. | boolean | - |
| id | Id of the root element. | string | - |
| onBlur | Called when focus leaves the whole rating; moving between stars does not call it. | Type(e: React.FocusEvent) => void | - |
| onChange | Called when the selection changes, with the new value. | Type(value: number) => void | - |
| onClick | Called when a star is clicked or selected with Enter or Space, with the event and the star index. It is not a native click listener on the root element. | Type(e: React.MouseEvent | React.KeyboardEvent, index: number) => void | - |
| onFocus | Called when focus enters the whole rating; moving between stars does not call it. | Type(e: React.FocusEvent) => void | - |
| onHoverChange | Called when the hovered value changes; receives undefined when the pointer leaves or a click clears the value. | Type(value?: number) => void | - |
| onKeyDown | Called for an arrow key that moves the value; other keys do not call it. | Type(e: React.KeyboardEvent) => void | - |
| prefixCls | Class name prefix of the component. | string | "semi-rating" |
| preventScroll | Whether to keep the browser from scrolling the document to show a star focused inside the component, including focus from autoFocus and focus(). | boolean | - |
| ref | Handle of the component, exposing the focus() and blur() methods. | TypeReact.Ref<RatingHandle> | - |
| size | Size: default or small, or a number for a custom size. | 'small' | 'default' | number | "default" |
| style | Style of the root element. | React.CSSProperties | {} |
| tooltips | Tooltip text for each star, matched by array index to the star position; an empty or missing item shows no tooltip. | string[] | - |
| value | Controlled value. When given, this value decides what is shown; back to undefined it returns to defaultValue and becomes uncontrolled. | number | - |
Methods
| Method | Description | Type |
|---|---|---|
| blur | Removes focus when it is inside the rating. Does nothing when disabled. | Type() => void |
| focus | Focuses the radio that Tab reaches, the same one autoFocus picks. Does nothing when disabled. | Type() => void |
aria-label is used as is as the accessible name of the radiogroup, which summarizes the current value when aria-label is not set; aria-labelledby takes the id of the labelling element as that name; data-* and other native attributes land on the role="radiogroup" root ul.
focus() on the ref focuses the radio that Tab reaches (the same one autoFocus uses), and blur() only takes effect when focus is inside the rating. tabIndex is no longer supported: a passed value is discarded and the list is fixed at tabIndex={-1}, so only the checked radio can be reached with Tab.
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 | 聚焦轮廓宽度 |