Skip to content
fandhe-frontendcore v0.4.3
GitHub

Rating Group

fandhe-frontend-headless-ui の rating_group mod が提供する星評価の unstyled 部品です。Root / Label / Control / Item / HiddenInput の 5 anatomy パーツを持ち、1..=count の数値評価値(未評価は None)と hover プレビューを表現する状態機械を備えます。readonly フラグにより表示専用の平均評価等も安全に描画できます。

/themes/ 側の RatingGroup(Chakra ライクな variant/size を持つスタイル層)と異なり、CSS を一切持ちません。

RatingGroupProps(disabled/readonly/required)は次のように各パーツへ反映されます。label は data-disabled/data-required を、control は data-disabled/data-readonly/aria-required に加えて disabled/readonly/required が真のときのみ aria-disabled="true"/aria-readonly="true"/aria-required="true" を付与します。hidden-input の required は type="hidden" に効果がないため付与しません。

キーボード操作(未実装)

item は tabindex を出力しません(タブ順序に入りません)。ark-ui Rating Group は Arrow キーによる星間移動 + Enter による確定選択を仕様として持ちますが、本部品(fandhe-frontend-headless-ui)はクリック・ポインタ hover・キー入力を実際に検知する DOM イベントハンドラの配線(fandhe-frontend-wasm-full)を一切持たず、SSR 静的マークアップと dispatch 契約(RatingGroupAction)のみを提供します。DOM 配線の実装と同時に tabindex を公開する方針です(配線が無い状態でタブ順序に入れると「到達できるが無反応」になるため、当初案の roving tabindex 先行公開は撤回しました)。

ポインタ・キーボード操作の実際の DOM 配線は fandhe-frontend-wasm-full の後続責務であり、本部品のスコープ外です。

参考サイトとの差分

ark-ui Rating Group と突合し、data-*/aria-* 語彙へ揃えました(キーボード操作の DOM 配線は上記のとおり未着手のため対象外)。一方、以下は意図的に合わせていません。

  • data-half(allow_half、0.5 刻み評価)は状態機械・CSS が別設計のため未提供です(#742 以来の継続)。
  • aria-setsize/aria-posinset(item)は全 item が DOM 上の兄弟要素として連続配置されるため、支援技術が自動算出できます。
  • aria-roledescription="rating"(item)は role="radio" + aria-label で十分と判断し、追随していません。
  • aria-orientation="horizontal"(control)は固定値かつ軸を持たないため、data-orientation も含めて不採用です。
  • data-hover/data-active/data-focus(pointer/focus 系)は SSR 静的出力の関心外です(Checkbox #1602 と同じ判断)。

スタイル済みの表示例は Rating Group を参照してください。

関連 API: fandhe-frontend-headless-ui API

自前 CSS の最小例

Themes 版を使わず本部品を直接使う場合、[data-scope="rating-group"][data-part="..."] セレクタでスタイルを当てます。以下は星の寸法・塗り分け(data-highlighted)・確定選択(data-checked)・無効化の最小例です(item は tabindex を出力せずタブ順序に入らないため、:focus-visible の例は含みません)。

CSS
[data-scope="rating-group"][data-part="item"] {
  display: inline-block;
  width: 1.25rem;
  height: 1.25rem;
  cursor: pointer;
}

[data-scope="rating-group"][data-part="item"][data-highlighted] {
  color: #f5a623;
}

[data-scope="rating-group"][data-part="item"][data-checked] {
  font-weight: bold;
}

[data-scope="rating-group"][data-part="item"][data-disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

Demo

枠線・余白は docs サイト側のデモ枠であり、fandhe-frontend-headless-ui 自体はスタイルを持ちません。

Rating
★★★

Features

  • Root / Label / Control / Item / HiddenInput の 5 anatomy パーツと、1..=count の数値評価値(未評価は None)+ hover プレビューを持つ状態機械を提供する。
  • role="radiogroup" + item の role="radio"/aria-checked で WAI-ARIA radio パターンを表現するが、ネイティブ <input type="radio"> の組ではなく単一の hidden_input(type="hidden")でフォーム送信値を送る。
  • hover(ポインタが指している星)は transient な CSR 挙動のため SSR 静的マークアップには現れず、hydration でも直列化しない(常に None から開始)。
  • readonly が true のとき値の変更操作は no-op になる(他ユーザーの平均評価等、表示専用の評価を安全に描画する用途)。
  • RatingGroupProps(disabled/readonly/required)が root/label/control/hidden_input の状態束を一元管理する(イシュー #1617)。label は data-disabled/data-required、control は data-disabled/data-readonly/aria-required + 真のときのみの aria-disabled="true"/aria-readonly="true"/aria-required="true" を反映する。
  • item は tabindex を出力しない。対応する DOM 配線(クリック・hover・キーボード。fandhe-frontend-wasm-full)が未実装のため、roving tabindex のみを先行公開すると「フォーカスは受けるが操作不能」な WAI-ARIA radio パターン違反になる(イシュー #1617 codex-review 指摘を受け、DOM 配線の実装と同時に tabindex を公開する方針とした)。

Anatomy

root
  label
  control
    item
  hidden-input

API Reference

Arguments

NameTypeDefaultDescription
root/label/control/hidden_input(props)&RatingGroupProps—disabled/readonly/required の状態束(イシュー #1617)。
label(id)Option<&str>—control(labelled_by) の参照先 id。
control(labelled_by)Option<&str>—Some のときのみ aria-labelledby を付与する。
item(index)u32—1-origin の星番号。data-value として動的値のまま出力する。
item(flags).checkedboolRatingItemFlags::default()確定選択中(index == value)かどうか。aria-checked/data-checked へ反映する。
item(flags).highlightedbool—塗り表示対象(index <= display_value)かどうか。data-highlighted へ反映する(確定選択とは独立の軸)。
item(flags).readonlybool—data-readonly を反映する。
item(aria_label)&str—呼び出し側が必須で与える国際化可能なラベル(例: "1 star")。フレームワーク側でハードコード生成しない。
hidden_input(name)Option<&str>—Some のとき name 属性を出力する。
hidden_input(value_text)&str—フォーム送信用の現在値 1 個(星群ではなく単一値)。

Data Attributes

PartAttributeObserved Values
itemdata-checked(値なし)
itemdata-highlighted(値なし)
itemdata-value1, 2, 3

Examples

Read-only average rating

RatingGroupProps { readonly: true, .. } + RatingItemFlags { readonly: true, .. } の他ユーザー平均評価表示例。

Average rating
★★★★★

Accessibility

WAI-ARIA

AttributeDescription
role="radiogroup" (control)固定付与。
aria-disabled / aria-readonly / aria-required (control)RatingGroupProps が真のときのみ "true" を出力する(イシュー #1617)。
role="radio" / aria-checked (item)item 自身が span[role="radio"](ネイティブ input の組ではない)。aria-checked は flags.checked を反映する。
aria-label (item)呼び出し側が必須で与える(例: "1 star")。