チャット入力ChatInputExperimental
メッセージ入力、添付、送信、停止、無効化理由をまとめて扱うチャット用の入力欄です。
プレビュー
状態とバリエーション
標準表示
1つの入力エリア内に、添付プレビュー、枠なしの複数行入力、下段ツールバーをまとめます。
処理中
送信中は停止ボタンに切り替え、入力を一時停止します。
無効化理由
送信できない理由はボタンのツールチップで伝えます。
AI からの選択肢
AI から提示された選択肢は ChatInput ではなく、ChatComposer の prompt として扱います。
どの整理方針で進めますか?
作業コンテキスト付き
現在のブランチ、作業フォルダ、ワークツリー状態などは ChatComposer の context としてまとめます。
#24feature/insights-panel作業状態を選択できます。
使用量とモデル状態
使用量は ChatComposer の footer で独立して表示し、モデル選択は ChatInput 側に残します。
入力ペット付き
補助キャラクターは装飾・状態通知なので、ChatInput の外側に重ねて配置します。
補助キャラクターは装飾・状態通知なので、ChatComposer の accessory として配置します。
プロパティ
表は横にスクロールできます
| プロパティ | 型 | 初期値 | 説明 |
|---|---|---|---|
| onSend | (message: string, files?: File[]) => void | - | 送信時に呼び出されるコールバックです。 |
| onStop | () => void | - | 処理中の停止操作で呼び出します。 |
| isProcessing | boolean | false | 送信中・生成中の状態を表します。 |
| enableAttachments | boolean | true | 添付ボタンを表示するかを指定します。 |
| modelLabel | React.ReactNode | "自動" | 下段右側のモデル表示です。 |
| optionsContent | React.ReactNode | - | 入力オプションボタンから開くポップオーバー内容です。 |
| modelOptions | ChatInputModelOption[] | - | モデルボタンから選択できる候補です。 |
| toolbarAccessory | React.ReactNode | - | モデル選択の右横に置く補助操作です。使用量など、モデルとは別の状態をアイコンで表示できます。 |
| voiceActive | boolean | false | 音声認識の録音中状態を外部から制御する場合に指定します。 |
| showOptionsButton / showModelSelector / showVoiceButton | boolean | true | 下段ツールバーの補助操作を表示するかを指定します。入力オプションは optionsContent または onOptionsClick がある場合だけ表示されます。 |
| labels | ChatInputLabels | - | ツールチップと無効化理由の文言を指定します。 |
使い方
import * as React from "react";
import { ChatInput, Switch } from "@gunjo/ui";
export function SupportComposer() {
const [isProcessing, setIsProcessing] = React.useState(false);
const [model, setModel] = React.useState("auto");
const [webSearch, setWebSearch] = React.useState(true);
const [imageContext, setImageContext] = React.useState(false);
const modelOptions = [
{ value: "auto", label: "自動", description: "内容に合わせて選択" },
{ value: "fast", label: "高速", description: "短い返答を優先" },
{ value: "deep", label: "推論", description: "複雑な確認向け" },
];
return (
<ChatInput
onSend={(message, files) => {
setIsProcessing(true);
console.log({ message, files });
}}
onStop={() => setIsProcessing(false)}
isProcessing={isProcessing}
placeholder="確認したい内容を入力..."
optionsContent={
<div className="space-y-3">
<p className="text-sm font-semibold">入力オプション</p>
<label className="flex items-center justify-between gap-3 rounded-md border px-3 py-2 text-sm">
<span>Web を参照</span>
<Switch checked={webSearch} onCheckedChange={setWebSearch} />
</label>
<label className="flex items-center justify-between gap-3 rounded-md border px-3 py-2 text-sm">
<span>画像を参照</span>
<Switch checked={imageContext} onCheckedChange={setImageContext} />
</label>
</div>
}
modelOptions={modelOptions}
modelValue={model}
onModelValueChange={setModel}
labels={{
attach: "ファイルを添付",
options: "入力オプション",
model: "モデルを選択",
voice: "音声入力",
voiceActive: "録音を停止",
send: "送信",
stop: "停止",
removeAttachment: "添付を削除",
emptyMessage: "メッセージを入力すると送信できます。",
}}
/>
);
}使用コンポーネント
関連コンポーネント
設計の判断(UIXHERO)
「いつ・なぜ使うか」の判断は、姉妹サイト UIXHERO の記事で解説しています。