mirror of
https://github.com/run-llama/chat-ui.git
synced 2026-07-21 11:25:22 -04:00
docs: update document for chat-ui (#102)
--------- Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'web': patch
|
||||
'@llamaindex/chat-ui-docs': patch
|
||||
---
|
||||
|
||||
docs: update documentation
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
useFile,
|
||||
} from '@llamaindex/chat-ui'
|
||||
import { Message, useChat } from 'ai/react'
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
|
||||
const code = `
|
||||
import {
|
||||
@@ -21,6 +22,7 @@ import {
|
||||
useFile,
|
||||
} from '@llamaindex/chat-ui'
|
||||
import { useChat } from 'ai/react'
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
|
||||
export function CustomChat() {
|
||||
const handler = useChat()
|
||||
@@ -68,29 +70,38 @@ function CustomChatMessages() {
|
||||
const { messages, isLoading, append } = useChatUI()
|
||||
return (
|
||||
<ChatMessages>
|
||||
<ChatMessages.List>
|
||||
{messages.map((message, index) => (
|
||||
<ChatMessage
|
||||
key={index}
|
||||
message={message}
|
||||
isLast={index === messages.length - 1}
|
||||
className="items-start"
|
||||
>
|
||||
<ChatMessage.Avatar>
|
||||
<img
|
||||
className="border-1 rounded-full border-[#e711dd]"
|
||||
alt="LlamaIndex"
|
||||
src="/llama.png"
|
||||
/>
|
||||
</ChatMessage.Avatar>
|
||||
<ChatMessage.Content isLoading={isLoading} append={append}>
|
||||
<ChatMessage.Content.Image />
|
||||
<ChatMessage.Content.Markdown />
|
||||
<ChatMessage.Content.DocumentFile />
|
||||
</ChatMessage.Content>
|
||||
<ChatMessage.Actions />
|
||||
</ChatMessage>
|
||||
))}
|
||||
<ChatMessages.List className="px-0 md:px-16">
|
||||
<AnimatePresence>
|
||||
{messages.map((message, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
transition={{ duration: 0.3, delay: index * 0.1 }}
|
||||
>
|
||||
<ChatMessage
|
||||
message={message}
|
||||
isLast={index === messages.length - 1}
|
||||
className="items-start"
|
||||
>
|
||||
<ChatMessage.Avatar>
|
||||
<img
|
||||
className="border-1 rounded-full border-[#e711dd]"
|
||||
alt="LlamaIndex"
|
||||
src="/llama.png"
|
||||
/>
|
||||
</ChatMessage.Avatar>
|
||||
<ChatMessage.Content isLoading={isLoading} append={append}>
|
||||
<ChatMessage.Content.Image />
|
||||
<ChatMessage.Content.Markdown />
|
||||
<ChatMessage.Content.DocumentFile />
|
||||
</ChatMessage.Content>
|
||||
<ChatMessage.Actions />
|
||||
</ChatMessage>
|
||||
</motion.div>
|
||||
))}
|
||||
</AnimatePresence>
|
||||
</ChatMessages.List>
|
||||
</ChatMessages>
|
||||
)
|
||||
@@ -208,28 +219,37 @@ function CustomChatMessages() {
|
||||
return (
|
||||
<ChatMessages>
|
||||
<ChatMessages.List className="px-0 md:px-16">
|
||||
{messages.map((message, index) => (
|
||||
<ChatMessage
|
||||
key={index}
|
||||
message={message}
|
||||
isLast={index === messages.length - 1}
|
||||
className="items-start"
|
||||
>
|
||||
<ChatMessage.Avatar>
|
||||
<img
|
||||
className="border-1 rounded-full border-[#e711dd]"
|
||||
alt="LlamaIndex"
|
||||
src="/llama.png"
|
||||
/>
|
||||
</ChatMessage.Avatar>
|
||||
<ChatMessage.Content isLoading={isLoading} append={append}>
|
||||
<ChatMessage.Content.Image />
|
||||
<ChatMessage.Content.Markdown />
|
||||
<ChatMessage.Content.DocumentFile />
|
||||
</ChatMessage.Content>
|
||||
<ChatMessage.Actions />
|
||||
</ChatMessage>
|
||||
))}
|
||||
<AnimatePresence>
|
||||
{messages.map((message, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
transition={{ duration: 0.3, delay: index * 0.1 }}
|
||||
>
|
||||
<ChatMessage
|
||||
message={message}
|
||||
isLast={index === messages.length - 1}
|
||||
className="items-start"
|
||||
>
|
||||
<ChatMessage.Avatar>
|
||||
<img
|
||||
className="border-1 rounded-full border-[#e711dd]"
|
||||
alt="LlamaIndex"
|
||||
src="/llama.png"
|
||||
/>
|
||||
</ChatMessage.Avatar>
|
||||
<ChatMessage.Content isLoading={isLoading} append={append}>
|
||||
<ChatMessage.Content.Image />
|
||||
<ChatMessage.Content.Markdown />
|
||||
<ChatMessage.Content.DocumentFile />
|
||||
</ChatMessage.Content>
|
||||
<ChatMessage.Actions />
|
||||
</ChatMessage>
|
||||
</motion.div>
|
||||
))}
|
||||
</AnimatePresence>
|
||||
</ChatMessages.List>
|
||||
</ChatMessages>
|
||||
)
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"type-check": "tsc --noEmit",
|
||||
"registry:build": "rm -rf public/r && npx shadcn@latest build"
|
||||
"registry:build": "rm -rf public/r && npx shadcn@latest build && npm run registry:post-build",
|
||||
"registry:post-build": "node scripts/add-css-source.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"framer-motion": "^12.15.0",
|
||||
"@faker-js/faker": "^9.4.0",
|
||||
"@llamaindex/chat-ui": "workspace:*",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
|
||||
@@ -11,8 +11,11 @@
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/chat/chat.tsx",
|
||||
"content": "'use client'\r\n\r\nimport {\r\n ChatHandler,\r\n ChatSection as ChatSectionUI,\r\n Message,\r\n} from '@llamaindex/chat-ui'\r\n\r\nimport '@llamaindex/chat-ui/styles/markdown.css'\r\nimport { useState } from 'react'\r\n\r\nconst initialMessages: Message[] = [\r\n {\r\n content: 'Write simple Javascript hello world code',\r\n role: 'user',\r\n },\r\n {\r\n role: 'assistant',\r\n content:\r\n 'Got it! Here\\'s the simplest JavaScript code to print \"Hello, World!\" to the console:\\n\\n```javascript\\nconsole.log(\"Hello, World!\");\\n```\\n\\nYou can run this code in any JavaScript environment, such as a web browser\\'s console or a Node.js environment. Just paste the code and execute it to see the output.',\r\n },\r\n {\r\n content: 'Write a simple math equation',\r\n role: 'user',\r\n },\r\n {\r\n role: 'assistant',\r\n content:\r\n \"Let's explore a simple mathematical equation using LaTeX:\\n\\n The quadratic formula is: $$x = \\\\frac{-b \\\\pm \\\\sqrt{b^2 - 4ac}}{2a}$$\\n\\nThis formula helps us solve quadratic equations in the form $ax^2 + bx + c = 0$. The solution gives us the x-values where the parabola intersects the x-axis.\",\r\n },\r\n]\r\n\r\nexport function ChatSection() {\r\n // You can replace the handler with a useChat hook from Vercel AI SDK\r\n const handler = useMockChat(initialMessages)\r\n return (\r\n <div className=\"flex max-h-[80vh] flex-col gap-6 overflow-y-auto\">\r\n <ChatSectionUI handler={handler} />\r\n </div>\r\n )\r\n}\r\n\r\nfunction useMockChat(initMessages: Message[]): ChatHandler {\r\n const [messages, setMessages] = useState<Message[]>(initMessages)\r\n const [input, setInput] = useState('')\r\n const [isLoading, setIsLoading] = useState(false)\r\n\r\n const append = async (message: Message) => {\r\n setIsLoading(true)\r\n\r\n const mockResponse: Message = {\r\n role: 'assistant',\r\n content: '',\r\n }\r\n setMessages(prev => [...prev, message, mockResponse])\r\n\r\n const mockContent =\r\n 'This is a mock response. In a real implementation, this would be replaced with an actual AI response.'\r\n\r\n let streamedContent = ''\r\n const words = mockContent.split(' ')\r\n\r\n for (const word of words) {\r\n await new Promise(resolve => setTimeout(resolve, 100))\r\n streamedContent += (streamedContent ? ' ' : '') + word\r\n setMessages(prev => {\r\n return [\r\n ...prev.slice(0, -1),\r\n {\r\n role: 'assistant',\r\n content: streamedContent,\r\n },\r\n ]\r\n })\r\n }\r\n\r\n setIsLoading(false)\r\n return mockContent\r\n }\r\n\r\n return {\r\n messages,\r\n input,\r\n setInput,\r\n isLoading,\r\n append,\r\n }\r\n}\r\n",
|
||||
"content": "'use client'\r\n\r\nimport {\r\n ChatHandler,\r\n ChatSection as ChatSectionUI,\r\n Message,\r\n} from '@llamaindex/chat-ui'\r\n\r\nimport '@llamaindex/chat-ui/styles/markdown.css'\r\nimport '@llamaindex/chat-ui/styles/pdf.css'\r\nimport { useState } from 'react'\r\n\r\nconst initialMessages: Message[] = [\r\n {\r\n content: 'Write simple Javascript hello world code',\r\n role: 'user',\r\n },\r\n {\r\n role: 'assistant',\r\n content:\r\n 'Got it! Here\\'s the simplest JavaScript code to print \"Hello, World!\" to the console:\\n\\n```javascript\\nconsole.log(\"Hello, World!\");\\n```\\n\\nYou can run this code in any JavaScript environment, such as a web browser\\'s console or a Node.js environment. Just paste the code and execute it to see the output.',\r\n },\r\n {\r\n content: 'Write a simple math equation',\r\n role: 'user',\r\n },\r\n {\r\n role: 'assistant',\r\n content:\r\n \"Let's explore a simple mathematical equation using LaTeX:\\n\\n The quadratic formula is: $$x = \\\\frac{-b \\\\pm \\\\sqrt{b^2 - 4ac}}{2a}$$\\n\\nThis formula helps us solve quadratic equations in the form $ax^2 + bx + c = 0$. The solution gives us the x-values where the parabola intersects the x-axis.\",\r\n },\r\n]\r\n\r\nexport function ChatSection() {\r\n // You can replace the handler with a useChat hook from Vercel AI SDK\r\n const handler = useMockChat(initialMessages)\r\n return (\r\n <div className=\"flex max-h-[80vh] flex-col gap-6 overflow-y-auto\">\r\n <ChatSectionUI handler={handler} />\r\n </div>\r\n )\r\n}\r\n\r\nfunction useMockChat(initMessages: Message[]): ChatHandler {\r\n const [messages, setMessages] = useState<Message[]>(initMessages)\r\n const [input, setInput] = useState('')\r\n const [isLoading, setIsLoading] = useState(false)\r\n\r\n const append = async (message: Message) => {\r\n setIsLoading(true)\r\n\r\n const mockResponse: Message = {\r\n role: 'assistant',\r\n content: '',\r\n }\r\n setMessages(prev => [...prev, message, mockResponse])\r\n\r\n const mockContent =\r\n 'This is a mock response. In a real implementation, this would be replaced with an actual AI response.'\r\n\r\n let streamedContent = ''\r\n const words = mockContent.split(' ')\r\n\r\n for (const word of words) {\r\n await new Promise(resolve => setTimeout(resolve, 100))\r\n streamedContent += (streamedContent ? ' ' : '') + word\r\n setMessages(prev => {\r\n return [\r\n ...prev.slice(0, -1),\r\n {\r\n role: 'assistant',\r\n content: streamedContent,\r\n },\r\n ]\r\n })\r\n }\r\n\r\n setIsLoading(false)\r\n return mockContent\r\n }\r\n\r\n return {\r\n messages,\r\n input,\r\n setInput,\r\n isLoading,\r\n append,\r\n }\r\n}\r\n",
|
||||
"type": "registry:block"
|
||||
}
|
||||
]
|
||||
],
|
||||
"css": {
|
||||
"@source '../node_modules/@llamaindex/chat-ui/**/*.{ts,tsx}'": ""
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from '@llamaindex/chat-ui'
|
||||
|
||||
import '@llamaindex/chat-ui/styles/markdown.css'
|
||||
import '@llamaindex/chat-ui/styles/pdf.css'
|
||||
import { useState } from 'react'
|
||||
|
||||
const initialMessages: Message[] = [
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const registryPath = path.join(__dirname, '../public/r/chat.json')
|
||||
|
||||
try {
|
||||
// Read the built registry file
|
||||
const registryData = JSON.parse(fs.readFileSync(registryPath, 'utf8'))
|
||||
|
||||
// Add the CSS source directive
|
||||
registryData.css = {
|
||||
"@source '../node_modules/@llamaindex/chat-ui/**/*.{ts,tsx}'": '',
|
||||
}
|
||||
|
||||
// Write back the modified registry
|
||||
fs.writeFileSync(registryPath, JSON.stringify(registryData, null, 2))
|
||||
|
||||
console.log('✅ CSS source directive added to registry')
|
||||
} catch (error) {
|
||||
console.error('❌ Error modifying registry:', error.message)
|
||||
process.exit(1)
|
||||
}
|
||||
@@ -643,7 +643,7 @@ function createAnnotations(data: any) {
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Artifacts](./artifacts) - Learn about interactive code and document artifacts
|
||||
- [Widgets](./widgets) - Explore widget implementation details
|
||||
- [Examples](./examples) - See complete annotation examples
|
||||
- [Customization](./customization) - Style and customize annotation appearance
|
||||
- [Artifacts](./artifacts.mdx) - Learn about interactive code and document artifacts
|
||||
- [Widgets](./widgets.mdx) - Explore widget implementation details
|
||||
- [Examples](./examples.mdx) - See complete annotation examples
|
||||
- [Customization](./customization.mdx) - Style and customize annotation appearance
|
||||
|
||||
@@ -574,7 +574,7 @@ function CopyArtifact() {
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Examples](./examples) - See complete artifact implementations
|
||||
- [Customization](./customization) - Style and customize artifact appearance
|
||||
- [Widgets](./widgets) - Explore related widget functionality
|
||||
- [Annotations](./annotations) - Understand the annotation system
|
||||
- [Examples](./examples.mdx) - See complete artifact implementations
|
||||
- [Customization](./customization.mdx) - Style and customize artifact appearance
|
||||
- [Widgets](./widgets.mdx) - Explore related widget functionality
|
||||
- [Annotations](./annotations.mdx) - Understand the annotation system
|
||||
|
||||
@@ -417,7 +417,7 @@ function CustomComponent() {
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Widgets](./widgets) - Learn about specialized content widgets
|
||||
- [Annotations](./annotations) - Implement rich content support
|
||||
- [Hooks](./hooks) - Understand the hook system
|
||||
- [Customization](./customization) - Style and theme the components
|
||||
- [Widgets](./widgets.mdx) - Learn about specialized content widgets
|
||||
- [Annotations](./annotations.mdx) - Implement rich content support
|
||||
- [Hooks](./hooks.mdx) - Understand the hook system
|
||||
- [Customization](./customization.mdx) - Style and theme the components
|
||||
@@ -712,7 +712,7 @@ function AccessibleChat() {
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Examples](./examples) - See complete customization examples
|
||||
- [Core Components](./core-components) - Understand component structure for customization
|
||||
- [Widgets](./widgets) - Customize widget appearance and behavior
|
||||
- [Hooks](./hooks) - Use hooks for dynamic customization
|
||||
- [Examples](./examples.mdx) - See complete customization examples
|
||||
- [Core Components](./core-components.mdx) - Understand component structure for customization
|
||||
- [Widgets](./widgets.mdx) - Customize widget appearance and behavior
|
||||
- [Hooks](./hooks.mdx) - Use hooks for dynamic customization
|
||||
@@ -13,5 +13,5 @@ This section provides complete, working examples that demonstrate how to impleme
|
||||
|
||||
- Explore the [NextJS Example](https://github.com/run-llama/chat-ui/tree/main/examples/nextjs) in the repository
|
||||
- Check out the [FastAPI Example](https://github.com/run-llama/chat-ui/tree/main/examples/fastapi) for backend integration
|
||||
- Review the [Core Components](./core-components) documentation for detailed API references
|
||||
- See [Customization](./customization) for styling and theming options
|
||||
- Review the [Core Components](./core-components.mdx) documentation for detailed API references
|
||||
- See [Customization](./customization.mdx) for styling and theming options
|
||||
|
||||
@@ -5,39 +5,35 @@ description: Learn how to install and set up LlamaIndex Chat UI in your project
|
||||
|
||||
This guide will help you get started with LlamaIndex Chat UI, from installation to building your first chat interface.
|
||||
|
||||
## Quick Start
|
||||
## Installation
|
||||
|
||||
The fastest way to add a chatbot to your project is using the Shadcn CLI command:
|
||||
### Quick Start with Shadcn CLI
|
||||
|
||||
If you're using shadcn, then the fastest way to add a chatbot to your project is using the Shadcn CLI command:
|
||||
|
||||
```shell
|
||||
npx shadcn@latest add https://ui.llamaindex.ai/r/chat.json
|
||||
```
|
||||
|
||||
## Manual Installation
|
||||
**Note for React 19 users:** Select **"Use --force"** if asked and continue with the installation. This will resolve the peer dependency conflicts and allow the components to install properly.
|
||||
|
||||
Install the package using your preferred package manager:
|
||||
### Manual Installation
|
||||
|
||||
First, install the package using your preferred package manager:
|
||||
|
||||
```shell
|
||||
npm install @llamaindex/chat-ui
|
||||
npm install @llamaindex/chat-ui react react-dom
|
||||
|
||||
yarn add @llamaindex/chat-ui
|
||||
yarn add @llamaindex/chat-ui react react-dom
|
||||
|
||||
pnpm add @llamaindex/chat-ui
|
||||
pnpm add @llamaindex/chat-ui react react-dom
|
||||
|
||||
bun add @llamaindex/chat-ui
|
||||
bun add @llamaindex/chat-ui react react-dom
|
||||
```
|
||||
|
||||
## Peer Dependencies
|
||||
Then, you need to configure your styling with the following three steps:
|
||||
|
||||
Chat UI requires React 18+:
|
||||
|
||||
```shell
|
||||
npm install react react-dom
|
||||
```
|
||||
|
||||
## Basic Setup
|
||||
|
||||
### 1. Configure Tailwind CSS
|
||||
#### 1. Configure Tailwind CSS
|
||||
|
||||
**For Tailwind CSS version 4.x**, update `globals.css` to include the chat-ui components (update the relative path to node_modules if necessary):
|
||||
|
||||
@@ -58,7 +54,58 @@ module.exports = {
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Import Styles
|
||||
#### 2. Define theme:
|
||||
|
||||
Chat UI components use the same theming system as [shadcn/ui](https://ui.shadcn.com/), based on CSS custom properties.
|
||||
|
||||
**If you already have shadcn/ui set up with a theme in your project, you can skip this step** - Chat UI will automatically inherit your existing theme configuration.
|
||||
|
||||
**If you're not using shadcn/ui**, you need to define theme variables in your `app/globals.css` file to make Chat UI work properly. These CSS custom properties control colors, typography, spacing, and other visual aspects of the components.
|
||||
|
||||
##### Theme Generation
|
||||
|
||||
We recommend using [Shadcn Studio Theme Editor](https://shadcnstudio.com/theme-editor) to easily generate and customize your theme:
|
||||
|
||||
1. Visit [https://shadcnstudio.com/theme-editor](https://shadcnstudio.com/theme-editor)
|
||||
2. Select or customize a theme that matches your design
|
||||
3. Copy the generated CSS variables
|
||||
4. Add them to your `globals.css` file
|
||||
|
||||
##### Sample Configuration
|
||||
|
||||
Here's a complete example of `globals.css` after configuring Tailwind CSS and adding theme variables:
|
||||
|
||||
You can use this [sample globals.css file](./sample-globals.css) as a reference, or copy the following basic structure:
|
||||
|
||||
```css
|
||||
@import 'tailwindcss';
|
||||
@source '../node_modules/@llamaindex/chat-ui/**/*.{ts,tsx}';
|
||||
|
||||
:root {
|
||||
/* Theme variables - see sample file for complete configuration */
|
||||
--background: oklch(1 0 0);
|
||||
--foreground: oklch(0.14 0 285.86);
|
||||
/* ... other theme variables ... */
|
||||
}
|
||||
|
||||
.dark {
|
||||
/* Dark mode theme variables */
|
||||
--background: oklch(0.14 0 285.86);
|
||||
--foreground: oklch(0.99 0 0);
|
||||
/* ... other dark theme variables ... */
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
/* Theme mapping for Tailwind CSS */
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
/* ... other color mappings ... */
|
||||
}
|
||||
```
|
||||
|
||||
For a complete configuration with all theme variables, download and use the [full sample globals.css file](./sample-globals.css).
|
||||
|
||||
#### 3. Import Styles
|
||||
|
||||
Import the CSS styles in your app's root file (e.g., `_app.tsx` or `layout.tsx`):
|
||||
|
||||
@@ -69,7 +116,9 @@ import '@llamaindex/chat-ui/styles/pdf.css' // pdf styling
|
||||
|
||||
The `markdown.css` file includes styling for code blocks using [highlight.js](https://highlightjs.org/) with the `atom-one-dark` theme by default, [katex](https://katex.org/) for latex, and [pdf-viewer](https://github.com/run-llama/pdf-viewer) for PDF files. You can use any highlight.js theme by copying [their CSS](https://github.com/highlightjs/highlight.js/tree/main/src/styles/) to your project and importing it.
|
||||
|
||||
### 3. Create a Chat API Route
|
||||
## Basic Usage
|
||||
|
||||
### 1. Create a Chat API Route
|
||||
|
||||
Set up an API route to handle chat requests. Here's an example using Next.js:
|
||||
|
||||
@@ -92,7 +141,7 @@ export async function POST(request: Request) {
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Create Your Chat Component
|
||||
### 2. Create Your Chat Component
|
||||
|
||||
The easiest way to get started is to connect the whole `ChatSection` component with `useChat` hook from [vercel/ai](https://github.com/vercel/ai):
|
||||
|
||||
@@ -258,10 +307,10 @@ For any language that the LLM generates, you can specify a custom renderer to re
|
||||
|
||||
Now that you have a basic chat interface running:
|
||||
|
||||
1. **Explore Components** - Learn about [Core Components](./core-components) for customization
|
||||
2. **Add Rich Content** - Implement [Annotations](./annotations) for images, files, and sources
|
||||
3. **Enable Artifacts** - Set up [Artifacts](./artifacts) for interactive code and documents
|
||||
4. **Customize Styling** - Read the [Customization](./customization) guide for theming
|
||||
1. **Explore Components** - Learn about [Core Components](./core-components.mdx) for customization
|
||||
2. **Add Rich Content** - Implement [Annotations](./annotations.mdx) for images, files, and sources
|
||||
3. **Enable Artifacts** - Set up [Artifacts](./artifacts.mdx) for interactive code and documents
|
||||
4. **Customize Styling** - Read the [Customization](./customization.mdx) guide for theming
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -277,6 +326,6 @@ Now that you have a basic chat interface running:
|
||||
|
||||
### Getting Help
|
||||
|
||||
- Check the [Examples](./examples) for working implementations
|
||||
- Check the [Examples](./examples.mdx) for working implementations
|
||||
- Review the component documentation for detailed API references
|
||||
- Open an issue on GitHub for bugs or feature requests
|
||||
|
||||
@@ -498,7 +498,7 @@ function SafeHookUsage() {
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Annotations](./annotations) - Learn how hooks work with annotation data
|
||||
- [Customization](./customization) - Use hooks for custom styling and behavior
|
||||
- [Examples](./examples) - See complete examples using hooks
|
||||
- [Core Components](./core-components) - Understand component-hook relationships
|
||||
- [Annotations](./annotations.mdx) - Learn how hooks work with annotation data
|
||||
- [Customization](./customization.mdx) - Use hooks for custom styling and behavior
|
||||
- [Examples](./examples.mdx) - See complete examples using hooks
|
||||
- [Core Components](./core-components.mdx) - Understand component-hook relationships
|
||||
|
||||
+10
-10
@@ -34,14 +34,14 @@ The library includes a comprehensive widget system for handling various content
|
||||
|
||||
## Getting Started
|
||||
|
||||
The fastest way to add a chatbot to your project is using the Shadcn CLI command:
|
||||
|
||||
```shell
|
||||
npm install @llamaindex/chat-ui
|
||||
|
||||
yarn add @llamaindex/chat-ui
|
||||
|
||||
pnpm add @llamaindex/chat-ui
|
||||
npx shadcn@latest add https://ui.llamaindex.ai/r/chat.json
|
||||
```
|
||||
|
||||
For more information on configuration, please see detailed guide in [Getting Started](./getting-started.mdx).
|
||||
|
||||
## Quick Example
|
||||
|
||||
```tsx
|
||||
@@ -82,8 +82,8 @@ Chat UI is designed to work with any chat backend that implements Vercel's [Stre
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Getting Started](./getting-started) - Installation and basic setup
|
||||
- [Core Components](./core-components) - Detailed guide to main components
|
||||
- [Widgets](./widgets) - Comprehensive widget documentation
|
||||
- [Annotations](./annotations) - Working with rich content
|
||||
- [Examples](./examples) - Real-world implementation examples
|
||||
- [Getting Started](./getting-started.mdx) - Installation and basic setup
|
||||
- [Core Components](./core-components.mdx) - Detailed guide to main components
|
||||
- [Widgets](./widgets.mdx) - Comprehensive widget documentation
|
||||
- [Annotations](./annotations.mdx) - Working with rich content
|
||||
- [Examples](./examples.mdx) - Real-world implementation examples
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
@import "tailwindcss";
|
||||
@source '../node_modules/@llamaindex/chat-ui/**/*.{ts,tsx}';
|
||||
|
||||
:root {
|
||||
--background: oklch(1.00 0 0);
|
||||
--foreground: oklch(0.14 0.00 285.86);
|
||||
--card: oklch(1.00 0 0);
|
||||
--card-foreground: oklch(0.14 0.00 285.86);
|
||||
--popover: oklch(1.00 0 0);
|
||||
--popover-foreground: oklch(0.14 0.00 285.86);
|
||||
--primary: oklch(0.21 0.01 285.93);
|
||||
--primary-foreground: oklch(0.99 0 0);
|
||||
--secondary: oklch(0.97 0 0);
|
||||
--secondary-foreground: oklch(0.21 0.01 285.93);
|
||||
--muted: oklch(0.97 0 0);
|
||||
--muted-foreground: oklch(0.55 0.02 285.93);
|
||||
--accent: oklch(0.97 0 0);
|
||||
--accent-foreground: oklch(0.21 0.01 285.93);
|
||||
--destructive: oklch(0.58 0.24 28.48);
|
||||
--border: oklch(0.92 0.00 286.61);
|
||||
--input: oklch(0.92 0.00 286.61);
|
||||
--ring: oklch(0.71 0.01 286.09);
|
||||
--chart-1: oklch(0.65 0.22 36.85);
|
||||
--chart-2: oklch(0.60 0.11 184.15);
|
||||
--chart-3: oklch(0.40 0.07 227.18);
|
||||
--chart-4: oklch(0.83 0.17 81.03);
|
||||
--chart-5: oklch(0.77 0.17 65.36);
|
||||
--sidebar: oklch(0.99 0 0);
|
||||
--sidebar-foreground: oklch(0.14 0.00 285.86);
|
||||
--sidebar-primary: oklch(0.21 0.01 285.93);
|
||||
--sidebar-primary-foreground: oklch(0.99 0 0);
|
||||
--sidebar-accent: oklch(0.97 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.21 0.01 285.93);
|
||||
--sidebar-border: oklch(0.92 0.00 286.61);
|
||||
--sidebar-ring: oklch(0.71 0.01 286.09);
|
||||
|
||||
--font-sans: 'Geist', 'Geist Fallback', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
--font-serif: "Geist", "Geist Fallback", ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
||||
--font-mono: "Geist Mono", "Geist Mono Fallback", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
|
||||
--radius: 0.625rem;
|
||||
|
||||
--shadow-2xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05);
|
||||
--shadow-xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05);
|
||||
--shadow-sm: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10);
|
||||
--shadow: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10);
|
||||
--shadow-md: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 2px 4px -1px oklch(0.00 0 0 / 0.10);
|
||||
--shadow-lg: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 4px 6px -1px oklch(0.00 0 0 / 0.10);
|
||||
--shadow-xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 8px 10px -1px oklch(0.00 0 0 / 0.10);
|
||||
--shadow-2xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.25);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(0.14 0.00 285.86);
|
||||
--foreground: oklch(0.99 0 0);
|
||||
--card: oklch(0.21 0.01 285.93);
|
||||
--card-foreground: oklch(0.99 0 0);
|
||||
--popover: oklch(0.21 0.01 285.93);
|
||||
--popover-foreground: oklch(0.99 0 0);
|
||||
--primary: oklch(0.92 0.00 286.61);
|
||||
--primary-foreground: oklch(0.21 0.01 285.93);
|
||||
--secondary: oklch(0.27 0.01 286.10);
|
||||
--secondary-foreground: oklch(0.99 0 0);
|
||||
--muted: oklch(0.27 0.01 286.10);
|
||||
--muted-foreground: oklch(0.71 0.01 286.09);
|
||||
--accent: oklch(0.27 0.01 286.10);
|
||||
--accent-foreground: oklch(0.99 0 0);
|
||||
--destructive: oklch(0.70 0.19 22.23);
|
||||
--border: oklch(1.00 0 0 / 10%);
|
||||
--input: oklch(1.00 0 0 / 15%);
|
||||
--ring: oklch(0.55 0.02 285.93);
|
||||
--chart-1: oklch(0.49 0.24 264.40);
|
||||
--chart-2: oklch(0.70 0.16 160.43);
|
||||
--chart-3: oklch(0.77 0.17 65.36);
|
||||
--chart-4: oklch(0.62 0.26 305.32);
|
||||
--chart-5: oklch(0.64 0.25 16.51);
|
||||
--sidebar: oklch(0.21 0.01 285.93);
|
||||
--sidebar-foreground: oklch(0.99 0 0);
|
||||
--sidebar-primary: oklch(0.49 0.24 264.40);
|
||||
--sidebar-primary-foreground: oklch(0.99 0 0);
|
||||
--sidebar-accent: oklch(0.27 0.01 286.10);
|
||||
--sidebar-accent-foreground: oklch(0.99 0 0);
|
||||
--sidebar-border: oklch(1.00 0 0 / 10%);
|
||||
--sidebar-ring: oklch(0.55 0.02 285.93);
|
||||
|
||||
--shadow-2xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05);
|
||||
--shadow-xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05);
|
||||
--shadow-sm: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10);
|
||||
--shadow: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10);
|
||||
--shadow-md: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 2px 4px -1px oklch(0.00 0 0 / 0.10);
|
||||
--shadow-lg: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 4px 6px -1px oklch(0.00 0 0 / 0.10);
|
||||
--shadow-xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 8px 10px -1px oklch(0.00 0 0 / 0.10);
|
||||
--shadow-2xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.25);
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-card: var(--card);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-border: var(--border);
|
||||
--color-input: var(--input);
|
||||
--color-ring: var(--ring);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
|
||||
--font-sans: var(--font-sans);
|
||||
--font-mono: var(--font-mono);
|
||||
--font-serif: var(--font-serif);
|
||||
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
|
||||
--shadow-2xs: var(--shadow-2xs);
|
||||
--shadow-xs: var(--shadow-xs);
|
||||
--shadow-sm: var(--shadow-sm);
|
||||
--shadow: var(--shadow);
|
||||
--shadow-md: var(--shadow-md);
|
||||
--shadow-lg: var(--shadow-lg);
|
||||
--shadow-xl: var(--shadow-xl);
|
||||
--shadow-2xl: var(--shadow-2xl);
|
||||
}
|
||||
@@ -529,7 +529,7 @@ function CustomWeatherWidget() {
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Annotations](./annotations) - Learn how to create and send annotation data
|
||||
- [Artifacts](./artifacts) - Implement interactive code and document artifacts
|
||||
- [Hooks](./hooks) - Understand the widget hook system
|
||||
- [Customization](./customization) - Style and customize widget appearance
|
||||
- [Annotations](./annotations.mdx) - Learn how to create and send annotation data
|
||||
- [Artifacts](./artifacts.mdx) - Implement interactive code and document artifacts
|
||||
- [Hooks](./hooks.mdx) - Understand the widget hook system
|
||||
- [Customization](./customization.mdx) - Style and customize widget appearance
|
||||
Generated
+34
@@ -50,6 +50,9 @@ importers:
|
||||
clsx:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1
|
||||
framer-motion:
|
||||
specifier: ^12.15.0
|
||||
version: 12.15.0(react-dom@18.3.1)(react@18.3.1)
|
||||
highlight.js:
|
||||
specifier: ^11.10.0
|
||||
version: 11.11.1
|
||||
@@ -5953,6 +5956,27 @@ packages:
|
||||
web-streams-polyfill: 4.0.0-beta.3
|
||||
dev: false
|
||||
|
||||
/framer-motion@12.15.0(react-dom@18.3.1)(react@18.3.1):
|
||||
resolution: {integrity: sha512-XKg/LnKExdLGugZrDILV7jZjI599785lDIJZLxMiiIFidCsy0a4R2ZEf+Izm67zyOuJgQYTHOmodi7igQsw3vg==}
|
||||
peerDependencies:
|
||||
'@emotion/is-prop-valid': '*'
|
||||
react: ^18.0.0 || ^19.0.0
|
||||
react-dom: ^18.0.0 || ^19.0.0
|
||||
peerDependenciesMeta:
|
||||
'@emotion/is-prop-valid':
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
dependencies:
|
||||
motion-dom: 12.15.0
|
||||
motion-utils: 12.12.1
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
tslib: 2.8.1
|
||||
dev: false
|
||||
|
||||
/fs-constants@1.0.0:
|
||||
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
|
||||
requiresBuild: true
|
||||
@@ -7752,6 +7776,16 @@ packages:
|
||||
ufo: 1.6.1
|
||||
dev: false
|
||||
|
||||
/motion-dom@12.15.0:
|
||||
resolution: {integrity: sha512-D2ldJgor+2vdcrDtKJw48k3OddXiZN1dDLLWrS8kiHzQdYVruh0IoTwbJBslrnTXIPgFED7PBN2Zbwl7rNqnhA==}
|
||||
dependencies:
|
||||
motion-utils: 12.12.1
|
||||
dev: false
|
||||
|
||||
/motion-utils@12.12.1:
|
||||
resolution: {integrity: sha512-f9qiqUHm7hWSLlNW8gS9pisnsN7CRFRD58vNjptKdsqFLpkVnX00TNeD6Q0d27V9KzT7ySFyK1TZ/DShfVOv6w==}
|
||||
dev: false
|
||||
|
||||
/mri@1.2.0:
|
||||
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
Reference in New Issue
Block a user