@v0-sdk/react 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +246 -52
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,14 +17,14 @@ pnpm add @v0-sdk/react
|
|
|
17
17
|
### Basic Usage
|
|
18
18
|
|
|
19
19
|
```tsx
|
|
20
|
-
import {
|
|
20
|
+
import { Message } from '@v0-sdk/react'
|
|
21
21
|
|
|
22
22
|
function ChatMessage({ apiResponse }) {
|
|
23
23
|
// Parse the content from the API response
|
|
24
24
|
const content = JSON.parse(apiResponse.content)
|
|
25
25
|
|
|
26
26
|
return (
|
|
27
|
-
<
|
|
27
|
+
<Message
|
|
28
28
|
content={content}
|
|
29
29
|
messageId={apiResponse.id}
|
|
30
30
|
role={apiResponse.role}
|
|
@@ -36,13 +36,13 @@ function ChatMessage({ apiResponse }) {
|
|
|
36
36
|
### With Streaming
|
|
37
37
|
|
|
38
38
|
```tsx
|
|
39
|
-
import {
|
|
39
|
+
import { Message } from '@v0-sdk/react'
|
|
40
40
|
|
|
41
41
|
function StreamingMessage({ apiResponse, isStreaming }) {
|
|
42
42
|
const content = JSON.parse(apiResponse.content)
|
|
43
43
|
|
|
44
44
|
return (
|
|
45
|
-
<
|
|
45
|
+
<Message
|
|
46
46
|
content={content}
|
|
47
47
|
messageId={apiResponse.id}
|
|
48
48
|
role={apiResponse.role}
|
|
@@ -53,19 +53,55 @@ function StreamingMessage({ apiResponse, isStreaming }) {
|
|
|
53
53
|
}
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
### Custom Styling
|
|
56
|
+
### Custom Component Styling
|
|
57
|
+
|
|
58
|
+
The `Message` component supports custom component renderers for complete control over styling and behavior:
|
|
57
59
|
|
|
58
60
|
```tsx
|
|
59
|
-
import {
|
|
61
|
+
import { Message, CodeBlock, MathPart } from '@v0-sdk/react'
|
|
62
|
+
|
|
63
|
+
// Custom code block with syntax highlighting
|
|
64
|
+
function CustomCodeBlock({ language, code, className }) {
|
|
65
|
+
return (
|
|
66
|
+
<div className="my-code-block">
|
|
67
|
+
<div className="code-header">{language}</div>
|
|
68
|
+
<pre className={className}>
|
|
69
|
+
<code>{code}</code>
|
|
70
|
+
</pre>
|
|
71
|
+
</div>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Custom math renderer
|
|
76
|
+
function CustomMathPart({ content, inline, className }) {
|
|
77
|
+
return (
|
|
78
|
+
<span className={`my-math ${inline ? 'inline' : 'block'} ${className}`}>
|
|
79
|
+
{content}
|
|
80
|
+
</span>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
60
83
|
|
|
61
84
|
function StyledMessage({ apiResponse }) {
|
|
62
85
|
const content = JSON.parse(apiResponse.content)
|
|
63
86
|
|
|
64
87
|
return (
|
|
65
|
-
<
|
|
88
|
+
<Message
|
|
66
89
|
content={content}
|
|
67
90
|
messageId={apiResponse.id}
|
|
68
91
|
role={apiResponse.role}
|
|
92
|
+
components={{
|
|
93
|
+
CodeBlock: CustomCodeBlock,
|
|
94
|
+
MathPart: CustomMathPart,
|
|
95
|
+
// Style HTML elements with simple className objects
|
|
96
|
+
p: { className: 'my-paragraph-styles' },
|
|
97
|
+
h1: { className: 'my-heading-styles' },
|
|
98
|
+
// Or use custom components for full control
|
|
99
|
+
blockquote: ({ children, ...props }) => (
|
|
100
|
+
<div className="my-custom-blockquote" {...props}>
|
|
101
|
+
{children}
|
|
102
|
+
</div>
|
|
103
|
+
),
|
|
104
|
+
}}
|
|
69
105
|
className="my-custom-message-styles"
|
|
70
106
|
/>
|
|
71
107
|
)
|
|
@@ -74,7 +110,7 @@ function StyledMessage({ apiResponse }) {
|
|
|
74
110
|
|
|
75
111
|
## API Reference
|
|
76
112
|
|
|
77
|
-
###
|
|
113
|
+
### Message
|
|
78
114
|
|
|
79
115
|
The main component for rendering v0 Platform API message content.
|
|
80
116
|
|
|
@@ -87,7 +123,69 @@ The main component for rendering v0 Platform API message content.
|
|
|
87
123
|
| `role` | `'user' \| 'assistant' \| 'system' \| 'tool'` | `'assistant'` | Role of the message sender |
|
|
88
124
|
| `streaming` | `boolean` | `false` | Whether the message is currently being streamed |
|
|
89
125
|
| `isLastMessage` | `boolean` | `false` | Whether this is the last message in the conversation |
|
|
90
|
-
| `className` | `string` | `undefined` | Custom className for styling
|
|
126
|
+
| `className` | `string` | `undefined` | Custom className for styling the root container |
|
|
127
|
+
| `components` | `ComponentOverrides` | `undefined` | Custom component renderers (see Custom Components section) |
|
|
128
|
+
|
|
129
|
+
### Individual Components
|
|
130
|
+
|
|
131
|
+
You can also use individual components directly:
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
import {
|
|
135
|
+
CodeBlock,
|
|
136
|
+
MathPart,
|
|
137
|
+
ThinkingSection,
|
|
138
|
+
TaskSection,
|
|
139
|
+
CodeProjectPart
|
|
140
|
+
} from '@v0-sdk/react'
|
|
141
|
+
|
|
142
|
+
// Use components directly
|
|
143
|
+
<CodeBlock language="javascript" code="console.log('Hello')" />
|
|
144
|
+
<MathPart content="E = mc^2" inline />
|
|
145
|
+
<ThinkingSection title="Planning" thought="Let me think about this..." />
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### CodeBlock
|
|
149
|
+
|
|
150
|
+
| Prop | Type | Default | Description |
|
|
151
|
+
| ----------- | ----------------- | ------------ | -------------------------------------------- |
|
|
152
|
+
| `language` | `string` | **required** | Programming language for syntax highlighting |
|
|
153
|
+
| `code` | `string` | **required** | The code content to display |
|
|
154
|
+
| `filename` | `string` | `undefined` | Optional filename to display |
|
|
155
|
+
| `className` | `string` | `undefined` | Custom styling |
|
|
156
|
+
| `children` | `React.ReactNode` | `undefined` | Custom content (overrides code prop) |
|
|
157
|
+
|
|
158
|
+
#### MathPart
|
|
159
|
+
|
|
160
|
+
| Prop | Type | Default | Description |
|
|
161
|
+
| ------------- | ----------------- | ------------ | --------------------------------------- |
|
|
162
|
+
| `content` | `string` | **required** | The mathematical expression |
|
|
163
|
+
| `inline` | `boolean` | `false` | Whether to render inline or as block |
|
|
164
|
+
| `displayMode` | `boolean` | `undefined` | Alternative to inline for display mode |
|
|
165
|
+
| `className` | `string` | `undefined` | Custom styling |
|
|
166
|
+
| `children` | `React.ReactNode` | `undefined` | Custom content (overrides content prop) |
|
|
167
|
+
|
|
168
|
+
#### ThinkingSection
|
|
169
|
+
|
|
170
|
+
| Prop | Type | Default | Description |
|
|
171
|
+
| ------------ | ------------ | ----------- | ---------------------------- |
|
|
172
|
+
| `title` | `string` | `undefined` | Section title |
|
|
173
|
+
| `thought` | `string` | `undefined` | The thinking content |
|
|
174
|
+
| `duration` | `number` | `undefined` | Duration in milliseconds |
|
|
175
|
+
| `collapsed` | `boolean` | `false` | Whether section is collapsed |
|
|
176
|
+
| `onCollapse` | `() => void` | `undefined` | Collapse toggle handler |
|
|
177
|
+
| `className` | `string` | `undefined` | Custom styling |
|
|
178
|
+
|
|
179
|
+
#### TaskSection
|
|
180
|
+
|
|
181
|
+
| Prop | Type | Default | Description |
|
|
182
|
+
| ------------ | ------------ | ----------- | ---------------------------- |
|
|
183
|
+
| `title` | `string` | `undefined` | Section title |
|
|
184
|
+
| `type` | `string` | `undefined` | Task type |
|
|
185
|
+
| `parts` | `any[]` | `undefined` | Task content parts |
|
|
186
|
+
| `collapsed` | `boolean` | `false` | Whether section is collapsed |
|
|
187
|
+
| `onCollapse` | `() => void` | `undefined` | Collapse toggle handler |
|
|
188
|
+
| `className` | `string` | `undefined` | Custom styling |
|
|
91
189
|
|
|
92
190
|
### Types
|
|
93
191
|
|
|
@@ -99,16 +197,17 @@ type MessageBinaryFormat = [number, ...any[]][]
|
|
|
99
197
|
|
|
100
198
|
The binary format for message content as returned by the v0 Platform API. Each row is a tuple where the first element is the type and the rest are data.
|
|
101
199
|
|
|
102
|
-
####
|
|
200
|
+
#### MessageProps
|
|
103
201
|
|
|
104
202
|
```typescript
|
|
105
|
-
interface
|
|
203
|
+
interface MessageProps {
|
|
106
204
|
content: MessageBinaryFormat
|
|
107
205
|
messageId?: string
|
|
108
206
|
role?: 'user' | 'assistant' | 'system' | 'tool'
|
|
109
207
|
streaming?: boolean
|
|
110
208
|
isLastMessage?: boolean
|
|
111
209
|
className?: string
|
|
210
|
+
components?: ComponentOverrides
|
|
112
211
|
}
|
|
113
212
|
```
|
|
114
213
|
|
|
@@ -117,50 +216,61 @@ interface V0MessageRendererProps {
|
|
|
117
216
|
### Supported Content Types
|
|
118
217
|
|
|
119
218
|
- **Markdown/Text Content**: Paragraphs, headings, lists, links, emphasis, code spans, etc.
|
|
120
|
-
- **Code Blocks**: Syntax-highlighted code blocks with support
|
|
121
|
-
- **Mathematical Expressions**: Inline and block math
|
|
122
|
-
- **
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
Code blocks are automatically syntax-highlighted using Prism.js with support for:
|
|
127
|
-
|
|
128
|
-
- JavaScript/TypeScript
|
|
129
|
-
- Python, Java, C/C++, C#
|
|
130
|
-
- PHP, Ruby, Go, Rust
|
|
131
|
-
- Swift, Kotlin, Scala
|
|
132
|
-
- SQL, JSON, YAML
|
|
133
|
-
- Markdown, CSS/SCSS
|
|
134
|
-
- Bash/Shell scripts
|
|
135
|
-
- And many more...
|
|
136
|
-
|
|
137
|
-
### Math Rendering
|
|
219
|
+
- **Code Blocks**: Syntax-highlighted code blocks with filename support
|
|
220
|
+
- **Mathematical Expressions**: Inline and block math expressions
|
|
221
|
+
- **Thinking Sections**: Collapsible reasoning/thinking content
|
|
222
|
+
- **Task Sections**: Structured task and workflow content
|
|
223
|
+
- **Code Projects**: Multi-file code project display
|
|
224
|
+
- **Rich Components**: Full component customization support
|
|
138
225
|
|
|
139
|
-
|
|
226
|
+
### Component Customization
|
|
140
227
|
|
|
141
|
-
|
|
142
|
-
- Block math: `$$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$`
|
|
228
|
+
The `components` prop allows you to override any part of the rendering:
|
|
143
229
|
|
|
144
|
-
|
|
230
|
+
```tsx
|
|
231
|
+
// Simple className-based styling
|
|
232
|
+
<Message
|
|
233
|
+
content={content}
|
|
234
|
+
components={{
|
|
235
|
+
p: { className: 'my-paragraph' },
|
|
236
|
+
h1: { className: 'text-2xl font-bold' }
|
|
237
|
+
}}
|
|
238
|
+
/>
|
|
239
|
+
|
|
240
|
+
// Full component replacement
|
|
241
|
+
<Message
|
|
242
|
+
content={content}
|
|
243
|
+
components={{
|
|
244
|
+
CodeBlock: MyCustomCodeBlock,
|
|
245
|
+
MathPart: MyCustomMathRenderer,
|
|
246
|
+
ThinkingSection: MyCustomThinking
|
|
247
|
+
}}
|
|
248
|
+
/>
|
|
249
|
+
```
|
|
145
250
|
|
|
146
|
-
|
|
251
|
+
### Default Styling
|
|
147
252
|
|
|
148
|
-
|
|
149
|
-
2. **Custom CSS**: Override styles using the `className` prop
|
|
150
|
-
3. **CSS Modules**: Import your own styles and pass via `className`
|
|
253
|
+
The components use Tailwind CSS classes by default but can work with any CSS framework:
|
|
151
254
|
|
|
152
|
-
|
|
255
|
+
1. **Tailwind CSS**: Works out of the box
|
|
256
|
+
2. **Custom CSS**: Use the `className` prop and `components` overrides
|
|
257
|
+
3. **CSS Modules**: Pass CSS module classes via `className` and `components`
|
|
258
|
+
4. **Styled Components**: Wrap components with styled-components
|
|
153
259
|
|
|
154
|
-
|
|
260
|
+
## Backward Compatibility
|
|
155
261
|
|
|
156
|
-
|
|
157
|
-
@import 'katex/dist/katex.min.css';
|
|
158
|
-
```
|
|
262
|
+
The package maintains backward compatibility with previous versions:
|
|
159
263
|
|
|
160
|
-
|
|
264
|
+
```tsx
|
|
265
|
+
// These all work and refer to the same component
|
|
266
|
+
import { Message } from '@v0-sdk/react'
|
|
267
|
+
import { MessageRenderer } from '@v0-sdk/react'
|
|
268
|
+
import { V0MessageRenderer } from '@v0-sdk/react'
|
|
161
269
|
|
|
162
|
-
|
|
163
|
-
|
|
270
|
+
// These are all equivalent
|
|
271
|
+
<Message content={content} />
|
|
272
|
+
<MessageRenderer content={content} />
|
|
273
|
+
<V0MessageRenderer content={content} />
|
|
164
274
|
```
|
|
165
275
|
|
|
166
276
|
## Examples
|
|
@@ -168,8 +278,7 @@ import 'katex/dist/katex.min.css'
|
|
|
168
278
|
### Complete Chat Interface
|
|
169
279
|
|
|
170
280
|
```tsx
|
|
171
|
-
import {
|
|
172
|
-
import 'katex/dist/katex.min.css'
|
|
281
|
+
import { Message } from '@v0-sdk/react'
|
|
173
282
|
|
|
174
283
|
function ChatInterface({ messages }) {
|
|
175
284
|
return (
|
|
@@ -184,7 +293,7 @@ function ChatInterface({ messages }) {
|
|
|
184
293
|
<span className="role">{message.role}</span>
|
|
185
294
|
<span className="timestamp">{message.createdAt}</span>
|
|
186
295
|
</div>
|
|
187
|
-
<
|
|
296
|
+
<Message
|
|
188
297
|
content={content}
|
|
189
298
|
messageId={message.id}
|
|
190
299
|
role={message.role}
|
|
@@ -199,17 +308,75 @@ function ChatInterface({ messages }) {
|
|
|
199
308
|
}
|
|
200
309
|
```
|
|
201
310
|
|
|
311
|
+
### Custom Theme Example
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
import { Message, CodeBlock, MathPart } from '@v0-sdk/react'
|
|
315
|
+
|
|
316
|
+
// Dark theme code block
|
|
317
|
+
function DarkCodeBlock({ language, code, filename }) {
|
|
318
|
+
return (
|
|
319
|
+
<div className="bg-gray-900 rounded-lg overflow-hidden">
|
|
320
|
+
{filename && (
|
|
321
|
+
<div className="bg-gray-800 px-4 py-2 text-gray-300 text-sm">
|
|
322
|
+
{filename}
|
|
323
|
+
</div>
|
|
324
|
+
)}
|
|
325
|
+
<div className="bg-gray-700 px-2 py-1 text-xs text-gray-400">
|
|
326
|
+
{language}
|
|
327
|
+
</div>
|
|
328
|
+
<pre className="p-4 text-green-400 overflow-x-auto">
|
|
329
|
+
<code>{code}</code>
|
|
330
|
+
</pre>
|
|
331
|
+
</div>
|
|
332
|
+
)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Elegant math renderer
|
|
336
|
+
function ElegantMath({ content, inline }) {
|
|
337
|
+
return (
|
|
338
|
+
<span
|
|
339
|
+
className={`
|
|
340
|
+
${inline ? 'mx-1' : 'block text-center my-4'}
|
|
341
|
+
font-serif text-blue-600
|
|
342
|
+
`}
|
|
343
|
+
>
|
|
344
|
+
{content}
|
|
345
|
+
</span>
|
|
346
|
+
)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function ThemedChat({ apiResponse }) {
|
|
350
|
+
const content = JSON.parse(apiResponse.content)
|
|
351
|
+
|
|
352
|
+
return (
|
|
353
|
+
<Message
|
|
354
|
+
content={content}
|
|
355
|
+
components={{
|
|
356
|
+
CodeBlock: DarkCodeBlock,
|
|
357
|
+
MathPart: ElegantMath,
|
|
358
|
+
h1: { className: 'text-3xl font-bold text-gray-800 mb-4' },
|
|
359
|
+
h2: { className: 'text-2xl font-semibold text-gray-700 mb-3' },
|
|
360
|
+
p: { className: 'text-gray-600 leading-relaxed mb-4' },
|
|
361
|
+
blockquote: { className: 'border-l-4 border-blue-500 pl-4 italic' },
|
|
362
|
+
}}
|
|
363
|
+
className="max-w-4xl mx-auto p-6"
|
|
364
|
+
/>
|
|
365
|
+
)
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
202
369
|
### Error Handling
|
|
203
370
|
|
|
204
371
|
```tsx
|
|
205
|
-
import {
|
|
372
|
+
import { Message } from '@v0-sdk/react'
|
|
206
373
|
|
|
207
374
|
function SafeMessageRenderer({ apiResponse }) {
|
|
208
375
|
try {
|
|
209
376
|
const content = JSON.parse(apiResponse.content)
|
|
210
377
|
|
|
211
378
|
return (
|
|
212
|
-
<
|
|
379
|
+
<Message
|
|
213
380
|
content={content}
|
|
214
381
|
messageId={apiResponse.id}
|
|
215
382
|
role={apiResponse.role}
|
|
@@ -217,16 +384,43 @@ function SafeMessageRenderer({ apiResponse }) {
|
|
|
217
384
|
)
|
|
218
385
|
} catch (error) {
|
|
219
386
|
console.error('Failed to parse message content:', error)
|
|
220
|
-
|
|
221
|
-
|
|
387
|
+
return (
|
|
388
|
+
<div className="error-message p-4 bg-red-50 border border-red-200 rounded">
|
|
389
|
+
<p className="text-red-700">Failed to render message content</p>
|
|
390
|
+
<pre className="text-xs text-red-600 mt-2 overflow-x-auto">
|
|
391
|
+
{error.message}
|
|
392
|
+
</pre>
|
|
393
|
+
</div>
|
|
394
|
+
)
|
|
222
395
|
}
|
|
223
396
|
}
|
|
224
397
|
```
|
|
225
398
|
|
|
399
|
+
## TypeScript
|
|
400
|
+
|
|
401
|
+
The package is written in TypeScript and includes comprehensive type definitions. All components and props are fully typed for the best development experience.
|
|
402
|
+
|
|
403
|
+
```tsx
|
|
404
|
+
import type {
|
|
405
|
+
MessageProps,
|
|
406
|
+
CodeBlockProps,
|
|
407
|
+
MathPartProps,
|
|
408
|
+
MessageBinaryFormat,
|
|
409
|
+
} from '@v0-sdk/react'
|
|
410
|
+
|
|
411
|
+
// Type-safe usage
|
|
412
|
+
const myMessage: MessageProps = {
|
|
413
|
+
content: parsedContent,
|
|
414
|
+
role: 'assistant',
|
|
415
|
+
streaming: false,
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
226
419
|
## Requirements
|
|
227
420
|
|
|
228
421
|
- React 18+ or React 19+
|
|
229
422
|
- Modern browser with ES2020+ support
|
|
423
|
+
- TypeScript 4.5+ (if using TypeScript)
|
|
230
424
|
|
|
231
425
|
## License
|
|
232
426
|
|