rate —— 評価
評価は「スコアをつける」ことを離散的な星選択に変えます:ユーザーは数字を入力するのではなく、星を点亮します。core/rate が管理するのは星ごとの充填バリエーション(全星 / 半星 / 空)、半星ステップと浮動小数点の蓄積、そして APG の slider セマンティクスです——評価コントロールはアクセシビリティの観点ではラジオボタングループではなくスライダーです。
- 各端の
LhRate実装:商品 / サービス評価、難易度のマーク、満足度調査。 - 値域が 1~N の整数(または半星を許容する 0.5 ステップ)のシーン。
- 使うべきでない:精密な小数や任意の範囲の連続値が必要なら
sliderかinput-numberを使います;読み取り専用で表示のみであれば rate を使ってもよいですが、readonly状態に切り替えるべきです。
インポート方法
Section titled “インポート方法”import { LH_RATE_MAX_DEFAULT, clampRate, stepRate, getStarFill, getRateAriaText, getRateClassNames, getRateAria,} from '@lh-ui/share/core/rate'import type { LhRateState } from '@lh-ui/share/core/rate'stepRate は加減の後に Math.round(next * 10) / 10 を行います——これは余計なものではなく、浮動小数点蓄積への防御です:0.5 ステップは JS では 0.5 → 1.0 → 1.5 と問題ないものの、0.1 + 0.2 !== 0.3 のような罠が他のステップ値で現れるため、一律に小数第 1 位を残して結果を綺麗な小数に固定します。getStarFill の判定順序は full → half → empty です:先に整星を判定し、その後に半星を判定することで、value=2.5 のとき第 3 星目が empty ではなく half になることを保証します。
getRateAriaText は formatMessage で {n} を補間し、メッセージテンプレートは言語パック(rate.ariaText)から取得します。数値は事前に同じ round を行ってから文字列にします——aria のメッセージと視覚的な充填は、必ず同一の正規化された値に基づかなければなりません。
| 関数 | シグネチャ | 戻り値 | 役割 |
|---|---|---|---|
clampRate |
(value: number | undefined, max: number) => number |
クランプ値 | 非数値は 0、上限は max |
stepRate |
(value, direction: 1 | -1, allowHalf, max) => number |
ステップ値 | 半星は 0.5 ステップ、小数第 1 位 |
getStarFill |
(value, index, allowHalf) => 'full' | 'half' | 'empty' |
充填バリエーション | 第 index 番目の星(1 始まり) |
getRateAriaText |
(value, template: string) => string |
aria メッセージ | {n} を補間して星の数に |
getRateClassNames |
(state: LhRateState & { readonly, disabled }) => string[] |
クラス名 | 読み取り専用 / 無効の修飾 |
getRateAria |
(options: { value, max, disabled?, ariaValueText? }) => LhAriaAttrs |
aria 属性パック | slider セマンティクス |
export interface LhRateState { max: number value: number allowHalf: boolean}
export const LH_RATE_MAX_DEFAULT = 5アクセシビリティ
Section titled “アクセシビリティ”getRateAria は slider セマンティクス(radiogroup ではない)を出力します:評価の値は連続的に調整可能(特に半星モード)で、APG の rating パターンはしばしば slider として実装されます。キーボード操作は slider の規約に従います:←/→ で 1 ステップ減 / 増。
getRateAria({ value: 4.5, max: 5 })// { role: 'slider', 'aria-valuenow': 4.5, 'aria-valuemin': 0, 'aria-valuemax': 5 }
getRateAria({ value: 0, max: 5, disabled: true, ariaValueText: '0 星' })// { role: 'slider', 'aria-valuenow': 0, 'aria-valuemin': 0, 'aria-valuemax': 5,// 'aria-disabled': true, 'aria-valuetext': '0 星' }aria-valuetext はvaluenow より優先して読み上げられます——スクリーンリーダーは「4.5」ではなく「星 4 つ半」と読み上げます。各星のボタンには別途 aria-label が必要です(UI 層が getRateAriaText(value, t('rate.ariaText')) で生成します)。
import { getStarFill, stepRate, clampRate } from '@lh-ui/share/core/rate'
getStarFill(3.5, 3, true) // 'full'getStarFill(3.5, 4, true) // 'half'getStarFill(3.5, 4, false) // 'empty'(整星モードでは 3.5 の第 4 星は空)getStarFill(3.5, 5, true) // 'empty'stepRate(3, 1, true, 5) // 3.5stepRate(3.5, 1, true, 5) // 4stepRate(0, -1, true, 5) // 0(クランプ)clampRate(undefined, 5) // 0clampRate(9, 5) // 5<!-- Vue3 --><div :class="getRateClassNames({ max, value, allowHalf, readonly, disabled })"> <div class="lh-rate__star-list" v-bind="getRateAria({ value, max, disabled, ariaValueText: getRateAriaText(value, t('rate.ariaText')) })" tabindex="0" @keydown.left="onStep(-1)" @keydown.right="onStep(1)" > <button v-for="i in max" :key="i" type="button" class="lh-rate__star" :class="`lh-rate__star--${getStarFill(value, i, allowHalf)}`" @click="onSelect(i)" > <LhIcon :name="getStarFill(value, i, allowHalf) === 'empty' ? 'star' : 'star-fill'" /> </button> </div></div>// React:半星モードでは hover 状態で value を決定し、モバイルでは星全体のクリックを使う// ステップ:const next = stepRate(value, dir, allowHalf, max); onChange(clampRate(next, max))// uniapp:<view> で max 個の星をループ;非 h5 端では aria サポートが限られ、getRateAria の undefined 属性は無視されるスタイルとトークン
Section titled “スタイルとトークン”| クラス名 | 意味 |
|---|---|
.lh-rate |
基底クラス |
.lh-rate--readonly |
読み取り専用(hover ハイライトを非表示、ポインタを無効化) |
.lh-rate--disabled |
無効 |
.lh-rate__star-list |
星グループのコンテナ(tabindex とキーボードイベントはここに掛ける) |
.lh-rate__star |
星 1 つのボタン |
.lh-rate__star--full / --half / --empty |
充填バリエーション(半星は半分隠す重ね合わせで表現) |
.lh-rate__text |
スコアのメッセージ(「3.5 点」など) |
星の色は --lh-warning-color(黄)、空の星は --lh-fill-color / --lh-border-color です。
getStarFillの index は 1 始まりです。ループにはv-for="i in max"(max を含む)を使い、v-for="i in max - 1"ではありません。- 半星と整星の一貫性:
allowHalfを変えた後、stepRateとgetStarFillには必ず同じ値を渡さなければなりません。さもなくばクリックとキーボードステップのバリエーションが合わなくなります。 - 読み取り専用のセマンティクス:
readonlyはクラス名を切り替えるだけ(視覚的にインタラクションを無効化)で、getRateAriaはaria-disabledを出力しません——読み取り専用の評価は引き続きスクリーンリーダーに理解可能な評価値として認識されるべきで(aria-valuetextによる)、ここが disabled との違いです。 maxの境界:LH_RATE_MAX_DEFAULTは 5 です;UI 層は max を変更可能ですが、星が多すぎると(20 など)狭い画面で溢れるため、独自に折り返してください。- value が小数なのに allowHalf が false:core はこの組み合わせを検証せず、
getStarFillは 3.5 を「星 3 つ full + 第 4 星は empty」として扱います——呼び出し側の設定ミスであり、視覚的には切り詰めとして現れます。
@lh-ui/share/core/rate → getStarFill( )(填好参数后点运行)Copyright © 2024-2026 FengMo WenXue