@kite-copilot/chat-panel 0.2.1 → 0.2.2
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 +236 -369
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
# @kite-copilot/chat-panel
|
|
2
2
|
|
|
3
|
-
An AI-powered chat panel SDK for embedding intelligent chat assistants. This package provides a
|
|
3
|
+
An AI-powered chat panel SDK for embedding intelligent chat assistants. This package provides a **side panel** interface that integrates with any AI backend agent. The panel slides in from the right edge and automatically adjusts page content - no layout changes required.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
7
|
+
- **Side Panel UX**: Slides in from the right edge, pushes page content (no overlay)
|
|
8
|
+
- **Zero-Config**: Drop-in integration - no layout changes required from host apps
|
|
9
|
+
- **AI-Powered Chat**: Connects to your AI backend agent for intelligent responses
|
|
10
|
+
- **CSV Bulk Operations**: Upload CSV files for bulk data processing
|
|
11
|
+
- **Interactive Guides**: Built-in guided tours with animated cursor
|
|
12
|
+
- **Dynamic Starting Questions**: Customizable per-user questions from backend
|
|
13
|
+
- **Customizable Themes**: Light and dark mode support
|
|
14
|
+
- **Responsive Design**: Works on desktop and mobile
|
|
15
|
+
- **Easy Integration**: Programmatic API or React component
|
|
16
|
+
- **PWA-Ready**: Fully bundled by your build tool, no CDN required
|
|
17
|
+
- **Offline-Safe**: Works with service workers and precaching
|
|
15
18
|
|
|
16
19
|
## Installation
|
|
17
20
|
|
|
@@ -47,129 +50,142 @@ const chat = createKiteChat({
|
|
|
47
50
|
orgId: 'org-456',
|
|
48
51
|
agentUrl: 'https://your-api.example.com',
|
|
49
52
|
onNavigate: (page, subtab) => {
|
|
50
|
-
// Handle navigation requests from the chat
|
|
51
53
|
router.push(`/${page}${subtab ? `?tab=${subtab}` : ''}`);
|
|
52
54
|
},
|
|
53
|
-
onActionComplete: (actionType, data) => {
|
|
54
|
-
console.log('Action completed:', actionType, data);
|
|
55
|
-
},
|
|
56
55
|
});
|
|
57
56
|
|
|
58
|
-
// Mount
|
|
59
|
-
chat.mount(
|
|
57
|
+
// Mount - that's it! No container needed, panel handles its own positioning
|
|
58
|
+
chat.mount(document.body);
|
|
59
|
+
|
|
60
|
+
// Control the panel programmatically
|
|
61
|
+
chat.open(); // Open the side panel
|
|
62
|
+
chat.close(); // Close the side panel
|
|
63
|
+
chat.toggle(); // Toggle open/closed
|
|
64
|
+
|
|
65
|
+
// Check state
|
|
66
|
+
if (chat.isOpen()) {
|
|
67
|
+
console.log('Panel is open');
|
|
68
|
+
}
|
|
60
69
|
|
|
61
|
-
// Update
|
|
70
|
+
// Update context as user navigates
|
|
62
71
|
chat.setCurrentPage('settings');
|
|
63
|
-
chat.updateConfig({ theme: 'dark' });
|
|
64
72
|
|
|
65
73
|
// Clean up when done
|
|
66
74
|
chat.unmount();
|
|
67
75
|
```
|
|
68
76
|
|
|
69
|
-
###
|
|
77
|
+
### Vanilla HTML/JavaScript (Easiest)
|
|
70
78
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
import '@kite-copilot/chat-panel/style.css';
|
|
76
|
-
|
|
77
|
-
const chat = mountKiteChat({
|
|
78
|
-
container: '#chat-container',
|
|
79
|
+
```html
|
|
80
|
+
<!-- No special container or layout needed! -->
|
|
81
|
+
<script>
|
|
82
|
+
window.KiteChatConfig = {
|
|
79
83
|
userId: 'user-123',
|
|
80
84
|
orgId: 'org-456',
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
chat.
|
|
85
|
+
agentUrl: 'https://your-api.example.com'
|
|
86
|
+
};
|
|
87
|
+
</script>
|
|
88
|
+
<script src="https://cdn.example.com/kite-chat.js"></script>
|
|
85
89
|
```
|
|
86
90
|
|
|
91
|
+
That's it! The panel automatically:
|
|
92
|
+
- Adds a toggle arrow (◀) to the right edge of the page
|
|
93
|
+
- Slides in when clicked, pushing page content left
|
|
94
|
+
- Manages `padding-right` on the body element
|
|
95
|
+
|
|
87
96
|
### React Component
|
|
88
97
|
|
|
89
|
-
For React applications, use the component
|
|
98
|
+
For React applications, use the `ChatPanelWithToggle` component:
|
|
90
99
|
|
|
91
100
|
```tsx
|
|
92
|
-
import {
|
|
101
|
+
import { ChatPanelWithToggle } from '@kite-copilot/chat-panel';
|
|
93
102
|
import '@kite-copilot/chat-panel/style.css';
|
|
94
103
|
|
|
95
104
|
function App() {
|
|
96
|
-
const { userId, orgId } = useAuth();
|
|
97
|
-
|
|
98
105
|
return (
|
|
99
|
-
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
106
|
+
<>
|
|
107
|
+
<YourExistingApp />
|
|
108
|
+
{/* Just add this - no layout changes needed */}
|
|
109
|
+
<ChatPanelWithToggle
|
|
110
|
+
agentUrl="https://your-api.example.com"
|
|
111
|
+
onNavigate={(page) => router.push(`/${page}`)}
|
|
112
|
+
/>
|
|
113
|
+
</>
|
|
103
114
|
);
|
|
104
115
|
}
|
|
105
116
|
```
|
|
106
117
|
|
|
107
|
-
|
|
118
|
+
For controlled mode:
|
|
108
119
|
|
|
109
|
-
|
|
120
|
+
```tsx
|
|
121
|
+
import { useState } from 'react';
|
|
122
|
+
import { ChatPanelWithToggle } from '@kite-copilot/chat-panel';
|
|
110
123
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
124
|
+
function App() {
|
|
125
|
+
const [isPanelOpen, setIsPanelOpen] = useState(false);
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<>
|
|
129
|
+
<button onClick={() => setIsPanelOpen(true)}>Open Help</button>
|
|
130
|
+
<ChatPanelWithToggle
|
|
131
|
+
isOpen={isPanelOpen}
|
|
132
|
+
onOpenChange={setIsPanelOpen}
|
|
133
|
+
agentUrl="https://your-api.example.com"
|
|
134
|
+
/>
|
|
135
|
+
</>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
```
|
|
116
139
|
|
|
117
|
-
|
|
140
|
+
## How It Works
|
|
118
141
|
|
|
119
|
-
|
|
120
|
-
userId: 'user-123',
|
|
121
|
-
orgId: 'org-456',
|
|
122
|
-
onNavigate: (page) => router.push(`/${page}`),
|
|
123
|
-
});
|
|
142
|
+
The side panel uses fixed positioning and automatically manages the body's `padding-right`:
|
|
124
143
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
144
|
+
```
|
|
145
|
+
┌─────────────────────────────────┐ ┌────────────────────────┬────────┐
|
|
146
|
+
│ │ │ │ │
|
|
147
|
+
│ │ │ │ Side │
|
|
148
|
+
│ Your Page Content │ → │ Your Page Content │ Panel │
|
|
149
|
+
│ │ │ (shifted left) │ │
|
|
150
|
+
│ [◀] │ │ [▶] │ │
|
|
151
|
+
└─────────────────────────────────┘ └────────────────────────┴────────┘
|
|
152
|
+
Panel Closed Panel Open
|
|
128
153
|
```
|
|
129
154
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
// chat.service.ts
|
|
134
|
-
import { Injectable, OnDestroy } from '@angular/core';
|
|
135
|
-
import { createKiteChat, KiteChatInstance } from '@kite-copilot/chat-panel';
|
|
155
|
+
- **Closed**: Only the toggle arrow (◀) is visible on the right edge
|
|
156
|
+
- **Open**: Panel slides in, toggle becomes (▶), body gets `padding-right: 400px`
|
|
157
|
+
- **No overlays**: Content is pushed, not covered
|
|
136
158
|
|
|
137
|
-
|
|
138
|
-
export class ChatService implements OnDestroy {
|
|
139
|
-
private chat: KiteChatInstance;
|
|
159
|
+
## Dynamic Starting Questions
|
|
140
160
|
|
|
141
|
-
|
|
142
|
-
this.chat = createKiteChat({
|
|
143
|
-
userId: 'user-123',
|
|
144
|
-
orgId: 'org-456',
|
|
145
|
-
onNavigate: (page) => this.router.navigate([page]),
|
|
146
|
-
});
|
|
147
|
-
}
|
|
161
|
+
The panel shows suggested questions when empty. These can be customized per-user:
|
|
148
162
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
163
|
+
```ts
|
|
164
|
+
// Option 1: Pass questions directly
|
|
165
|
+
const chat = createKiteChat({
|
|
166
|
+
userId: 'user-123',
|
|
167
|
+
orgId: 'org-456',
|
|
168
|
+
startingQuestions: [
|
|
169
|
+
{ id: '1', label: 'Changing layouts', prompt: 'How do I customize the layout?' },
|
|
170
|
+
{ id: '2', label: 'Bulk uploads', prompt: 'How do I upload data in bulk?' },
|
|
171
|
+
{ id: '3', label: 'Example setups', prompt: 'Show me example configurations' },
|
|
172
|
+
],
|
|
173
|
+
});
|
|
152
174
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
175
|
+
// Option 2: Fetch from backend (per-user)
|
|
176
|
+
const chat = createKiteChat({
|
|
177
|
+
userId: 'user-123',
|
|
178
|
+
orgId: 'org-456',
|
|
179
|
+
startingQuestionsEndpoint: '/api/user/starting-questions',
|
|
180
|
+
});
|
|
157
181
|
```
|
|
158
182
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const chat = createKiteChat({
|
|
167
|
-
userId: 'user-123',
|
|
168
|
-
orgId: 'org-456',
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
chat.mount('#chat-container');
|
|
172
|
-
</script>
|
|
183
|
+
The endpoint should return:
|
|
184
|
+
```json
|
|
185
|
+
[
|
|
186
|
+
{ "id": "1", "label": "Question label", "prompt": "Full prompt to send" },
|
|
187
|
+
{ "id": "2", "label": "Another question", "prompt": "Another prompt" }
|
|
188
|
+
]
|
|
173
189
|
```
|
|
174
190
|
|
|
175
191
|
## API Reference
|
|
@@ -187,6 +203,8 @@ Creates a new chat instance with explicit lifecycle control.
|
|
|
187
203
|
| `agentUrl` | `string` | No | Backend agent API URL |
|
|
188
204
|
| `currentPage` | `string` | No | Current page context |
|
|
189
205
|
| `theme` | `'light' \| 'dark' \| 'system'` | No | Theme preference |
|
|
206
|
+
| `startingQuestions` | `StartingQuestion[]` | No | Custom starting questions |
|
|
207
|
+
| `startingQuestionsEndpoint` | `string` | No | URL to fetch per-user questions |
|
|
190
208
|
| `onNavigate` | `(page: string, subtab?: string) => void` | No | Navigation callback |
|
|
191
209
|
| `onActionComplete` | `(actionType: string, data: any) => void` | No | Action completion callback |
|
|
192
210
|
|
|
@@ -194,110 +212,132 @@ Creates a new chat instance with explicit lifecycle control.
|
|
|
194
212
|
|
|
195
213
|
| Method | Description |
|
|
196
214
|
|--------|-------------|
|
|
197
|
-
| `mount(container)` | Mount the chat widget
|
|
215
|
+
| `mount(container)` | Mount the chat widget (container is just a React mount point) |
|
|
198
216
|
| `unmount()` | Unmount and clean up the chat widget |
|
|
217
|
+
| `open()` | Open the side panel |
|
|
218
|
+
| `close()` | Close the side panel |
|
|
219
|
+
| `toggle()` | Toggle the panel open/closed |
|
|
220
|
+
| `isOpen()` | Check if the panel is currently open |
|
|
199
221
|
| `setCurrentPage(page)` | Update the current page context |
|
|
200
222
|
| `updateConfig(config)` | Update configuration options |
|
|
201
223
|
| `isMounted()` | Check if the widget is currently mounted |
|
|
202
224
|
|
|
203
|
-
|
|
225
|
+
### ChatPanelWithToggle (React)
|
|
204
226
|
|
|
205
|
-
|
|
227
|
+
The recommended React component with integrated toggle button.
|
|
206
228
|
|
|
207
|
-
|
|
229
|
+
```tsx
|
|
230
|
+
import { ChatPanelWithToggle } from '@kite-copilot/chat-panel';
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
#### Props
|
|
234
|
+
|
|
235
|
+
| Prop | Type | Default | Description |
|
|
236
|
+
|------|------|---------|-------------|
|
|
237
|
+
| `agentUrl` | `string` | `localhost:5002` | Backend agent URL |
|
|
238
|
+
| `currentPage` | `string` | - | Current page for context |
|
|
239
|
+
| `defaultOpen` | `boolean` | `false` | Initial open state (uncontrolled) |
|
|
240
|
+
| `isOpen` | `boolean` | - | Controlled open state |
|
|
241
|
+
| `onOpenChange` | `(isOpen: boolean) => void` | - | Called when open state changes |
|
|
242
|
+
| `startingQuestions` | `StartingQuestion[]` | - | Custom starting questions |
|
|
243
|
+
| `startingQuestionsEndpoint` | `string` | - | URL to fetch questions |
|
|
244
|
+
| `onNavigate` | `(page, subtab?) => void` | - | Navigation callback |
|
|
245
|
+
| `onActionComplete` | `(type, data) => void` | - | Action completion callback |
|
|
246
|
+
|
|
247
|
+
### Low-Level Components
|
|
248
|
+
|
|
249
|
+
For advanced customization, you can use the individual components:
|
|
208
250
|
|
|
209
251
|
```tsx
|
|
210
|
-
import { ChatPanel,
|
|
211
|
-
import '@kite-copilot/chat-panel/style.css'
|
|
252
|
+
import { ChatPanel, PanelToggle } from '@kite-copilot/chat-panel';
|
|
212
253
|
|
|
213
|
-
function
|
|
214
|
-
|
|
215
|
-
const { userId, orgId } = useAuth()
|
|
254
|
+
function CustomPanel() {
|
|
255
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
216
256
|
|
|
217
257
|
return (
|
|
218
|
-
|
|
219
|
-
<
|
|
220
|
-
<ChatPanel />
|
|
221
|
-
|
|
222
|
-
)
|
|
258
|
+
<>
|
|
259
|
+
<PanelToggle isOpen={isOpen} onClick={() => setIsOpen(!isOpen)} />
|
|
260
|
+
<ChatPanel isOpen={isOpen} onClose={() => setIsOpen(false)} />
|
|
261
|
+
</>
|
|
262
|
+
);
|
|
223
263
|
}
|
|
224
264
|
```
|
|
225
265
|
|
|
226
|
-
|
|
266
|
+
## Framework Examples
|
|
227
267
|
|
|
228
|
-
|
|
229
|
-
import { ChatPanel, ChatPanelProvider } from '@kite-copilot/chat-panel'
|
|
230
|
-
import '@kite-copilot/chat-panel/style.css'
|
|
231
|
-
import { useRouter } from 'next/navigation'
|
|
268
|
+
### Vue.js
|
|
232
269
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
const [currentPage, setCurrentPage] = useState('dashboard')
|
|
270
|
+
```ts
|
|
271
|
+
import { createKiteChat } from '@kite-copilot/chat-panel';
|
|
272
|
+
import '@kite-copilot/chat-panel/style.css';
|
|
237
273
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
onNavigate={(page, subtab) => {
|
|
251
|
-
setCurrentPage(page)
|
|
252
|
-
router.push(`/${page}${subtab ? `?tab=${subtab}` : ''}`)
|
|
253
|
-
}}
|
|
254
|
-
onActionComplete={(actionType, data) => {
|
|
255
|
-
console.log('Action completed:', actionType, data)
|
|
256
|
-
// Refresh your data or perform other side effects
|
|
257
|
-
}}
|
|
258
|
-
/>
|
|
259
|
-
</ChatPanelProvider>
|
|
260
|
-
)
|
|
261
|
-
}
|
|
274
|
+
const chat = createKiteChat({
|
|
275
|
+
userId: 'user-123',
|
|
276
|
+
orgId: 'org-456',
|
|
277
|
+
onNavigate: (page) => router.push(`/${page}`),
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Mount after Vue app is ready
|
|
281
|
+
app.mount('#app');
|
|
282
|
+
chat.mount(document.body);
|
|
283
|
+
|
|
284
|
+
// Open programmatically
|
|
285
|
+
chat.open();
|
|
262
286
|
```
|
|
263
287
|
|
|
264
|
-
|
|
288
|
+
### Angular
|
|
265
289
|
|
|
266
|
-
|
|
290
|
+
```ts
|
|
291
|
+
import { Injectable, OnDestroy } from '@angular/core';
|
|
292
|
+
import { createKiteChat, KiteChatInstance } from '@kite-copilot/chat-panel';
|
|
267
293
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
294
|
+
@Injectable({ providedIn: 'root' })
|
|
295
|
+
export class ChatService implements OnDestroy {
|
|
296
|
+
private chat: KiteChatInstance;
|
|
271
297
|
|
|
272
|
-
|
|
298
|
+
constructor(private router: Router) {
|
|
299
|
+
this.chat = createKiteChat({
|
|
300
|
+
userId: 'user-123',
|
|
301
|
+
orgId: 'org-456',
|
|
302
|
+
onNavigate: (page) => this.router.navigate([page]),
|
|
303
|
+
});
|
|
304
|
+
this.chat.mount(document.body);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
open() { this.chat.open(); }
|
|
308
|
+
close() { this.chat.close(); }
|
|
309
|
+
toggle() { this.chat.toggle(); }
|
|
310
|
+
|
|
311
|
+
ngOnDestroy() {
|
|
312
|
+
this.chat.unmount();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
273
316
|
|
|
274
|
-
|
|
275
|
-
|----------|------|---------|-------------|
|
|
276
|
-
| `userId` | `string` | **Required** | User ID of the end user querying the chat panel |
|
|
277
|
-
| `orgId` | `string` | **Required** | Organization ID the user belongs to |
|
|
278
|
-
| `agentUrl` | `string` | Built-in URL | Optional override for agent backend URL (for development/testing only) |
|
|
279
|
-
| `theme` | `'light' \| 'dark' \| 'system'` | `'light'` | Theme preference |
|
|
280
|
-
| `position` | `'bottom-right' \| 'bottom-left' \| 'custom'` | `'bottom-right'` | Panel position |
|
|
281
|
-
| `guides` | `Record<string, GuideWithSteps>` | - | Custom interactive guides |
|
|
282
|
-
| `folders` | `Folder[]` | - | Custom help topic folders |
|
|
283
|
-
| `showDefaultFolders` | `boolean` | `true` | Show default help topics |
|
|
284
|
-
| `enableGuideCursor` | `boolean` | `true` | Enable animated guide cursor |
|
|
285
|
-
| `className` | `string` | - | Custom CSS class |
|
|
317
|
+
### Next.js App Router
|
|
286
318
|
|
|
287
|
-
|
|
319
|
+
```tsx
|
|
320
|
+
// app/layout.tsx
|
|
321
|
+
import { ChatPanelWithToggle } from '@kite-copilot/chat-panel';
|
|
322
|
+
import '@kite-copilot/chat-panel/style.css';
|
|
288
323
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
324
|
+
export default function RootLayout({ children }) {
|
|
325
|
+
return (
|
|
326
|
+
<html>
|
|
327
|
+
<body>
|
|
328
|
+
{children}
|
|
329
|
+
<ChatPanelWithToggle
|
|
330
|
+
agentUrl={process.env.NEXT_PUBLIC_AGENT_URL}
|
|
331
|
+
/>
|
|
332
|
+
</body>
|
|
333
|
+
</html>
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
```
|
|
297
337
|
|
|
298
338
|
## Backend Integration
|
|
299
339
|
|
|
300
|
-
The ChatPanel expects your backend agent to expose the following SSE endpoints.
|
|
340
|
+
The ChatPanel expects your backend agent to expose the following SSE endpoints.
|
|
301
341
|
|
|
302
342
|
### `/chat/stream` (POST)
|
|
303
343
|
|
|
@@ -326,117 +366,33 @@ CSV file upload endpoint for bulk operations.
|
|
|
326
366
|
|
|
327
367
|
**Request:** FormData with `file`, `message`, `session_id`, `user_id`, `org_id`, `current_page`
|
|
328
368
|
|
|
329
|
-
**SSE Events:**
|
|
330
|
-
- `preview`: CSV preview with row count and sample data
|
|
331
|
-
- `error`: Error messages
|
|
332
|
-
|
|
333
369
|
### `/chat/bulk/confirm` (POST)
|
|
334
370
|
|
|
335
371
|
Confirm and execute bulk operation.
|
|
336
372
|
|
|
337
|
-
|
|
338
|
-
```json
|
|
339
|
-
{
|
|
340
|
-
"session_id": "uuid",
|
|
341
|
-
"user_id": "user-123",
|
|
342
|
-
"org_id": "org-456",
|
|
343
|
-
"bulk_session_id": "bulk-uuid"
|
|
344
|
-
}
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
**SSE Events:**
|
|
348
|
-
- `progress`: Row-by-row processing updates
|
|
349
|
-
- `summary`: Final results with success/failure counts
|
|
350
|
-
- `error`: Error messages
|
|
351
|
-
|
|
352
|
-
## Custom Guides
|
|
353
|
-
|
|
354
|
-
You can add custom interactive guides:
|
|
373
|
+
### `/api/user/starting-questions` (GET) - Optional
|
|
355
374
|
|
|
356
|
-
|
|
357
|
-
const customGuides = {
|
|
358
|
-
'my-guide': {
|
|
359
|
-
id: 'my-guide',
|
|
360
|
-
title: 'My Custom Guide',
|
|
361
|
-
steps: [
|
|
362
|
-
{
|
|
363
|
-
text: 'Step 1: Click the button below',
|
|
364
|
-
navigation: { page: 'settings' },
|
|
365
|
-
cursorTarget: {
|
|
366
|
-
selector: '[data-testid="my-button"]',
|
|
367
|
-
onClick: true
|
|
368
|
-
}
|
|
369
|
-
},
|
|
370
|
-
// More steps...
|
|
371
|
-
]
|
|
372
|
-
}
|
|
373
|
-
}
|
|
375
|
+
Return per-user starting questions.
|
|
374
376
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
## Custom Help Topics
|
|
381
|
-
|
|
382
|
-
Add custom help topic folders:
|
|
383
|
-
|
|
384
|
-
```tsx
|
|
385
|
-
const customFolders = [
|
|
386
|
-
{
|
|
387
|
-
id: 'support',
|
|
388
|
-
title: 'Support',
|
|
389
|
-
topics: [
|
|
390
|
-
{
|
|
391
|
-
id: 'contact',
|
|
392
|
-
label: 'Contact Us',
|
|
393
|
-
prompt: 'How can I contact support?'
|
|
394
|
-
}
|
|
395
|
-
]
|
|
396
|
-
}
|
|
377
|
+
**Response:**
|
|
378
|
+
```json
|
|
379
|
+
[
|
|
380
|
+
{ "id": "1", "label": "Changing layouts", "prompt": "How do I change the layout?" },
|
|
381
|
+
{ "id": "2", "label": "Bulk uploads", "prompt": "How do I upload in bulk?" }
|
|
397
382
|
]
|
|
398
|
-
|
|
399
|
-
<ChatPanelProvider config={{ userId, orgId, folders: customFolders }}>
|
|
400
|
-
...
|
|
401
|
-
</ChatPanelProvider>
|
|
402
383
|
```
|
|
403
384
|
|
|
404
385
|
## Styling
|
|
405
386
|
|
|
406
387
|
### Using the Default Styles
|
|
407
388
|
|
|
408
|
-
Import the CSS file in your app:
|
|
409
|
-
|
|
410
389
|
```tsx
|
|
411
|
-
import '@kite-copilot/chat-panel/style.css'
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
### With Tailwind CSS
|
|
415
|
-
|
|
416
|
-
If you're using Tailwind, extend your config with our preset:
|
|
417
|
-
|
|
418
|
-
```js
|
|
419
|
-
// tailwind.config.js
|
|
420
|
-
module.exports = {
|
|
421
|
-
content: [
|
|
422
|
-
// ... your paths
|
|
423
|
-
'./node_modules/@kite-copilot/chat-panel/dist/**/*.{js,mjs}'
|
|
424
|
-
],
|
|
425
|
-
theme: {
|
|
426
|
-
extend: {
|
|
427
|
-
colors: {
|
|
428
|
-
background: "var(--background)",
|
|
429
|
-
foreground: "var(--foreground)",
|
|
430
|
-
// ... other theme colors
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
390
|
+
import '@kite-copilot/chat-panel/style.css';
|
|
435
391
|
```
|
|
436
392
|
|
|
437
393
|
### CSS Variables
|
|
438
394
|
|
|
439
|
-
|
|
395
|
+
Override theme variables in your CSS:
|
|
440
396
|
|
|
441
397
|
```css
|
|
442
398
|
:root {
|
|
@@ -444,13 +400,11 @@ The component uses CSS variables for theming. Override them in your CSS:
|
|
|
444
400
|
--foreground: oklch(0.145 0 0);
|
|
445
401
|
--primary: oklch(0.205 0 0);
|
|
446
402
|
--primary-foreground: oklch(0.985 0 0);
|
|
447
|
-
/* ... more variables */
|
|
448
403
|
}
|
|
449
404
|
|
|
450
405
|
.dark {
|
|
451
406
|
--background: oklch(0.145 0 0);
|
|
452
407
|
--foreground: oklch(0.985 0 0);
|
|
453
|
-
/* ... dark mode overrides */
|
|
454
408
|
}
|
|
455
409
|
```
|
|
456
410
|
|
|
@@ -460,126 +414,39 @@ Full TypeScript support with exported types:
|
|
|
460
414
|
|
|
461
415
|
```tsx
|
|
462
416
|
import type {
|
|
463
|
-
// Programmatic API types
|
|
464
417
|
KiteChatConfig,
|
|
465
418
|
KiteChatInstance,
|
|
466
|
-
// React component types
|
|
467
|
-
ChatPanelConfig,
|
|
468
419
|
ChatPanelProps,
|
|
420
|
+
ChatPanelWithToggleProps,
|
|
421
|
+
PanelToggleProps,
|
|
422
|
+
StartingQuestion,
|
|
469
423
|
ActionType,
|
|
470
424
|
ActionData,
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
} from '@kite-copilot/chat-panel'
|
|
425
|
+
Page,
|
|
426
|
+
SettingsTab,
|
|
427
|
+
} from '@kite-copilot/chat-panel';
|
|
475
428
|
```
|
|
476
429
|
|
|
477
|
-
##
|
|
430
|
+
## Migration from Overlay Version
|
|
478
431
|
|
|
479
|
-
|
|
432
|
+
If upgrading from a previous version with overlay/floating panel:
|
|
480
433
|
|
|
481
|
-
|
|
482
|
-
|
|
434
|
+
1. **Remove layout changes**: You no longer need flex containers or special positioning
|
|
435
|
+
2. **Update imports**: Use `ChatPanelWithToggle` instead of `ChatPanel` for the full experience
|
|
436
|
+
3. **Update API calls**: Use `open()`/`close()`/`toggle()` instead of managing `isCollapsed` state
|
|
483
437
|
|
|
484
438
|
```tsx
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
```tsx
|
|
495
|
-
// app/providers.tsx
|
|
496
|
-
'use client'
|
|
497
|
-
|
|
498
|
-
import { ChatPanelProvider } from '@kite-copilot/chat-panel'
|
|
499
|
-
import { useAuth } from './auth' // Your auth provider
|
|
500
|
-
|
|
501
|
-
export function Providers({ children }) {
|
|
502
|
-
const { userId, orgId } = useAuth()
|
|
503
|
-
|
|
504
|
-
return (
|
|
505
|
-
<ChatPanelProvider
|
|
506
|
-
config={{
|
|
507
|
-
userId,
|
|
508
|
-
orgId,
|
|
509
|
-
}}
|
|
510
|
-
>
|
|
511
|
-
{children}
|
|
512
|
-
</ChatPanelProvider>
|
|
513
|
-
)
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// app/layout.tsx
|
|
517
|
-
import { Providers } from './providers'
|
|
518
|
-
import '@kite-copilot/chat-panel/style.css'
|
|
519
|
-
|
|
520
|
-
export default function RootLayout({ children }) {
|
|
521
|
-
return (
|
|
522
|
-
<html>
|
|
523
|
-
<body>
|
|
524
|
-
<Providers>{children}</Providers>
|
|
525
|
-
</body>
|
|
526
|
-
</html>
|
|
527
|
-
)
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
// app/page.tsx
|
|
531
|
-
'use client'
|
|
532
|
-
|
|
533
|
-
import { ChatPanel } from '@kite-copilot/chat-panel'
|
|
534
|
-
|
|
535
|
-
export default function Page() {
|
|
536
|
-
return (
|
|
537
|
-
<main>
|
|
538
|
-
<h1>My App</h1>
|
|
539
|
-
<ChatPanel currentPage="home" />
|
|
540
|
-
</main>
|
|
541
|
-
)
|
|
542
|
-
}
|
|
543
|
-
```
|
|
544
|
-
|
|
545
|
-
### React with React Router
|
|
546
|
-
|
|
547
|
-
```tsx
|
|
548
|
-
import { BrowserRouter, useLocation, useNavigate } from 'react-router-dom'
|
|
549
|
-
import { ChatPanel, ChatPanelProvider } from '@kite-copilot/chat-panel'
|
|
550
|
-
import '@kite-copilot/chat-panel/style.css'
|
|
551
|
-
import { useAuth } from './auth' // Your auth provider
|
|
552
|
-
|
|
553
|
-
function ChatPanelWithRouter() {
|
|
554
|
-
const location = useLocation()
|
|
555
|
-
const navigate = useNavigate()
|
|
556
|
-
const currentPage = location.pathname.slice(1) || 'dashboard'
|
|
557
|
-
|
|
558
|
-
return (
|
|
559
|
-
<ChatPanel
|
|
560
|
-
currentPage={currentPage}
|
|
561
|
-
onNavigate={(page) => navigate(`/${page}`)}
|
|
562
|
-
/>
|
|
563
|
-
)
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
function App() {
|
|
567
|
-
const { userId, orgId } = useAuth()
|
|
568
|
-
|
|
569
|
-
return (
|
|
570
|
-
<BrowserRouter>
|
|
571
|
-
<ChatPanelProvider config={{ userId, orgId }}>
|
|
572
|
-
<Routes>
|
|
573
|
-
{/* Your routes */}
|
|
574
|
-
</Routes>
|
|
575
|
-
<ChatPanelWithRouter />
|
|
576
|
-
</ChatPanelProvider>
|
|
577
|
-
</BrowserRouter>
|
|
578
|
-
)
|
|
579
|
-
}
|
|
439
|
+
// Before (overlay)
|
|
440
|
+
<div style={{ display: 'flex' }}>
|
|
441
|
+
<main style={{ flex: 1 }}>...</main>
|
|
442
|
+
<div id="chat-container" />
|
|
443
|
+
</div>
|
|
444
|
+
|
|
445
|
+
// After (side panel)
|
|
446
|
+
<main>...</main>
|
|
447
|
+
<ChatPanelWithToggle />
|
|
580
448
|
```
|
|
581
449
|
|
|
582
450
|
## License
|
|
583
451
|
|
|
584
|
-
MIT ©
|
|
585
|
-
|
|
452
|
+
MIT © Kite
|