docs: update document for chat-ui (#102)

---------
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
This commit is contained in:
Thuc Pham
2025-05-30 13:40:24 +07:00
committed by GitHub
parent 40524c373f
commit 3481173bbc
17 changed files with 393 additions and 110 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'web': patch
'@llamaindex/chat-ui-docs': patch
---
docs: update documentation
+65 -45
View File
@@ -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>
)
+3 -1
View File
@@ -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",
+5 -2
View File
@@ -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}'": ""
}
}
+1
View File
@@ -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[] = [
+22
View File
@@ -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)
}
+4 -4
View File
@@ -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
+4 -4
View File
@@ -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
+4 -4
View File
@@ -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
+4 -4
View File
@@ -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
+2 -2
View File
@@ -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
+75 -26
View File
@@ -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
+4 -4
View File
@@ -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
View File
@@ -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
+146
View File
@@ -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);
}
+4 -4
View File
@@ -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
+34
View File
@@ -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'}