reachat 2.1.0-alpha.21 → 2.1.0-alpha.22
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/dist/{CSVFileRenderer-GYEEFRXD.js → CSVFileRenderer-DC2ZhtNx.js} +2 -2
- package/dist/{CSVFileRenderer-GYEEFRXD.js.map → CSVFileRenderer-DC2ZhtNx.js.map} +1 -1
- package/dist/ChatInput/ChatInput.d.ts +9 -1
- package/dist/ChatInput/FileDropzone.d.ts +33 -0
- package/dist/ChatInput/FileInput.d.ts +0 -4
- package/dist/ChatInput/index.d.ts +1 -0
- package/dist/ChatSuggestions/ChatSuggestion.d.ts +9 -0
- package/dist/ChatSuggestions/ChatSuggestions.d.ts +22 -0
- package/dist/ChatSuggestions/index.d.ts +2 -0
- package/dist/{DefaultFileRenderer-CUcl0kc2.js → DefaultFileRenderer-3oHDLIk4.js} +2 -2
- package/dist/{DefaultFileRenderer-CUcl0kc2.js.map → DefaultFileRenderer-3oHDLIk4.js.map} +1 -1
- package/dist/MessageStatus/MessageStatus.d.ts +44 -0
- package/dist/MessageStatus/MessageStatusItem.d.ts +9 -0
- package/dist/MessageStatus/StatusIcon.d.ts +17 -0
- package/dist/MessageStatus/index.d.ts +3 -0
- package/dist/SessionMessages/SessionMessages.d.ts +4 -0
- package/dist/docs.json +555 -16
- package/dist/{index-CwH75cwk.js → index-CWCW-OiG.js} +471 -122
- package/dist/index-CWCW-OiG.js.map +1 -0
- package/dist/index.css +186 -55
- package/dist/index.d.ts +2 -0
- package/dist/index.js +30 -24
- package/dist/index.umd.cjs +444 -97
- package/dist/index.umd.cjs.map +1 -1
- package/dist/stories/ChatSuggestions.stories.tsx +542 -0
- package/dist/stories/Console.stories.tsx +101 -623
- package/dist/stories/Files.stories.tsx +348 -0
- package/dist/stories/Markdown.stories.tsx +108 -1
- package/dist/stories/MessageStatus.stories.tsx +326 -0
- package/dist/stories/SessionsList.stories.tsx +276 -0
- package/dist/stories/assets/sparkles.svg +7 -0
- package/dist/stories/examples.ts +34 -0
- package/dist/theme.d.ts +46 -0
- package/dist/types.d.ts +10 -0
- package/package.json +7 -4
- package/dist/index-CwH75cwk.js.map +0 -1
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
|
|
4
|
+
import { ChatContext } from 'reachat';
|
|
5
|
+
import {
|
|
6
|
+
MessageStatus,
|
|
7
|
+
type MessageStatusState,
|
|
8
|
+
type MessageStatusStep
|
|
9
|
+
} from 'reachat';
|
|
10
|
+
import { chatTheme } from 'reachat';
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
title: 'Components/MessageStatus',
|
|
14
|
+
component: MessageStatus,
|
|
15
|
+
decorators: [
|
|
16
|
+
Story => (
|
|
17
|
+
<ChatContext.Provider
|
|
18
|
+
value={{ sessions: [], activeSessionId: null, theme: chatTheme }}
|
|
19
|
+
>
|
|
20
|
+
<Story />
|
|
21
|
+
</ChatContext.Provider>
|
|
22
|
+
)
|
|
23
|
+
],
|
|
24
|
+
args: {
|
|
25
|
+
text: 'Analyzing your request...',
|
|
26
|
+
status: 'loading'
|
|
27
|
+
},
|
|
28
|
+
argTypes: {
|
|
29
|
+
status: {
|
|
30
|
+
control: 'select',
|
|
31
|
+
options: ['loading', 'complete', 'error'],
|
|
32
|
+
description: 'Current status state'
|
|
33
|
+
},
|
|
34
|
+
text: {
|
|
35
|
+
control: 'text',
|
|
36
|
+
description: 'Main status text to display'
|
|
37
|
+
},
|
|
38
|
+
steps: {
|
|
39
|
+
description: 'Optional sub-steps to display'
|
|
40
|
+
},
|
|
41
|
+
icon: {
|
|
42
|
+
description: 'Custom icon to display'
|
|
43
|
+
},
|
|
44
|
+
theme: {
|
|
45
|
+
description: 'Custom theme overrides'
|
|
46
|
+
},
|
|
47
|
+
className: {
|
|
48
|
+
description: 'Additional CSS classes'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
} as Meta<typeof MessageStatus>;
|
|
52
|
+
|
|
53
|
+
type Story = StoryObj<typeof MessageStatus>;
|
|
54
|
+
|
|
55
|
+
export const Loading: Story = {
|
|
56
|
+
render: args => (
|
|
57
|
+
<div className="w-[400px]">
|
|
58
|
+
<MessageStatus {...args} />
|
|
59
|
+
</div>
|
|
60
|
+
)
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const Complete: Story = {
|
|
64
|
+
args: {
|
|
65
|
+
status: 'complete',
|
|
66
|
+
text: 'Analysis complete'
|
|
67
|
+
},
|
|
68
|
+
render: args => (
|
|
69
|
+
<div className="w-[400px]">
|
|
70
|
+
<MessageStatus {...args} />
|
|
71
|
+
</div>
|
|
72
|
+
)
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const Error: Story = {
|
|
76
|
+
args: {
|
|
77
|
+
status: 'error',
|
|
78
|
+
text: 'Failed to analyze request'
|
|
79
|
+
},
|
|
80
|
+
render: args => (
|
|
81
|
+
<div className="w-[400px]">
|
|
82
|
+
<MessageStatus {...args} />
|
|
83
|
+
</div>
|
|
84
|
+
)
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const WithSteps: Story = {
|
|
88
|
+
args: {
|
|
89
|
+
text: 'Processing your code...',
|
|
90
|
+
steps: [
|
|
91
|
+
{ id: '1', text: 'Reading file contents', status: 'complete' },
|
|
92
|
+
{ id: '2', text: 'Analyzing dependencies', status: 'complete' },
|
|
93
|
+
{ id: '3', text: 'Running linter checks', status: 'loading' },
|
|
94
|
+
{ id: '4', text: 'Generating suggestions', status: 'loading' }
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
render: args => (
|
|
98
|
+
<div className="w-[400px]">
|
|
99
|
+
<MessageStatus {...args} />
|
|
100
|
+
</div>
|
|
101
|
+
)
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const WithStepsComplete: Story = {
|
|
105
|
+
args: {
|
|
106
|
+
status: 'complete',
|
|
107
|
+
text: 'Code analysis complete',
|
|
108
|
+
steps: [
|
|
109
|
+
{ id: '1', text: 'Reading file contents', status: 'complete' },
|
|
110
|
+
{ id: '2', text: 'Analyzing dependencies', status: 'complete' },
|
|
111
|
+
{ id: '3', text: 'Running linter checks', status: 'complete' },
|
|
112
|
+
{ id: '4', text: 'Generating suggestions', status: 'complete' }
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
render: args => (
|
|
116
|
+
<div className="w-[400px]">
|
|
117
|
+
<MessageStatus {...args} />
|
|
118
|
+
</div>
|
|
119
|
+
)
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const WithStepsError: Story = {
|
|
123
|
+
args: {
|
|
124
|
+
status: 'error',
|
|
125
|
+
text: 'Analysis failed',
|
|
126
|
+
steps: [
|
|
127
|
+
{ id: '1', text: 'Reading file contents', status: 'complete' },
|
|
128
|
+
{ id: '2', text: 'Analyzing dependencies', status: 'complete' },
|
|
129
|
+
{ id: '3', text: 'Running linter checks', status: 'error' }
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
|
+
render: args => (
|
|
133
|
+
<div className="w-[400px]">
|
|
134
|
+
<MessageStatus {...args} />
|
|
135
|
+
</div>
|
|
136
|
+
)
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export const AllStates: Story = {
|
|
140
|
+
render: () => (
|
|
141
|
+
<div className="w-[400px] space-y-4">
|
|
142
|
+
<MessageStatus status="loading" text="Searching files..." />
|
|
143
|
+
<MessageStatus status="complete" text="Search complete" />
|
|
144
|
+
<MessageStatus status="error" text="Search failed" />
|
|
145
|
+
</div>
|
|
146
|
+
)
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export const InteractiveDemo: Story = {
|
|
150
|
+
render: () => {
|
|
151
|
+
const [status, setStatus] = useState<MessageStatusState>('loading');
|
|
152
|
+
const [steps, setSteps] = useState<MessageStatusStep[]>([
|
|
153
|
+
{ id: '1', text: 'Searching codebase', status: 'loading' },
|
|
154
|
+
{ id: '2', text: 'Analyzing results', status: 'loading' },
|
|
155
|
+
{ id: '3', text: 'Generating response', status: 'loading' }
|
|
156
|
+
]);
|
|
157
|
+
const [currentStep, setCurrentStep] = useState(0);
|
|
158
|
+
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
const interval = setInterval(() => {
|
|
161
|
+
setCurrentStep(prev => {
|
|
162
|
+
const next = prev + 1;
|
|
163
|
+
if (next > steps.length) {
|
|
164
|
+
setStatus('complete');
|
|
165
|
+
clearInterval(interval);
|
|
166
|
+
return prev;
|
|
167
|
+
}
|
|
168
|
+
setSteps(prevSteps =>
|
|
169
|
+
prevSteps.map((step, idx) => ({
|
|
170
|
+
...step,
|
|
171
|
+
status: idx < next ? 'complete' : 'loading'
|
|
172
|
+
}))
|
|
173
|
+
);
|
|
174
|
+
return next;
|
|
175
|
+
});
|
|
176
|
+
}, 1500);
|
|
177
|
+
|
|
178
|
+
return () => clearInterval(interval);
|
|
179
|
+
}, []);
|
|
180
|
+
|
|
181
|
+
const statusText =
|
|
182
|
+
status === 'complete'
|
|
183
|
+
? 'Task completed successfully'
|
|
184
|
+
: 'Processing your request...';
|
|
185
|
+
|
|
186
|
+
return (
|
|
187
|
+
<div className="w-[400px]">
|
|
188
|
+
<MessageStatus status={status} text={statusText} steps={steps} />
|
|
189
|
+
</div>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export const ToolUsageExample: Story = {
|
|
195
|
+
render: () => {
|
|
196
|
+
const [steps, setSteps] = useState<MessageStatusStep[]>([]);
|
|
197
|
+
const [status, setStatus] = useState<MessageStatusState>('loading');
|
|
198
|
+
const [text, setText] = useState('Starting tool execution...');
|
|
199
|
+
|
|
200
|
+
useEffect(() => {
|
|
201
|
+
const timeline = [
|
|
202
|
+
{
|
|
203
|
+
delay: 500,
|
|
204
|
+
action: () => {
|
|
205
|
+
setText('Using Read tool...');
|
|
206
|
+
setSteps([{ id: '1', text: 'Reading package.json', status: 'loading' as const }]);
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
delay: 1500,
|
|
211
|
+
action: () => {
|
|
212
|
+
setSteps(prev =>
|
|
213
|
+
prev.map(s => (s.id === '1' ? { ...s, status: 'complete' as const } : s))
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
delay: 2000,
|
|
219
|
+
action: () => {
|
|
220
|
+
setText('Using Grep tool...');
|
|
221
|
+
setSteps(prev => [
|
|
222
|
+
...prev,
|
|
223
|
+
{ id: '2', text: 'Searching for imports', status: 'loading' as const }
|
|
224
|
+
]);
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
delay: 3500,
|
|
229
|
+
action: () => {
|
|
230
|
+
setSteps(prev =>
|
|
231
|
+
prev.map(s => (s.id === '2' ? { ...s, status: 'complete' as const } : s))
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
delay: 4000,
|
|
237
|
+
action: () => {
|
|
238
|
+
setText('Using Edit tool...');
|
|
239
|
+
setSteps(prev => [
|
|
240
|
+
...prev,
|
|
241
|
+
{ id: '3', text: 'Modifying source file', status: 'loading' as const }
|
|
242
|
+
]);
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
delay: 5500,
|
|
247
|
+
action: () => {
|
|
248
|
+
setSteps(prev =>
|
|
249
|
+
prev.map(s => (s.id === '3' ? { ...s, status: 'complete' as const } : s))
|
|
250
|
+
);
|
|
251
|
+
setText('Tools completed');
|
|
252
|
+
setStatus('complete');
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
];
|
|
256
|
+
|
|
257
|
+
const timeouts = timeline.map(item =>
|
|
258
|
+
setTimeout(item.action, item.delay)
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
return () => timeouts.forEach(clearTimeout);
|
|
262
|
+
}, []);
|
|
263
|
+
|
|
264
|
+
return (
|
|
265
|
+
<div className="w-[400px]">
|
|
266
|
+
<MessageStatus status={status} text={text} steps={steps} />
|
|
267
|
+
</div>
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
export const MultipleStatuses: Story = {
|
|
273
|
+
render: () => (
|
|
274
|
+
<div className="w-[500px] space-y-3">
|
|
275
|
+
<MessageStatus
|
|
276
|
+
status="complete"
|
|
277
|
+
text="Read src/index.ts"
|
|
278
|
+
steps={[
|
|
279
|
+
{ id: '1', text: '156 lines read', status: 'complete' }
|
|
280
|
+
]}
|
|
281
|
+
/>
|
|
282
|
+
<MessageStatus
|
|
283
|
+
status="complete"
|
|
284
|
+
text="Grep for dependencies"
|
|
285
|
+
steps={[
|
|
286
|
+
{ id: '1', text: 'Found 12 matches', status: 'complete' }
|
|
287
|
+
]}
|
|
288
|
+
/>
|
|
289
|
+
<MessageStatus
|
|
290
|
+
status="loading"
|
|
291
|
+
text="Analyzing code patterns"
|
|
292
|
+
steps={[
|
|
293
|
+
{ id: '1', text: 'Parsing AST', status: 'complete' },
|
|
294
|
+
{ id: '2', text: 'Finding patterns', status: 'loading' }
|
|
295
|
+
]}
|
|
296
|
+
/>
|
|
297
|
+
</div>
|
|
298
|
+
)
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
export const CustomStyling: Story = {
|
|
302
|
+
args: {
|
|
303
|
+
text: 'Custom styled status',
|
|
304
|
+
className: 'bg-gradient-to-r from-purple-500/10 to-blue-500/10 border-purple-500/30'
|
|
305
|
+
},
|
|
306
|
+
render: args => (
|
|
307
|
+
<div className="w-[400px]">
|
|
308
|
+
<MessageStatus {...args} />
|
|
309
|
+
</div>
|
|
310
|
+
)
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
export const LongText: Story = {
|
|
314
|
+
args: {
|
|
315
|
+
text: 'Analyzing complex codebase with multiple files and dependencies to generate comprehensive suggestions',
|
|
316
|
+
steps: [
|
|
317
|
+
{ id: '1', text: 'Scanning src/components directory for React components', status: 'complete' },
|
|
318
|
+
{ id: '2', text: 'Analyzing TypeScript interfaces and type definitions', status: 'loading' }
|
|
319
|
+
]
|
|
320
|
+
},
|
|
321
|
+
render: args => (
|
|
322
|
+
<div className="w-[400px]">
|
|
323
|
+
<MessageStatus {...args} />
|
|
324
|
+
</div>
|
|
325
|
+
)
|
|
326
|
+
};
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import type { Meta } from '@storybook/react';
|
|
2
|
+
import { subDays } from 'date-fns';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
Chat,
|
|
6
|
+
ChatInput,
|
|
7
|
+
NewSessionButton,
|
|
8
|
+
type Session,
|
|
9
|
+
SessionGroups,
|
|
10
|
+
SessionListItem,
|
|
11
|
+
SessionMessagePanel,
|
|
12
|
+
SessionMessages,
|
|
13
|
+
SessionMessagesHeader,
|
|
14
|
+
SessionsGroup,
|
|
15
|
+
SessionsList
|
|
16
|
+
} from 'reachat';
|
|
17
|
+
import { fakeSessions } from './examples';
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
title: 'Demos/SessionList',
|
|
21
|
+
component: SessionsList
|
|
22
|
+
} as Meta;
|
|
23
|
+
|
|
24
|
+
export const DefaultSession = () => {
|
|
25
|
+
return (
|
|
26
|
+
<div
|
|
27
|
+
className="dark:bg-(--color-background-basic-black) bg-(--color-background-basic-white)"
|
|
28
|
+
style={{
|
|
29
|
+
position: 'absolute',
|
|
30
|
+
top: 0,
|
|
31
|
+
left: 0,
|
|
32
|
+
right: 0,
|
|
33
|
+
bottom: 0,
|
|
34
|
+
padding: 20,
|
|
35
|
+
margin: 20,
|
|
36
|
+
borderRadius: 5
|
|
37
|
+
}}
|
|
38
|
+
>
|
|
39
|
+
<Chat
|
|
40
|
+
viewType="console"
|
|
41
|
+
sessions={fakeSessions}
|
|
42
|
+
activeSessionId="1"
|
|
43
|
+
onDeleteSession={() => alert('delete!')}
|
|
44
|
+
>
|
|
45
|
+
<SessionsList>
|
|
46
|
+
<NewSessionButton />
|
|
47
|
+
<SessionGroups />
|
|
48
|
+
</SessionsList>
|
|
49
|
+
|
|
50
|
+
<SessionMessagePanel>
|
|
51
|
+
<SessionMessagesHeader />
|
|
52
|
+
<SessionMessages />
|
|
53
|
+
<ChatInput />
|
|
54
|
+
</SessionMessagePanel>
|
|
55
|
+
</Chat>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const UndeleteableSessions = () => {
|
|
61
|
+
return (
|
|
62
|
+
<div
|
|
63
|
+
className="dark:bg-(--color-background-basic-black) bg-(--color-background-basic-white)"
|
|
64
|
+
style={{
|
|
65
|
+
position: 'absolute',
|
|
66
|
+
top: 0,
|
|
67
|
+
left: 0,
|
|
68
|
+
right: 0,
|
|
69
|
+
bottom: 0,
|
|
70
|
+
padding: 20,
|
|
71
|
+
margin: 20,
|
|
72
|
+
borderRadius: 5
|
|
73
|
+
}}
|
|
74
|
+
>
|
|
75
|
+
<Chat viewType="console" sessions={fakeSessions} activeSessionId="1">
|
|
76
|
+
<SessionsList>
|
|
77
|
+
<NewSessionButton />
|
|
78
|
+
<SessionGroups>
|
|
79
|
+
{groups =>
|
|
80
|
+
groups.map(({ heading, sessions }) => (
|
|
81
|
+
<SessionsGroup heading={heading} key={heading}>
|
|
82
|
+
{sessions.map(s => (
|
|
83
|
+
<SessionListItem key={s.id} session={s} deletable={false} />
|
|
84
|
+
))}
|
|
85
|
+
</SessionsGroup>
|
|
86
|
+
))
|
|
87
|
+
}
|
|
88
|
+
</SessionGroups>
|
|
89
|
+
</SessionsList>
|
|
90
|
+
|
|
91
|
+
<SessionMessagePanel>
|
|
92
|
+
<SessionMessagesHeader />
|
|
93
|
+
<SessionMessages />
|
|
94
|
+
<ChatInput />
|
|
95
|
+
</SessionMessagePanel>
|
|
96
|
+
</Chat>
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const HundredSessions = () => {
|
|
102
|
+
const generateFakeSessions = (count: number): Session[] => {
|
|
103
|
+
return Array.from({ length: count }, (_, index) => ({
|
|
104
|
+
id: `session-${index + 1}`,
|
|
105
|
+
title: `Session ${index + 1}`,
|
|
106
|
+
createdAt: subDays(new Date(), index),
|
|
107
|
+
updatedAt: subDays(new Date(), index),
|
|
108
|
+
conversations: [
|
|
109
|
+
{
|
|
110
|
+
id: `conv-${index}-1`,
|
|
111
|
+
question: `Question for session ${index + 1}`,
|
|
112
|
+
response: `Response for session ${index + 1}`,
|
|
113
|
+
createdAt: subDays(new Date(), index),
|
|
114
|
+
updatedAt: subDays(new Date(), index)
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}));
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const hundredSessions = generateFakeSessions(100);
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<div
|
|
124
|
+
className="dark:bg-(--color-background-basic-black) bg-(--color-background-basic-white)"
|
|
125
|
+
style={{
|
|
126
|
+
position: 'absolute',
|
|
127
|
+
top: 0,
|
|
128
|
+
left: 0,
|
|
129
|
+
right: 0,
|
|
130
|
+
bottom: 0,
|
|
131
|
+
padding: 20,
|
|
132
|
+
margin: 20,
|
|
133
|
+
borderRadius: 5
|
|
134
|
+
}}
|
|
135
|
+
>
|
|
136
|
+
<Chat viewType="console" sessions={hundredSessions}>
|
|
137
|
+
<SessionsList>
|
|
138
|
+
<NewSessionButton />
|
|
139
|
+
<SessionGroups />
|
|
140
|
+
</SessionsList>
|
|
141
|
+
|
|
142
|
+
<SessionMessagePanel>
|
|
143
|
+
<SessionMessagesHeader />
|
|
144
|
+
<SessionMessages />
|
|
145
|
+
<ChatInput />
|
|
146
|
+
</SessionMessagePanel>
|
|
147
|
+
</Chat>
|
|
148
|
+
</div>
|
|
149
|
+
);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export const LongSessionNames = () => {
|
|
153
|
+
const generateFakeSessionsWithLongNames = (count: number) => {
|
|
154
|
+
return Array.from({ length: count }, (_, index) => ({
|
|
155
|
+
id: `session-${index + 1}`,
|
|
156
|
+
title: `Session ${index + 1}: This is a very long session name to test how the UI handles overflow and text wrapping in the session list. It should be truncated or wrapped appropriately to ensure a good user experience.`,
|
|
157
|
+
createdAt: subDays(new Date(), count - index),
|
|
158
|
+
updatedAt: new Date(),
|
|
159
|
+
conversations: [
|
|
160
|
+
{
|
|
161
|
+
id: '1',
|
|
162
|
+
question:
|
|
163
|
+
'Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics?',
|
|
164
|
+
response:
|
|
165
|
+
'Can you provide an in-depth explanation of the theory of relativity, including its historical context, key principles, mathematical foundations, experimental evidence, and its implications for our understanding of space, time, and gravity? Additionally, how does it relate to quantum mechanics, and what are the current challenges in reconciling these two fundamental theories of physics?',
|
|
166
|
+
createdAt: new Date(),
|
|
167
|
+
updatedAt: new Date()
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
}));
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const sessionsWithLongNames = generateFakeSessionsWithLongNames(10);
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<div
|
|
177
|
+
className="dark:bg-(--color-background-basic-black) bg-(--color-background-basic-white)"
|
|
178
|
+
style={{
|
|
179
|
+
position: 'absolute',
|
|
180
|
+
top: 0,
|
|
181
|
+
left: 0,
|
|
182
|
+
right: 0,
|
|
183
|
+
bottom: 0,
|
|
184
|
+
padding: 20,
|
|
185
|
+
margin: 20,
|
|
186
|
+
borderRadius: 5
|
|
187
|
+
}}
|
|
188
|
+
>
|
|
189
|
+
<Chat
|
|
190
|
+
viewType="console"
|
|
191
|
+
sessions={sessionsWithLongNames}
|
|
192
|
+
activeSessionId="session-10"
|
|
193
|
+
>
|
|
194
|
+
<SessionsList>
|
|
195
|
+
<NewSessionButton />
|
|
196
|
+
<SessionGroups />
|
|
197
|
+
</SessionsList>
|
|
198
|
+
|
|
199
|
+
<SessionMessagePanel>
|
|
200
|
+
<SessionMessagesHeader />
|
|
201
|
+
<SessionMessages />
|
|
202
|
+
<ChatInput />
|
|
203
|
+
</SessionMessagePanel>
|
|
204
|
+
</Chat>
|
|
205
|
+
</div>
|
|
206
|
+
);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
export const SessionGrouping = () => {
|
|
210
|
+
const createSessionWithDate = (
|
|
211
|
+
id: string,
|
|
212
|
+
title: string,
|
|
213
|
+
daysAgo: number
|
|
214
|
+
): Session => ({
|
|
215
|
+
id,
|
|
216
|
+
title,
|
|
217
|
+
createdAt: subDays(new Date(), daysAgo),
|
|
218
|
+
updatedAt: subDays(new Date(), daysAgo),
|
|
219
|
+
conversations: [
|
|
220
|
+
{
|
|
221
|
+
id: `${id}-1`,
|
|
222
|
+
question: 'Sample question',
|
|
223
|
+
response: 'Sample response',
|
|
224
|
+
createdAt: subDays(new Date(), daysAgo),
|
|
225
|
+
updatedAt: subDays(new Date(), daysAgo)
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
const sessionsWithVariousDates: Session[] = [
|
|
231
|
+
createSessionWithDate('1', 'Today Session', 0),
|
|
232
|
+
createSessionWithDate('2', 'Yesterday Session', 1),
|
|
233
|
+
createSessionWithDate('3', 'Yesterday Session 2', 1),
|
|
234
|
+
createSessionWithDate('4', 'Last Week Session', 6),
|
|
235
|
+
createSessionWithDate('5', 'Two Weeks Ago Session', 14),
|
|
236
|
+
createSessionWithDate('6', 'Last Month Session', 32),
|
|
237
|
+
createSessionWithDate('7', 'Two Months Ago Session', 65),
|
|
238
|
+
createSessionWithDate('8', 'Six Months Ago Session', 180),
|
|
239
|
+
createSessionWithDate('9', 'Last Year Session', 370),
|
|
240
|
+
createSessionWithDate('10', 'Two Years Ago Session', 740)
|
|
241
|
+
];
|
|
242
|
+
|
|
243
|
+
return (
|
|
244
|
+
<div
|
|
245
|
+
className="dark:bg-(--color-background-basic-black) bg-(--color-background-basic-white)"
|
|
246
|
+
style={{
|
|
247
|
+
position: 'absolute',
|
|
248
|
+
top: 0,
|
|
249
|
+
left: 0,
|
|
250
|
+
right: 0,
|
|
251
|
+
bottom: 0,
|
|
252
|
+
padding: 20,
|
|
253
|
+
margin: 20,
|
|
254
|
+
borderRadius: 5
|
|
255
|
+
}}
|
|
256
|
+
>
|
|
257
|
+
<Chat
|
|
258
|
+
viewType="console"
|
|
259
|
+
sessions={sessionsWithVariousDates}
|
|
260
|
+
isLoading={false}
|
|
261
|
+
onDeleteSession={() => {}}
|
|
262
|
+
>
|
|
263
|
+
<SessionsList>
|
|
264
|
+
<NewSessionButton />
|
|
265
|
+
<SessionGroups />
|
|
266
|
+
</SessionsList>
|
|
267
|
+
|
|
268
|
+
<SessionMessagePanel>
|
|
269
|
+
<SessionMessagesHeader />
|
|
270
|
+
<SessionMessages />
|
|
271
|
+
<ChatInput placeholder="Send a message" />
|
|
272
|
+
</SessionMessagePanel>
|
|
273
|
+
</Chat>
|
|
274
|
+
</div>
|
|
275
|
+
);
|
|
276
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M12 3l1.912 5.813a2 2 0 0 0 1.275 1.275L21 12l-5.813 1.912a2 2 0 0 0-1.275 1.275L12 21l-1.912-5.813a2 2 0 0 0-1.275-1.275L3 12l5.813-1.912a2 2 0 0 0 1.275-1.275L12 3z"/>
|
|
3
|
+
<path d="M5 3v4"/>
|
|
4
|
+
<path d="M3 5h4"/>
|
|
5
|
+
<path d="M19 17v4"/>
|
|
6
|
+
<path d="M17 19h4"/>
|
|
7
|
+
</svg>
|
package/dist/stories/examples.ts
CHANGED
|
@@ -272,3 +272,37 @@ export const chatTemplates = [
|
|
|
272
272
|
icon: 'SendPlane'
|
|
273
273
|
}
|
|
274
274
|
];
|
|
275
|
+
|
|
276
|
+
export const defaultSuggestions = [
|
|
277
|
+
{
|
|
278
|
+
id: '1',
|
|
279
|
+
content: 'Tell me more about this topic'
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
id: '2',
|
|
283
|
+
content: 'Can you provide an example?'
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
id: '3',
|
|
287
|
+
content: 'What are the best practices?'
|
|
288
|
+
}
|
|
289
|
+
];
|
|
290
|
+
|
|
291
|
+
export const sessionWithSuggestions = [
|
|
292
|
+
{
|
|
293
|
+
id: 'session-suggestions',
|
|
294
|
+
title: 'Session with Suggestions',
|
|
295
|
+
createdAt: new Date(),
|
|
296
|
+
updatedAt: new Date(),
|
|
297
|
+
conversations: [
|
|
298
|
+
{
|
|
299
|
+
id: '1',
|
|
300
|
+
question: 'What is React?',
|
|
301
|
+
response:
|
|
302
|
+
'React is a JavaScript library for building user interfaces. It was developed by Facebook and is now maintained by Meta and a community of developers.',
|
|
303
|
+
createdAt: new Date(),
|
|
304
|
+
updatedAt: new Date()
|
|
305
|
+
}
|
|
306
|
+
]
|
|
307
|
+
}
|
|
308
|
+
];
|
package/dist/theme.d.ts
CHANGED
|
@@ -4,6 +4,33 @@ export interface ChatTheme {
|
|
|
4
4
|
companion: string;
|
|
5
5
|
empty: string;
|
|
6
6
|
appbar: string;
|
|
7
|
+
status: {
|
|
8
|
+
base: string;
|
|
9
|
+
header: string;
|
|
10
|
+
icon: {
|
|
11
|
+
base: string;
|
|
12
|
+
loading: string;
|
|
13
|
+
complete: string;
|
|
14
|
+
error: string;
|
|
15
|
+
};
|
|
16
|
+
text: {
|
|
17
|
+
base: string;
|
|
18
|
+
loading: string;
|
|
19
|
+
complete: string;
|
|
20
|
+
error: string;
|
|
21
|
+
};
|
|
22
|
+
steps: {
|
|
23
|
+
base: string;
|
|
24
|
+
step: {
|
|
25
|
+
base: string;
|
|
26
|
+
icon: string;
|
|
27
|
+
text: string;
|
|
28
|
+
loading: string;
|
|
29
|
+
complete: string;
|
|
30
|
+
error: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
};
|
|
7
34
|
sessions: {
|
|
8
35
|
base: string;
|
|
9
36
|
console: string;
|
|
@@ -34,6 +61,10 @@ export interface ChatTheme {
|
|
|
34
61
|
cursor: string;
|
|
35
62
|
overlay: string;
|
|
36
63
|
expand: string;
|
|
64
|
+
scrollToBottom: {
|
|
65
|
+
container: string;
|
|
66
|
+
button: string;
|
|
67
|
+
};
|
|
37
68
|
files: {
|
|
38
69
|
base: string;
|
|
39
70
|
file: {
|
|
@@ -103,6 +134,21 @@ export interface ChatTheme {
|
|
|
103
134
|
send: string;
|
|
104
135
|
stop: string;
|
|
105
136
|
};
|
|
137
|
+
dropzone: {
|
|
138
|
+
base: string;
|
|
139
|
+
active: string;
|
|
140
|
+
overlay: string;
|
|
141
|
+
text: string;
|
|
142
|
+
icon: string;
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
suggestions: {
|
|
146
|
+
base: string;
|
|
147
|
+
item: {
|
|
148
|
+
base: string;
|
|
149
|
+
icon: string;
|
|
150
|
+
text: string;
|
|
151
|
+
};
|
|
106
152
|
};
|
|
107
153
|
}
|
|
108
154
|
export declare const chatTheme: ChatTheme;
|