Files
nextjs-chat-gpt/components/chat/ChatInput.tsx
T

92 lines
2.7 KiB
TypeScript

'use client';
import type { ChatStatus } from 'ai';
import { RiAddLine } from '@remixicon/react';
import { ChatModelSelector } from './ChatModelSelector';
import type { OpenRouterModelId } from '@/lib/openrouter';
import {
PromptInput,
PromptInputActionAddAttachments,
PromptInputActionMenu,
PromptInputActionMenuContent,
PromptInputActionMenuTrigger,
PromptInputAttachment,
PromptInputAttachments,
PromptInputBody,
PromptInputFooter,
PromptInputHeader,
type PromptInputMessage,
PromptInputSubmit,
PromptInputTextarea,
PromptInputTools,
} from '@/components/ai-elements/prompt-input';
interface ChatInputProps {
value: string;
onChange: (value: string) => void;
onSubmit: (message: PromptInputMessage) => void;
modelId: OpenRouterModelId;
onModelChange: (modelId: OpenRouterModelId) => void;
onStop?: () => void;
status?: ChatStatus;
placeholder?: string;
}
export function ChatInput({
value,
onChange,
onSubmit,
modelId,
onModelChange,
onStop,
status = 'ready',
placeholder,
}: ChatInputProps) {
const isGenerating = status === 'submitted' || status === 'streaming';
return (
<PromptInput
className="[&_[data-slot=input-group]]:bg-background"
globalDrop
multiple
onSubmit={onSubmit}
>
<PromptInputHeader className="pt-1.5 pb-0">
<PromptInputAttachments className="gap-1.5 px-3 py-0">
{(attachment) => <PromptInputAttachment data={attachment} />}
</PromptInputAttachments>
</PromptInputHeader>
<PromptInputBody>
<PromptInputTextarea
className="min-h-10 py-2"
onChange={(event) => onChange(event.target.value)}
placeholder={placeholder}
value={value}
/>
</PromptInputBody>
<PromptInputFooter className="pt-0 pb-2">
<PromptInputTools className="min-w-0">
<PromptInputActionMenu>
<PromptInputActionMenuTrigger>
<RiAddLine className="size-4" />
</PromptInputActionMenuTrigger>
<PromptInputActionMenuContent>
<PromptInputActionAddAttachments />
</PromptInputActionMenuContent>
</PromptInputActionMenu>
<ChatModelSelector value={modelId} onChange={onModelChange} disabled={isGenerating} />
</PromptInputTools>
<PromptInputSubmit
aria-label={isGenerating ? 'Stop response' : 'Send message'}
type={isGenerating ? 'button' : 'submit'}
onClick={isGenerating ? onStop : undefined}
disabled={isGenerating && !onStop}
status={status}
/>
</PromptInputFooter>
</PromptInput>
);
}
export type { PromptInputMessage };