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 の例は含みません)。
[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 自体はスタイルを持ちません。
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)が未実装のため、rovingtabindexのみを先行公開すると「フォーカスは受けるが操作不能」な WAI-ARIA radio パターン違反になる(イシュー #1617 codex-review 指摘を受け、DOM 配線の実装と同時に tabindex を公開する方針とした)。
Anatomy
root
label
control
item
hidden-inputAPI Reference
Arguments
| Name | Type | Default | Description |
|---|---|---|---|
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).checked | bool | RatingItemFlags::default() | 確定選択中(index == value)かどうか。aria-checked/data-checked へ反映する。 |
item(flags).highlighted | bool | — | 塗り表示対象(index <= display_value)かどうか。data-highlighted へ反映する(確定選択とは独立の軸)。 |
item(flags).readonly | bool | — | data-readonly を反映する。 |
item(aria_label) | &str | — | 呼び出し側が必須で与える国際化可能なラベル(例: "1 star")。フレームワーク側でハードコード生成しない。 |
hidden_input(name) | Option<&str> | — | Some のとき name 属性を出力する。 |
hidden_input(value_text) | &str | — | フォーム送信用の現在値 1 個(星群ではなく単一値)。 |
Data Attributes
| Part | Attribute | Observed Values |
|---|---|---|
item | data-checked | (値なし) |
item | data-highlighted | (値なし) |
item | data-value | 1, 2, 3 |
Examples
Read-only average rating
RatingGroupProps { readonly: true, .. } + RatingItemFlags { readonly: true, .. } の他ユーザー平均評価表示例。
Accessibility
WAI-ARIA
| Attribute | Description |
|---|---|
| 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")。 |