UNPKG

@aichatkit/ui

Version:

Composable chat UI components for AI powered apps

539 lines (445 loc) 11.3 kB
# @aichatkit/ui React components for building chat interfaces with Hypermode ChatKit and rich response items. ## Installation ```bash npm install @aichatkit/ui ``` ## Quick Start ```tsx import "@aichatkit/ui/dist/base.css" import { ChatInterface, Avatar } from "@aichatkit/ui" import { ApolloAdapter } from "@aichatkit/apollo-adapter" import { LocalStorageAdapter } from "@aichatkit/localstorage-adapter" import { SendIcon, PlusIcon, XIcon } from "lucide-react" // Initialize adapters const networkAdapter = new ApolloAdapter({ apiUrl: "https://your-api.com/graphql", }) const storageAdapter = new LocalStorageAdapter() await storageAdapter.initialize() // Connect storage with network for syncing storageAdapter.setNetworkCallbacks({ getConversationItems: (agentId) => networkAdapter.getConversationItems(agentId), clearConversationHistory: (agentId) => networkAdapter.clearConversationHistory(agentId), }) // Use the chat interface function ChatApp() { return ( <ChatInterface networkAdapter={networkAdapter} storageAdapter={storageAdapter} hypermodeStyle={true} sendButtonIcon={<SendIcon size={18} />} newConversationIcon={<PlusIcon size={18} />} deleteConversationIcon={<XIcon size={16} />} userAvatar={<Avatar initial="U" role="user" hypermodeStyle={true} />} assistantAvatar={<Avatar initial="A" hypermodeStyle={true} />} onCardAction={(action) => { // Handle card button clicks console.log("Card action:", action) }} /> ) } ``` ## Components ### Main Components #### ChatInterface Complete chat interface with messages, input, sidebar, and rich response items. ```tsx interface ChatInterfaceProps { networkAdapter?: NetworkAdapter storageAdapter?: StorageAdapter showSidebar?: boolean className?: string chatAreaClassName?: string sidebarClassName?: string inputAreaClassName?: string headerClassName?: string headerContent?: ReactNode sidebarHeaderContent?: ReactNode userProfileContent?: ReactNode username?: string inputPlaceholder?: string sendButtonIcon?: ReactNode newConversationIcon?: ReactNode deleteConversationIcon?: ReactNode hypermodeStyle?: boolean userAvatar?: ReactNode assistantAvatar?: ReactNode onCardAction?: (action: CardAction) => void } ``` #### ResponseItem Displays different types of response items including messages, tool calls, and cards. ```tsx <ResponseItem item={{ id: "tool_1", type: "tool_call", toolCall: { id: "call_1", name: "get_weather", arguments: { location: "NYC" }, status: "completed", result: { temperature: "22°C" }, }, }} hypermodeStyle={true} /> ``` #### ChatBubble Individual message bubble component. ```tsx <ChatBubble content="Hello world!" role="user" timestamp={new Date()} hypermodeStyle={true} avatar={<Avatar initial="U" role="user" />} /> ``` #### ToolCallDisplay Displays tool execution with status, arguments, and results. ```tsx <ToolCallDisplay toolCall={{ id: "call_1", name: "get_weather", arguments: { location: "New York" }, status: "completed", result: { temperature: "22°C", condition: "Sunny" }, }} hypermodeStyle={true} /> ``` #### CardDisplay Rich content cards with structured data and interactive actions. ```tsx <CardDisplay card={{ id: "weather_card", type: "weather", title: "Weather Information", content: { location: "New York", temperature: "22°C" }, actions: [ { id: "forecast", label: "View Forecast", type: "button", action: "show_forecast", }, ], }} onAction={(action) => console.log("Action:", action)} hypermodeStyle={true} /> ``` #### ChatSidebar Sidebar for displaying and managing conversations. ```tsx <ChatSidebar conversations={conversations} currentConversationId={currentId} onCreateConversation={handleCreate} onDeleteConversation={handleDelete} onSelectConversation={handleSelect} username="User" hypermodeStyle={true} /> ``` #### LoadingIndicator Loading animation for messages and processing states. ```tsx <LoadingIndicator dots={3} /> <LoadingChatBubble hypermodeStyle={true} /> ``` ### UI Components #### Avatar User or assistant avatar component. ```tsx <Avatar initial="U" role="user" size="md" hypermodeStyle={true} /> ``` Props: - `initial`: String - The initial to display - `role`: 'user' | 'assistant' - The role of the user - `size`: 'sm' | 'md' | 'lg' - Size of the avatar - `hypermodeStyle`: boolean - Whether to use Hypermode styling #### Button Reusable button component with variants. ```tsx <Button variant="primary" size="default" onClick={handleClick}> Click me </Button> ``` Variants: - `primary` - Primary action button - `secondary` - Secondary action button - `ghost` - Minimal styling - `destructive` - For dangerous actions - `warning` - Warning actions #### Input Text input field component. ```tsx <Input type="text" placeholder="Type a message..." value={value} onChange={handleChange} /> ``` ## Response Item Types The UI components support various response item types: ### Message Items Standard chat messages between user and assistant. ```tsx { id: "msg_123", type: "message", content: "Hello there!", role: "assistant", timestamp: "2024-01-01T00:00:00Z" } ``` ### Tool Call Items Displays tool executions with arguments, status, and results. ```tsx { id: "tool_123", type: "tool_call", toolCall: { id: "call_123", name: "get_weather", arguments: { location: "New York" }, status: "completed", result: { temperature: "22°C", condition: "Sunny" } } } ``` ### Card Items Rich content cards with structured data and actions. ```tsx { id: "card_123", type: "card", card: { id: "weather_card", type: "weather", title: "Weather Information", content: { location: "New York", temperature: "22°C" }, actions: [ { id: "view_forecast", label: "View Forecast", type: "button", action: "show_forecast" } ] } } ``` ## Styling The components support two styling modes: ### 1. Default Style Clean, neutral design with light/dark mode support using CSS custom properties. ### 2. Hypermode Style Dark mode with purple accents designed for AI applications. Enable Hypermode styling by setting `hypermodeStyle={true}` on components: ```tsx <ChatInterface hypermodeStyle={true} /> <ChatBubble hypermodeStyle={true} /> <ToolCallDisplay hypermodeStyle={true} /> <CardDisplay hypermodeStyle={true} /> <Avatar hypermodeStyle={true} /> ``` ### CSS Import Include the base styles in your application: ```tsx // Import styles directly import "@aichatkit/ui/dist/base.css" // Or use the path constant import { CHATKIT_CSS_PATH } from "@aichatkit/ui" ``` ### Tailwind CSS Integration If using Tailwind CSS, add the component paths to your content configuration: ```js // tailwind.config.js module.exports = { content: [ // ... your content "node_modules/@aichatkit/ui/dist/**/*.{js,ts,jsx,tsx}", ], theme: { extend: { colors: { hypermode: { bg: "#121212", card: "#1c1c1c", border: "#2a2a2a", hover: "#282828", input: "#222222", accent: "#9333ea", "accent-light": "#a855f7", }, }, }, }, plugins: [], } ``` ## Advanced Usage ### Custom Avatars ```tsx import { User, Bot } from "lucide-react" ;<ChatInterface userAvatar={ <div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center"> <User size={16} className="text-white" /> </div> } assistantAvatar={ <div className="w-8 h-8 bg-purple-500 rounded-full flex items-center justify-center"> <Bot size={16} className="text-white" /> </div> } /> ``` ### Custom Header ```tsx <ChatInterface headerContent={ <div className="p-4 border-b flex items-center justify-between"> <h1>My AI Assistant</h1> <button>Settings</button> </div> } /> ``` ### Card Action Handling ```tsx <ChatInterface onCardAction={(action) => { switch (action.action) { case "show_forecast": // Handle forecast action showForecast(action.data?.location) break case "search_web": // Handle web search performSearch(action.data?.query) break default: if (action.type === "link") { window.open(action.action, "_blank") } } }} /> ``` ### Custom Text Area Replace the default input with a custom text area using the inputAreaContent prop: ```tsx <ChatInterface networkAdapter={networkAdapter} storageAdapter={storageAdapter} inputAreaContent={(context) => ( <div className="border-t p-4 bg-white"> <div className="flex items-end gap-2"> <textarea value={context.input} onChange={(e) => context.setInput(e.target.value)} placeholder={context.inputPlaceholder} className="flex-1 max-h-32 min-h-[40px] resize-none rounded-lg border border-gray-300 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault() context.sendMessage(context.input) context.setInput("") } }} /> <Button onClick={() => { context.sendMessage(context.input) context.setInput("") }} disabled={context.loading || !context.input.trim()} > {context.sendButtonIcon} </Button> </div> </div> )} /> ``` ### Handling Different Response Items ```tsx import { ResponseItemList } from "@aichatkit/ui" function CustomChatArea({ items }) { return ( <ResponseItemList items={items} hypermodeStyle={true} onCardAction={(action) => { // Handle card actions console.log("Card action:", action) }} userAvatar={<Avatar initial="U" role="user" hypermodeStyle={true} />} assistantAvatar={<Avatar initial="A" hypermodeStyle={true} />} /> ) } ``` ## TypeScript The package includes comprehensive TypeScript definitions: ```tsx import type { ChatResponseItem, Message, Conversation, ChatInterfaceProps, ToolCall, Card, CardAction, } from "@aichatkit/ui" const toolCall: ToolCall = { id: "call_1", name: "get_weather", arguments: { location: "NYC" }, status: "completed", result: { temperature: "22°C" }, } const card: Card = { id: "weather_card", type: "weather", title: "Weather Info", content: { temperature: "22°C" }, actions: [ { id: "forecast", label: "View Forecast", type: "button", action: "show_forecast", }, ], } const conversation: Conversation = { id: "conv-1", title: "Chat with AI", items: [ { id: "msg_1", type: "message", content: "Hello", role: "user", }, { id: "tool_1", type: "tool_call", toolCall: toolCall, }, { id: "card_1", type: "card", card: card, }, ], } ``` ## License [MIT](../../LICENSE) © Hypermode