reachat 2.1.2 → 3.0.0

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.
Files changed (65) hide show
  1. package/dist/{CSVFileRenderer-DXI8PDqR.js → CSVFileRenderer-C2tuexJf.js} +2 -2
  2. package/dist/{CSVFileRenderer-DXI8PDqR.js.map → CSVFileRenderer-C2tuexJf.js.map} +1 -1
  3. package/dist/Chat.d.ts +12 -0
  4. package/dist/{Markdown/charts/ChartError.d.ts → ComponentCatalog/ComponentError.d.ts} +2 -2
  5. package/dist/ComponentCatalog/ComponentPre.d.ts +18 -0
  6. package/dist/ComponentCatalog/ComponentRenderer.d.ts +17 -0
  7. package/dist/ComponentCatalog/chartComponentDef.d.ts +36 -0
  8. package/dist/ComponentCatalog/componentCatalog.d.ts +44 -0
  9. package/dist/ComponentCatalog/componentCatalog.spec.d.ts +1 -0
  10. package/dist/ComponentCatalog/generatePrompt.d.ts +9 -0
  11. package/dist/ComponentCatalog/generatePrompt.spec.d.ts +1 -0
  12. package/dist/ComponentCatalog/index.d.ts +9 -0
  13. package/dist/ComponentCatalog/types.d.ts +108 -0
  14. package/dist/ComponentCatalog/validateSpec.d.ts +17 -0
  15. package/dist/ComponentCatalog/validateSpec.spec.d.ts +1 -0
  16. package/dist/{DefaultFileRenderer-Bi8LNDio.js → DefaultFileRenderer-CJ3jwiQa.js} +3 -3
  17. package/dist/{DefaultFileRenderer-Bi8LNDio.js.map → DefaultFileRenderer-CJ3jwiQa.js.map} +1 -1
  18. package/dist/Markdown/charts/ChartRenderer.d.ts +1 -1
  19. package/dist/Markdown/charts/ComponentError.d.ts +1 -0
  20. package/dist/Markdown/charts/index.d.ts +2 -6
  21. package/dist/Markdown/charts/types.d.ts +21 -0
  22. package/dist/Markdown/plugins/index.d.ts +3 -1
  23. package/dist/Markdown/plugins/redactMatchers.d.ts +21 -0
  24. package/dist/Markdown/plugins/remarkComponent.d.ts +27 -0
  25. package/dist/Markdown/plugins/remarkRedact.d.ts +37 -0
  26. package/dist/SessionMessages/SessionMessage/MessageActions.d.ts +2 -2
  27. package/dist/SessionMessages/SessionMessage/MessageFiles.d.ts +2 -2
  28. package/dist/SessionMessages/SessionMessage/MessageQuestion.d.ts +2 -2
  29. package/dist/SessionMessages/SessionMessage/MessageResponse.d.ts +2 -2
  30. package/dist/SessionMessages/SessionMessage/MessageSources.d.ts +2 -2
  31. package/dist/SessionMessages/SessionMessage/SessionMessage.d.ts +2 -2
  32. package/dist/SessionsList/SessionListItem.d.ts +2 -2
  33. package/dist/docs.json +264 -90
  34. package/dist/{index-CBHNcMyR.js → index-8tlsyFe-.js} +1224 -1576
  35. package/dist/index-8tlsyFe-.js.map +1 -0
  36. package/dist/index.css +32 -1
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.js +53 -46
  39. package/dist/index.umd.cjs +1220 -1574
  40. package/dist/index.umd.cjs.map +1 -1
  41. package/dist/stories/AgUi.stories.tsx +118 -0
  42. package/dist/stories/Charts.stories.tsx +118 -130
  43. package/dist/stories/Chat.stories.tsx +6 -1
  44. package/dist/stories/ChatSuggestions.stories.tsx +9 -81
  45. package/dist/stories/Companion.stories.tsx +7 -1
  46. package/dist/stories/ComponentCatalog.stories.tsx +509 -0
  47. package/dist/stories/{ChartError.stories.tsx → ComponentError.stories.tsx} +14 -11
  48. package/dist/stories/Console.stories.tsx +66 -21
  49. package/dist/stories/EnhancedInput.stories.tsx +7 -1
  50. package/dist/stories/Redact.stories.tsx +175 -0
  51. package/dist/stories/examples.ts +31 -0
  52. package/dist/theme.d.ts +3 -0
  53. package/dist/useAgUi/index.d.ts +4 -0
  54. package/dist/useAgUi/types.d.ts +157 -0
  55. package/dist/useAgUi/useAgUi.d.ts +119 -0
  56. package/dist/useAgUi/useAgUi.spec.d.ts +1 -0
  57. package/dist/utils/getChildText.d.ts +10 -0
  58. package/dist/utils/getChildText.spec.d.ts +1 -0
  59. package/package.json +6 -6
  60. package/dist/Markdown/charts/ChartPre.d.ts +0 -6
  61. package/dist/Markdown/charts/chartHelpers.d.ts +0 -40
  62. package/dist/Markdown/plugins/remarkChart.d.ts +0 -59
  63. package/dist/index-CBHNcMyR.js.map +0 -1
  64. package/dist/stories/Integration.stories.tsx +0 -312
  65. /package/dist/{Markdown/charts/chartHelpers.spec.d.ts → ComponentCatalog/chartComponentDef.spec.d.ts} +0 -0
@@ -16,7 +16,8 @@ import {
16
16
  fakeSessions,
17
17
  sessionWithSources,
18
18
  sessionsWithFiles,
19
- chatTemplates
19
+ chatTemplates,
20
+ createSendMessageHandler
20
21
  } from './examples';
21
22
  import { useState, memo, useCallback } from 'react';
22
23
  import { IconButton } from 'reablocks';
@@ -69,6 +70,7 @@ export const Basic = () => {
69
70
  }}
70
71
  onSelectSession={setActiveId}
71
72
  onDeleteSession={() => alert('delete!')}
73
+ onSendMessage={createSendMessageHandler(setSessions, activeId)}
72
74
  >
73
75
  <SessionsList>
74
76
  <NewSessionButton />
@@ -161,6 +163,7 @@ export const WithAppBar = () => {
161
163
  }}
162
164
  onSelectSession={setActiveId}
163
165
  onDeleteSession={() => alert('delete!')}
166
+ onSendMessage={createSendMessageHandler(setSessions, activeId)}
164
167
  >
165
168
  <AppBar
166
169
  content={
@@ -256,6 +259,7 @@ export const TemplatesView = () => {
256
259
  activeSessionId={activeId}
257
260
  onSelectSession={setActiveId}
258
261
  onDeleteSession={() => alert('delete!')}
262
+ onSendMessage={createSendMessageHandler(setSessions, activeId)}
259
263
  >
260
264
  <div className="flex flex-col h-full">
261
265
  <div className="flex-1 overflow-y-auto">
@@ -321,6 +325,7 @@ export const TemplatesViewWithTitle = () => {
321
325
  activeSessionId={activeId}
322
326
  onSelectSession={setActiveId}
323
327
  onDeleteSession={() => alert('delete!')}
328
+ onSendMessage={createSendMessageHandler(setSessions, activeId)}
324
329
  >
325
330
  <div className="dark:text-white text-gray-500 w-full h-full overflow-hidden flex flex-col">
326
331
  <div className="flex-1 overflow-y-auto">
@@ -398,6 +403,7 @@ export const TemplatesViewWithAppBar = () => {
398
403
  activeSessionId={activeId}
399
404
  onSelectSession={setActiveId}
400
405
  onDeleteSession={() => alert('delete!')}
406
+ onSendMessage={createSendMessageHandler(setSessions, activeId)}
401
407
  >
402
408
  <div className="dark:text-white text-gray-500 w-full h-full overflow-hidden flex flex-col">
403
409
  <div className="flex-1 overflow-y-auto">
@@ -0,0 +1,509 @@
1
+ import React from 'react';
2
+ import { Meta } from '@storybook/react';
3
+ import { subHours } from 'date-fns';
4
+ import { z } from 'zod';
5
+ import {
6
+ Chat,
7
+ Session,
8
+ SessionsList,
9
+ SessionGroups,
10
+ NewSessionButton,
11
+ SessionMessages,
12
+ ChatInput,
13
+ SessionMessagePanel,
14
+ SessionMessagesHeader,
15
+ componentCatalog
16
+ } from 'reachat';
17
+
18
+ export default {
19
+ title: 'Demos/ComponentCatalog',
20
+ component: Chat
21
+ } as Meta;
22
+
23
+ // ---------------------------------------------------------------------------
24
+ // Sample components
25
+ // ---------------------------------------------------------------------------
26
+
27
+ const WeatherCard = ({
28
+ city,
29
+ temperature,
30
+ condition
31
+ }: {
32
+ city: string;
33
+ temperature: number;
34
+ condition: string;
35
+ }) => (
36
+ <div
37
+ style={{
38
+ padding: '16px',
39
+ borderRadius: '12px',
40
+ background:
41
+ condition === 'sunny'
42
+ ? 'linear-gradient(135deg, #f6d365 0%, #fda085 100%)'
43
+ : condition === 'rainy'
44
+ ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'
45
+ : 'linear-gradient(135deg, #a1c4fd 0%, #c2e9fb 100%)',
46
+ color: condition === 'rainy' ? '#fff' : '#1a1a2e',
47
+ minWidth: 200
48
+ }}
49
+ >
50
+ <div style={{ fontSize: '14px', opacity: 0.8 }}>{condition}</div>
51
+ <div style={{ fontSize: '24px', fontWeight: 700 }}>{city}</div>
52
+ <div style={{ fontSize: '36px', fontWeight: 300 }}>{temperature}°F</div>
53
+ </div>
54
+ );
55
+
56
+ const AlertBox = ({
57
+ title,
58
+ message,
59
+ severity
60
+ }: {
61
+ title: string;
62
+ message: string;
63
+ severity: string;
64
+ }) => {
65
+ const colors: Record<string, { bg: string; border: string; text: string }> = {
66
+ info: { bg: '#e3f2fd', border: '#90caf9', text: '#1565c0' },
67
+ warning: { bg: '#fff3e0', border: '#ffcc80', text: '#e65100' },
68
+ error: { bg: '#ffebee', border: '#ef9a9a', text: '#c62828' },
69
+ success: { bg: '#e8f5e9', border: '#a5d6a7', text: '#2e7d32' }
70
+ };
71
+ const c = colors[severity] || colors.info;
72
+ return (
73
+ <div
74
+ style={{
75
+ padding: '12px 16px',
76
+ borderRadius: '8px',
77
+ border: `1px solid ${c.border}`,
78
+ background: c.bg,
79
+ color: c.text
80
+ }}
81
+ >
82
+ <div style={{ fontWeight: 600, marginBottom: 4 }}>{title}</div>
83
+ <div style={{ fontSize: '14px' }}>{message}</div>
84
+ </div>
85
+ );
86
+ };
87
+
88
+ const StatusBadge = ({
89
+ label,
90
+ status
91
+ }: {
92
+ label: string;
93
+ status: string;
94
+ }) => {
95
+ const colors: Record<string, string> = {
96
+ online: '#22c55e',
97
+ offline: '#ef4444',
98
+ away: '#f59e0b',
99
+ busy: '#ef4444'
100
+ };
101
+ return (
102
+ <span
103
+ style={{
104
+ display: 'inline-flex',
105
+ alignItems: 'center',
106
+ gap: 6,
107
+ padding: '4px 12px',
108
+ borderRadius: '999px',
109
+ background: `${colors[status] || '#6b7280'}20`,
110
+ color: colors[status] || '#6b7280',
111
+ fontSize: '13px',
112
+ fontWeight: 500
113
+ }}
114
+ >
115
+ <span
116
+ style={{
117
+ width: 8,
118
+ height: 8,
119
+ borderRadius: '50%',
120
+ background: colors[status] || '#6b7280'
121
+ }}
122
+ />
123
+ {label}
124
+ </span>
125
+ );
126
+ };
127
+
128
+ const DataCard = ({
129
+ title,
130
+ value,
131
+ unit,
132
+ trend
133
+ }: {
134
+ title: string;
135
+ value: number;
136
+ unit?: string;
137
+ trend?: string;
138
+ }) => (
139
+ <div
140
+ style={{
141
+ padding: '16px',
142
+ borderRadius: '12px',
143
+ border: '1px solid #e5e7eb',
144
+ background: '#fff',
145
+ minWidth: 160
146
+ }}
147
+ >
148
+ <div style={{ fontSize: '12px', color: '#6b7280', marginBottom: 4 }}>
149
+ {title}
150
+ </div>
151
+ <div style={{ fontSize: '28px', fontWeight: 700, color: '#111827' }}>
152
+ {value}
153
+ {unit && (
154
+ <span style={{ fontSize: '14px', fontWeight: 400, marginLeft: 2 }}>
155
+ {unit}
156
+ </span>
157
+ )}
158
+ </div>
159
+ {trend && (
160
+ <div
161
+ style={{
162
+ fontSize: '12px',
163
+ color: trend.startsWith('+') ? '#22c55e' : '#ef4444',
164
+ marginTop: 4
165
+ }}
166
+ >
167
+ {trend}
168
+ </div>
169
+ )}
170
+ </div>
171
+ );
172
+
173
+ const RowLayout = ({
174
+ children
175
+ }: {
176
+ children?: React.ReactNode;
177
+ }) => (
178
+ <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>{children}</div>
179
+ );
180
+
181
+ // ---------------------------------------------------------------------------
182
+ // Catalog
183
+ // ---------------------------------------------------------------------------
184
+
185
+ const catalog = componentCatalog({
186
+ WeatherCard: {
187
+ description: 'Displays current weather conditions for a city',
188
+ props: z.object({
189
+ city: z.string().describe('City name'),
190
+ temperature: z.number().describe('Temperature in Fahrenheit'),
191
+ condition: z.enum(['sunny', 'cloudy', 'rainy']).describe(
192
+ 'Current weather condition'
193
+ )
194
+ }),
195
+ component: WeatherCard as any
196
+ },
197
+ AlertBox: {
198
+ description: 'Displays an alert or notification box',
199
+ props: z.object({
200
+ title: z.string().describe('Alert title'),
201
+ message: z.string().describe('Alert message body'),
202
+ severity: z.enum(['info', 'warning', 'error', 'success']).describe(
203
+ 'Severity level'
204
+ )
205
+ }),
206
+ component: AlertBox as any
207
+ },
208
+ StatusBadge: {
209
+ description: 'Displays a status indicator badge',
210
+ props: z.object({
211
+ label: z.string().describe('Display label'),
212
+ status: z.enum(['online', 'offline', 'away', 'busy']).describe(
213
+ 'Current status'
214
+ )
215
+ }),
216
+ component: StatusBadge as any
217
+ },
218
+ DataCard: {
219
+ description: 'Displays a single metric or KPI',
220
+ props: z.object({
221
+ title: z.string().describe('Metric name'),
222
+ value: z.number().describe('Metric value'),
223
+ unit: z.string().optional(),
224
+ trend: z.string().optional()
225
+ }),
226
+ component: DataCard as any
227
+ },
228
+ Row: {
229
+ description:
230
+ 'A horizontal flex layout container — use as a parent to lay out child components side-by-side',
231
+ props: z.object({}),
232
+ component: RowLayout as any
233
+ }
234
+ });
235
+
236
+ // ---------------------------------------------------------------------------
237
+ // Session data
238
+ // ---------------------------------------------------------------------------
239
+
240
+ const weatherSpec = {
241
+ type: 'WeatherCard',
242
+ props: { city: 'San Francisco', temperature: 68, condition: 'cloudy' }
243
+ };
244
+
245
+ const alertSpec = {
246
+ type: 'AlertBox',
247
+ props: {
248
+ title: 'Deployment Successful',
249
+ message:
250
+ 'Version 2.4.1 has been deployed to production. All health checks passing.',
251
+ severity: 'success'
252
+ }
253
+ };
254
+
255
+ const multiWeatherSpec = [
256
+ {
257
+ type: 'WeatherCard',
258
+ props: { city: 'San Francisco', temperature: 68, condition: 'cloudy' }
259
+ },
260
+ {
261
+ type: 'WeatherCard',
262
+ props: { city: 'New York', temperature: 45, condition: 'rainy' }
263
+ },
264
+ {
265
+ type: 'WeatherCard',
266
+ props: { city: 'Miami', temperature: 82, condition: 'sunny' }
267
+ }
268
+ ];
269
+
270
+ const dashboardSpec = {
271
+ type: 'Row',
272
+ props: {},
273
+ children: [
274
+ {
275
+ type: 'DataCard',
276
+ props: {
277
+ title: 'Revenue',
278
+ value: 12450,
279
+ unit: '$',
280
+ trend: '+12.5% from last month'
281
+ }
282
+ },
283
+ {
284
+ type: 'DataCard',
285
+ props: {
286
+ title: 'Active Users',
287
+ value: 8423,
288
+ trend: '+5.2% from last week'
289
+ }
290
+ },
291
+ {
292
+ type: 'DataCard',
293
+ props: { title: 'Error Rate', value: 0.3, unit: '%', trend: '-0.1%' }
294
+ }
295
+ ]
296
+ };
297
+
298
+ const sessions: Session[] = [
299
+ {
300
+ id: 'session-1',
301
+ title: 'Dynamic Components Demo',
302
+ createdAt: subHours(new Date(), 2),
303
+ updatedAt: new Date(),
304
+ conversations: [
305
+ {
306
+ id: 'conv-1',
307
+ question: "What's the weather in San Francisco?",
308
+ response: `Here's the current weather:
309
+
310
+ \`\`\`component
311
+ ${JSON.stringify(weatherSpec, null, 2)}
312
+ \`\`\`
313
+
314
+ Looks like a typical foggy day in the city!`,
315
+ createdAt: subHours(new Date(), 2)
316
+ },
317
+ {
318
+ id: 'conv-2',
319
+ question: 'Show me weather for multiple cities',
320
+ response: `Here's a comparison of weather across three cities:
321
+
322
+ \`\`\`component
323
+ ${JSON.stringify(multiWeatherSpec, null, 2)}
324
+ \`\`\`
325
+
326
+ San Francisco is mild, New York is rainy, and Miami is warm and sunny.`,
327
+ createdAt: subHours(new Date(), 1.5)
328
+ },
329
+ {
330
+ id: 'conv-3',
331
+ question: 'Any deployment updates?',
332
+ response: `Yes! Here's the latest update:
333
+
334
+ \`\`\`component
335
+ ${JSON.stringify(alertSpec, null, 2)}
336
+ \`\`\`
337
+
338
+ Everything looks good. All services are healthy.`,
339
+ createdAt: subHours(new Date(), 1)
340
+ },
341
+ {
342
+ id: 'conv-4',
343
+ question: 'Show me the dashboard metrics',
344
+ response: `Here's your dashboard overview with nested components:
345
+
346
+ \`\`\`component
347
+ ${JSON.stringify(dashboardSpec, null, 2)}
348
+ \`\`\`
349
+
350
+ Revenue is trending up and error rates are down. Looking great!`,
351
+ createdAt: subHours(new Date(), 0.5)
352
+ }
353
+ ]
354
+ }
355
+ ];
356
+
357
+ const errorSessions: Session[] = [
358
+ {
359
+ id: 'session-errors',
360
+ title: 'Error Handling Demo',
361
+ createdAt: subHours(new Date(), 1),
362
+ updatedAt: new Date(),
363
+ conversations: [
364
+ {
365
+ id: 'conv-err-1',
366
+ question: 'Show me an unknown component',
367
+ response: `Here's a component that doesn't exist in the catalog:
368
+
369
+ \`\`\`component
370
+ { "type": "NonExistentWidget", "props": { "foo": "bar" } }
371
+ \`\`\`
372
+
373
+ The error should be displayed gracefully above.`,
374
+ createdAt: subHours(new Date(), 1)
375
+ },
376
+ {
377
+ id: 'conv-err-2',
378
+ question: 'Show me invalid JSON',
379
+ response: `Here's some broken JSON:
380
+
381
+ \`\`\`component
382
+ { type: WeatherCard, props: invalid }
383
+ \`\`\`
384
+
385
+ The parser should handle this gracefully.`,
386
+ createdAt: subHours(new Date(), 0.5)
387
+ },
388
+ {
389
+ id: 'conv-err-3',
390
+ question: 'Show me invalid props',
391
+ response: `Here's a valid component type with wrong props:
392
+
393
+ \`\`\`component
394
+ { "type": "WeatherCard", "props": { "city": 123, "temperature": "not-a-number", "condition": "unknown" } }
395
+ \`\`\`
396
+
397
+ Zod validation should catch the prop type mismatches.`,
398
+ createdAt: new Date()
399
+ }
400
+ ]
401
+ }
402
+ ];
403
+
404
+ // ---------------------------------------------------------------------------
405
+ // Stories
406
+ // ---------------------------------------------------------------------------
407
+
408
+ const storyStyle = {
409
+ position: 'absolute' as const,
410
+ top: 0,
411
+ left: 0,
412
+ right: 0,
413
+ bottom: 0,
414
+ padding: 20,
415
+ margin: 20,
416
+ borderRadius: 5
417
+ };
418
+
419
+ export const BasicExample = () => (
420
+ <div className="dark:bg-gray-950 bg-white" style={storyStyle}>
421
+ <Chat
422
+ viewType="console"
423
+ sessions={sessions}
424
+ activeSessionId="session-1"
425
+ components={catalog}
426
+ >
427
+ <SessionsList>
428
+ <NewSessionButton />
429
+ <SessionGroups />
430
+ </SessionsList>
431
+ <SessionMessagePanel>
432
+ <SessionMessagesHeader />
433
+ <SessionMessages />
434
+ <ChatInput />
435
+ </SessionMessagePanel>
436
+ </Chat>
437
+ </div>
438
+ );
439
+
440
+ export const ErrorHandling = () => (
441
+ <div className="dark:bg-gray-950 bg-white" style={storyStyle}>
442
+ <Chat
443
+ viewType="console"
444
+ sessions={errorSessions}
445
+ activeSessionId="session-errors"
446
+ components={catalog}
447
+ >
448
+ <SessionsList>
449
+ <NewSessionButton />
450
+ <SessionGroups />
451
+ </SessionsList>
452
+ <SessionMessagePanel>
453
+ <SessionMessagesHeader />
454
+ <SessionMessages />
455
+ <ChatInput />
456
+ </SessionMessagePanel>
457
+ </Chat>
458
+ </div>
459
+ );
460
+
461
+ export const ChatViewOnly = () => (
462
+ <div
463
+ className="dark:bg-gray-950 bg-white"
464
+ style={{ ...storyStyle, maxWidth: 800, marginLeft: 'auto', marginRight: 'auto' }}
465
+ >
466
+ <Chat
467
+ viewType="chat"
468
+ sessions={sessions}
469
+ activeSessionId="session-1"
470
+ components={catalog}
471
+ >
472
+ <SessionMessagePanel>
473
+ <SessionMessagesHeader />
474
+ <SessionMessages />
475
+ <ChatInput />
476
+ </SessionMessagePanel>
477
+ </Chat>
478
+ </div>
479
+ );
480
+
481
+ export const SystemPromptPreview = () => {
482
+ const prompt = catalog.systemPrompt();
483
+ return (
484
+ <div style={{ padding: 40, maxWidth: 800 }}>
485
+ <h2 style={{ marginBottom: 16, fontSize: 20, fontWeight: 600 }}>
486
+ Generated LLM System Prompt
487
+ </h2>
488
+ <p style={{ marginBottom: 16, color: '#6b7280', fontSize: 14 }}>
489
+ This is what <code>catalog.systemPrompt()</code> generates.
490
+ Include this in your LLM system message so it knows how to use
491
+ your registered components.
492
+ </p>
493
+ <pre
494
+ style={{
495
+ padding: 20,
496
+ borderRadius: 8,
497
+ background: '#1e1e2e',
498
+ color: '#cdd6f4',
499
+ fontSize: 13,
500
+ lineHeight: 1.6,
501
+ overflow: 'auto',
502
+ whiteSpace: 'pre-wrap'
503
+ }}
504
+ >
505
+ {prompt}
506
+ </pre>
507
+ </div>
508
+ );
509
+ };
@@ -2,16 +2,20 @@ import React from 'react';
2
2
  import { Meta } from '@storybook/react';
3
3
  import {
4
4
  Chat,
5
- remarkChart,
6
- chartComponents,
7
- ChartError
5
+ ComponentError,
6
+ componentCatalog,
7
+ createChartComponentDef
8
8
  } from 'reachat';
9
9
 
10
10
  export default {
11
- title: 'Components/ChartError',
12
- component: ChartError
11
+ title: 'Components/ComponentError',
12
+ component: ComponentError
13
13
  } as Meta;
14
14
 
15
+ const catalog = componentCatalog({
16
+ Chart: createChartComponentDef()
17
+ });
18
+
15
19
  const Wrapper = ({ children }: { children: React.ReactNode }) => (
16
20
  <div
17
21
  className="dark:bg-gray-950 bg-white"
@@ -28,8 +32,7 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => (
28
32
  viewType="chat"
29
33
  sessions={[]}
30
34
  activeSessionId=""
31
- remarkPlugins={[remarkChart]}
32
- markdownComponents={chartComponents}
35
+ components={catalog}
33
36
  >
34
37
  <div style={{ maxWidth: 500 }}>{children}</div>
35
38
  </Chat>
@@ -38,7 +41,7 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => (
38
41
 
39
42
  export const Default = () => (
40
43
  <Wrapper>
41
- <ChartError
44
+ <ComponentError
42
45
  title="Failed to render chart"
43
46
  message="The chart data could not be parsed. Please check the JSON format."
44
47
  />
@@ -47,7 +50,7 @@ export const Default = () => (
47
50
 
48
51
  export const WithCode = () => (
49
52
  <Wrapper>
50
- <ChartError
53
+ <ComponentError
51
54
  title="Invalid chart configuration"
52
55
  message="The 'type' field is missing from the chart configuration."
53
56
  code={`{
@@ -62,7 +65,7 @@ export const WithCode = () => (
62
65
 
63
66
  export const Warning = () => (
64
67
  <Wrapper>
65
- <ChartError
68
+ <ComponentError
66
69
  variant="warning"
67
70
  title="Chart data incomplete"
68
71
  message="Some data points are missing values. The chart may not display correctly."
@@ -72,7 +75,7 @@ export const Warning = () => (
72
75
 
73
76
  export const WarningWithCode = () => (
74
77
  <Wrapper>
75
- <ChartError
78
+ <ComponentError
76
79
  variant="warning"
77
80
  title="Unsupported chart type"
78
81
  message="The chart type 'scatter' is not supported. Falling back to bar chart."