チャットコンポーザーChatComposerExperimental
チャット入力の前後に選択肢、作業コンテキスト、使用量、補助アクセサリを組み合わせる上位コンテナです。
プレビュー
状態とバリエーション
選択肢付き
AI やシステムからの選択肢を、入力欄の直前に配置します。
どの整理方針で進めますか?
作業状態付き
ブランチ、作業フォルダ、使用量など入力に関係する補助情報を、操作できる状態としてまとめます。
#24feature/insights-panel作業状態を選択できます。
アクセサリ付き
入力欄の周辺に装飾や補助状態を重ねます。入力本体の責務には含めません。
装飾や補助状態は accessory / footer slot に置きます。
プロパティ
表は横にスクロールできます
| プロパティ | 型 | 初期値 | 説明 |
|---|---|---|---|
| inputProps | ChatInputProps | - | 内側の ChatInput に渡す props です。 |
| context | React.ReactNode | - | 作業フォルダ、ブランチ、PR 状態などの入力コンテキストです。 |
| prompt | React.ReactNode | - | AI からの選択肢や、送信前に確認する質問です。 |
| status | React.ReactNode | - | リアルタイム補足状態などを入力欄の上に置くための領域です。 |
| footer | React.ReactNode | - | 使用量など、入力欄の下に置く補足表示です。 |
| accessory | React.ReactNode | - | 入力欄の周辺に重ねる補助 UI です。 |
使い方
import * as React from "react";
import { ChatComposer } from "@gunjo/ui";
export function ComposerWithChoices() {
const [selected, setSelected] = React.useState("hybrid");
const choices = [
{ id: "hybrid", label: "用途とタイプのハイブリッド" },
{ id: "file", label: "ファイルタイプで分ける" },
{ id: "date", label: "日付で分ける" },
{ id: "proposal", label: "まず提案だけ見たい" },
];
return (
<ChatComposer
prompt={
<div className="rounded-2xl border bg-background p-4 shadow-sm">
<div className="mb-3 flex items-center justify-between gap-3">
<p className="text-sm font-semibold">どの整理方針で進めますか?</p>
<button type="button" className="rounded-md px-2 py-1 text-sm hover:bg-muted">
スキップ
</button>
</div>
<div className="space-y-2">
{choices.map((choice, index) => (
<button
key={choice.id}
type="button"
onClick={() => setSelected(choice.id)}
className={`flex w-full items-center gap-3 rounded-xl border px-3 py-2 text-left text-sm transition-colors ${selected === choice.id ? "border-primary-border bg-primary-subtle text-foreground" : "border-border bg-muted/20 text-muted-foreground hover:bg-muted/40"}`}
>
<span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-background font-semibold">
{selected === choice.id ? "✓" : index + 1}
</span>
<span>{choice.label}</span>
</button>
))}
</div>
</div>
}
inputProps={{
onSend: (message, files) => console.log({ message, files }),
placeholder: "または直接返信...",
modelOptions: [
{ value: "auto", label: "自動", description: "内容に合わせて選択" },
{ value: "standard", label: "標準モデル", description: "通常の確認向け" },
{ value: "large", label: "大容量モデル", description: "長い文脈向け" },
{ value: "fast", label: "高速モデル", description: "短い確認向け" },
],
}}
/>
);
}使用コンポーネント
関連コンポーネント
設計の判断(UIXHERO)
「いつ・なぜ使うか」の判断は、姉妹サイト UIXHERO の記事で解説しています。