Select
fandhe-frontend-headless-ui の select mod が提供するリストボックス選択の unstyled 部品です。Root / Label / Control / Trigger / ValueText / ClearTrigger / Indicator / Positioner / Content / ItemGroup / ItemGroupLabel / Item / ItemText / ItemIndicator / HiddenSelect の 15 anatomy パーツを持ち、listbox の開閉と選択値(高々 1 個)を合成した状態機械を備えます。HiddenSelect はフォーム統合専用のネイティブ <select> です。
/themes/ 側の Select(Chakra ライクな variant/size を持つスタイル層)と異なり、CSS を一切持ちません。
スタイル済みの表示例は Select を参照してください。
関連 API: fandhe-frontend-headless-ui API
Demo
枠線・余白は docs サイト側のデモ枠であり、fandhe-frontend-headless-ui 自体はスタイルを持ちません。
Common
Apple✓
Features
- Root / Label / Control / Trigger / ValueText / ClearTrigger / Indicator / Positioner / Content / ItemGroup / ItemGroupLabel / Item / ItemText / ItemIndicator / HiddenSelect の 15 anatomy パーツを提供する。
- listbox の開閉(`Disclosure`)+ 選択値(`SingleSelect`、高々 1 個)を合成した状態機械を持つ。`data-state` 値語彙は `crate::state::OpenState` の `"open"`/`"closed"` に一元化し、選択有無の表現にも同じ語彙を再利用する(ark-ui の `checked`/`unchecked` は不採用)。
- `hidden_select` はフォーム統合専用のネイティブ `<select>` であり `aria-hidden="true"` + `tabindex="-1"` を固定付与して視覚 UI(`trigger`/`content`)との二重露出を防ぐ。未選択時は非表示 placeholder option を自動挿入し、ブラウザの「先頭 option 自動選択」による誤送信を防ぐ。
- 位置決め(`positioner` の `style`/`data-side`/`data-align`)は `crate::positioning`(#590)が算出した値を呼び出し側が渡す。Select は arrow を持たない。
- highlight 移動・typeahead・キーボードナビゲーション自体は CSR 挙動層のスコープであり、本モジュールは `item(highlighted)`/`content(activedescendant)` の SSR 静的表現のみを提供する。
Anatomy
root
label
control
trigger
value-text
indicator
clear-trigger
positioner
content
item-group
item-group-label
item
item-text
item-indicator
hidden-selectAPI Reference
Arguments
| Name | Type | Default | Description |
|---|---|---|---|
| root/control/trigger/indicator/positioner/content/item/item_indicator(state) | OpenState | OpenState::Closed | 開閉(または選択有無)状態。`data-state` へ反映する。 |
| label/item_group_label(id) | Option<&str> | `Some` のとき `id` 属性を出力し、対応する `labelledby`/`labelled_by` 引数の関連付け先になる。 | |
| trigger(disabled) | bool | ネイティブ `disabled` + `data-disabled` を反映する。 | |
| trigger(controls) | Option<&str> | `Some` のとき `aria-controls` で `content` の id と関連付ける。 | |
| trigger(labelledby) | Option<&str> | `Some` のとき `aria-labelledby` で `label` と関連付ける。 | |
| value_text(placeholder_shown) | bool | `true` のとき `data-placeholder-shown` 存在属性を付与する(未選択時のプレースホルダー表示)。 | |
| content(id) | Option<&str> | `trigger(controls)` の参照先 id。 | |
| content(labelledby) | Option<&str> | `Some` のとき `aria-labelledby` を付与する。 | |
| content(activedescendant) | Option<&str> | `Some` のとき `aria-activedescendant` を付与する(現在ハイライト中の `item` の id を指す。移動自体は CSR 挙動層の責務)。 | |
| item_group(labelledby) | Option<&str> | `Some` のときのみ `role="group"` + `aria-labelledby` を対で付与する(名前なし group を作らない)。 | |
| item(disabled) | bool | `true` のとき `aria-disabled="true"` + `data-disabled` を対で付与する(`div[role="option"]` はネイティブ `disabled` を持たない)。 | |
| item(highlighted) | bool | `data-highlighted` へ反映する(キーボードナビゲーション等によるフォーカス位置の SSR 静的表現)。 | |
| item(value) | &str | 選択肢の値。`data-value` として動的値のまま出力する。 | |
| item(id) | Option<&str> | `Some` のとき、`content(activedescendant)` の参照先識別子になる。 | |
| hidden_select(selected) | Option<&str> | 現在選択中の値。`None` のとき非表示 placeholder option を先頭へ自動挿入する。 | |
| hidden_select(name) | Option<&str> | `Some` のとき `name` 属性を出力する。 | |
| hidden_select(options) | Vec<(&str, &str)> | `(value, label)` の列。各要素を `<option>` として組み立てる。 |
Data Attributes
| Part | Attribute | Observed Values |
|---|---|---|
| content | data-state | open |
| control | data-state | open |
| indicator | data-state | open |
| item | data-highlighted | |
| item | data-state | open |
| item | data-value | apple |
| item-indicator | data-state | open |
| positioner | data-state | open |
| root | data-state | open |
| trigger | data-state | open |
| value-text | data-bind-text | select-value-text |
Examples
Disabled trigger, unselected
`trigger(disabled: true)` + `hidden_select(selected: None)` の未選択・無効化状態。非表示 placeholder option が自動挿入される。
Japan✓
Accessibility
WAI-ARIA
| Attribute | Description |
|---|---|
| aria-haspopup="listbox" (trigger) | 固定付与。 |
| aria-expanded (trigger) | `state.is_open()` を反映する。 |
| role="listbox" (content) | 固定付与。`aria-activedescendant` の配線先(`trigger` は素の `button` のため付与しない)。 |
| role="option" / aria-selected (item) | 固定付与 + `selected_state.is_open()` を反映する。 |
| aria-hidden="true" / tabindex="-1" (hidden_select) | 視覚 UI(`trigger`/`content`)との二重露出・二重フォーカスを防ぐため固定付与する。 |