Input Group
入力欄の前後にテキスト・アイコン・ボタンなどの addon を配置する複合パターンです。root / addon / text / button の 4 パーツで構成され、実際の <input>/<textarea> は Field の input/textarea を呼び出し側が子として合成します。
addon は data-align 属性(inline-start / inline-end / block-start / block-end)で配置位置を表現します。inline-* は <input> の前後、block-* は <textarea> の上下に addon を置く用途を想定しています。
fandhe-frontend-headless-ui の input_group mod が提供する構造・アクセシビリティ(WAI-ARIA・キーボード操作)・表示状態(data-*)のみを持つ unstyled 部品です。fandhe-frontend-pre-styled-ui に対応するスタイル済み部品があります。Themes 版は Input Group を参照してください。
関連 API: fandhe-frontend-headless-ui API
Demo
枠線・余白は docs サイト側のデモ枠であり、fandhe-frontend-headless-ui 自体はスタイルを持ちません。
Features
- root(role="group")/addon/text/button の 4 パーツで、入力欄の前後にテキスト・アイコン・ボタンを配置する(shadcn/ui の Input Group 相当、input_group.rs モジュール doc)。
- 実際の <input>/<textarea> は本モジュールが出力せず、呼び出し側が crate::field の input/textarea を root の子として合成する契約(
.claude/rules/coding-rust.md§UI 部品の責務境界 規則 1、input_group.rs:8-16)。 - addon は data-align(inline-start/inline-end/block-start/block-end の 4 値)で配置を表す。inline-* は <input> の前後、block-* は <textarea> の上下を想定する(input_group.rs:107-131)。
- merge_field_props は disabled・invalid の双方を OR 伝播する。fieldset::FieldsetProps と異なり invalid も伝播する理由は「1 group = 1 control」の構造(1 つのコントロールを addon で装飾する)であるため(input_group.rs:95-105)。
- addon に role="group" は重ねない(root が既に role="group" を持つため、入れ子のグループを支援技術へ伝えない、input_group.rs モジュール doc「参考サイトとの意図的な差分」節)。
- button は type="button" を固定し、フォームの暗黙送信を起こさない(input_group.rs:195-213)。
Anatomy
root
addon
text
buttonAPI Reference
Arguments
| Name | Type | Default | Description |
|---|---|---|---|
props.disabled | bool | false | true のとき root/addon/button へ data-disabled を付与する(input_group.rs:83-85)。 |
props.invalid | bool | false | true のとき root へ aria-invalid="true"・data-invalid、addon へも data-invalid を付与する(input_group.rs:86-89, 150-170)。 |
merge_field_props(field) | FieldProps -> FieldProps | — | Input Group の disabled・invalid を内包する FieldProps へ OR 伝播する(input_group.rs:95-105)。 |
addon(align, props, attrs, children) | InputGroupAlign, &InputGroupProps, ... | — | align は inline-start/inline-end/block-start/block-end の 4 値(既定 inline-start、input_group.rs:107-131)。 |
text(attrs, children) | Vec<(&str, &str)>, Vec<Node> | — | addon 内の可視テキストラベル(span)。aria-label は付与しない(input_group.rs:181-186)。 |
attrs / children | Vec<(&str, &str)> / Vec<Node> | — | 各パーツ共通の追加属性・子ノード(代表 1 行に集約)。 |
Data Attributes
| Part | Attribute | Observed Values |
|---|---|---|
addon | data-align | block-end, block-start, inline-end, inline-start |
addon | data-disabled | (値なし) |
addon | data-invalid | (値なし) |
root | data-disabled | (値なし) |
root | data-invalid | (値なし) |
Examples
Invalid + field::input の合成例
invalid な Input Group と field::input の合成例です。
invalid な Input Group と field::input の合成例です。merge_field_props により field::input 側にも aria-invalid/data-invalid が反映されます。
自前 CSS の最小例
data-scope / data-part / data-align / data-invalid 属性セレクタで見た目を組み立てる最小例です。
利用者が data-scope / data-part / data-align / data-invalid 属性セレクタで自前 CSS を当てる最小例です。headless-ui 自体はスタイルを持ちません。
[data-scope="input-group"][data-part="root"] {
display: flex;
border: 1px solid #888;
border-radius: 4px;
}
[data-scope="input-group"][data-part="addon"] {
padding: 0 0.5rem;
background: #f3f4f6;
}
[data-scope="input-group"][data-part="root"][data-invalid] {
border-color: #dc2626;
}
Accessibility
Keyboard Interactions
| Key | Description |
|---|---|
| Tab | Input Group 自体は独自のキー操作を持たない。addon 内の button・root の子として合成された input/textarea 間の移動はネイティブの Tab 順に従う(input_group.rs モジュール doc「参考サイトとの意図的な差分」節: addon クリックで input へフォーカス移動する JS 配線は wasm-full 側の後続責務のためスコープ外)。 |
WAI-ARIA
| Attribute | Description |
|---|---|
| role="group" | root パーツへ固定付与する(input_group.rs:139-149)。 |
| aria-invalid="true" | invalid のとき root パーツへ付与する(input_group.rs:150-151)。addon/input 個別への aria-labelledby/aria-describedby は付与しない(名前付けは field::label、補足説明は field::helper_text/error_text が担う契約、input_group.rs モジュール doc「ラベル付け・説明の契約」節)。 |