Field
ラベル・入力・説明・エラーメッセージを合成するフィールドコンポーネント群。id・htmlFor・aria-describedbyを自動配線する。
インポート
個別サブパス(バンドルサイズを抑えたい場合):
合成API(実際のProps構成)
Field は label / required / error / description のような単一propsは受け取りません。
FieldLabel / FieldControl / FieldDescription / FieldError を子要素として合成します。
Field は React.useId() ベースの内部contextを持ち、以下を自動配線します(明示指定があればそちらを優先):
| サブコンポーネント | 自動配線される内容 |
|---|---|
FieldLabel | htmlFor(FieldControlのidと一致) |
FieldControl | id・aria-describedby(FieldDescription・FieldErrorのidを参照) |
FieldDescription | id |
FieldError | id。children が空の場合は描画されない(FormMessageと同様のガード) |
FieldControl はRadixの Slot を使った合成コンポーネントです。Input / Textarea / CommandCombobox など、単一のフォームコントロール要素を子に1つ渡してください。
基本的な使い方
必須マーク付き
required propは無いため、FieldLabel の中に直接マークを書きます。
エラー状態
FieldError を子要素として置くだけで、FieldControl の aria-describedby に自動的に紐付きます。
実際に赤枠を出すには Input 側に aria-invalid を渡してください(FieldControl はaria-invalidを自動判定しません)。
ヘルプテキスト付き
horizontal レイアウト
orientation="horizontal" と FieldContent(ラベル+説明のグループ)を組み合わせます。
FieldGroup / FieldSet でまとめる
react-hook-formと組み合わせる場合
react-hook-formを使う場合は Field ではなく Form(FormItem / FormLabel / FormControl / FormDescription / FormMessage)を使用してください。Field はreact-hook-form非依存の軽量な合成コンポーネントです。
明示指定での上書き
htmlFor / id を明示的に渡すと自動配線より優先されます。複数のコントロールを1つの Field に置く場合など、自動採番では対応できないケースで使用します。
FieldControlの子要素が独自idを持つ場合
FieldControl は Slot(@radix-ui/react-slot)合成のため、子要素側が独自の id を持っている場合はそちらがDOMへ反映されます(Radixの仕様上、通常propsは子側の値が優先されます)。FieldControl はこの子要素のidを自動検出し、FieldLabel の htmlFor にも同じidを配線するため、以下のように書いても食い違いは起きません。
ただし FieldControl に渡した id prop(<FieldControl id="...">)は、子要素が独自の id を持つ場合はDOMに反映されません(子のidが優先されるため)。両方に異なるidを指定すると意図が伝わりにくいので、子要素にidを渡すか、FieldControl にidを渡すかのどちらか一方に統一することを推奨します。
SSR / 初回描画時の制約
FieldLabel の htmlFor は、FieldControl の存在・idをReactの useEffect を通じて検知しています。useEffect はマウント後(クライアント側のコミット後)にしか実行されないため、FieldLabel を FieldControl より先に描画する一般的な順序(Label→Control)では、サーバーサイドレンダリング(SSR)の出力・クライアント側の初回コミット時点では htmlFor が付与されません。クライアント側で1回再レンダーされた後(通常は次のフレーム内)に付与されます。
- 影響: SSR出力やハイドレーション前の一瞬だけ、ラベルクリックで対応する入力欄へフォーカスが移動しない・スクリーンリーダーがラベルと入力欄の関連付けを認識しない、という状態が起こり得ます
htmlFor/idを明示指定した場合(上記「明示指定での上書き」参照)はこの制約を受けません。アクセシビリティを初回描画から保証したい場合はhtmlFor/idを明示的に指定してください- 自動配線(明示指定なし)は、通常のクライアントサイド操作では実用上問題になりませんが、SSR結果をそのまま検証するテストやLighthouse等の初回描画時点でのa11y監査では検出される場合があります
Props
Field
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'vertical' | 'horizontal' | 'vertical' | レイアウト方向 |
id | string | - | 内部contextのベースid。未指定時はReact.useId()で自動生成される |
FieldLabel
| Prop | Type | Default | Description |
|---|---|---|---|
htmlFor | string | - | 関連付けるコントロールのid。未指定時はFieldContextから自動配線される |
FieldControl
Slot合成コンポーネント(asChild前提)。単一の子要素(Input・Textarea・CommandCombobox等)に id / aria-describedby を配線します。
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | - | 子要素のid。未指定時はFieldContextから自動配線される |
FieldDescription / FieldError
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | - | 未指定時はFieldContextから自動配線される |
children | ReactNode | - | FieldErrorはchildrenが空(null/undefined/空文字)の場合、何も描画しない |
FieldSet / FieldLegend / FieldGroup / FieldContent
見た目とセマンティクスのみを提供するラッパーです。固有のPropsはありません(className 以外は標準のHTML属性をそのまま受け取ります)。