@cuadra-ai/uikit 0.2.0 → 0.3.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.
Files changed (44) hide show
  1. package/README.md +142 -2
  2. package/dist/adapters/attachmentAdapter.d.ts +63 -4
  3. package/dist/adapters/attachmentAdapter.d.ts.map +1 -1
  4. package/dist/components/CuadraChat.d.ts +54 -110
  5. package/dist/components/CuadraChat.d.ts.map +1 -1
  6. package/dist/components/CuadraChatContext.d.ts +141 -0
  7. package/dist/components/CuadraChatContext.d.ts.map +1 -0
  8. package/dist/components/ErrorBoundary.d.ts +79 -0
  9. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  10. package/dist/index.cjs +204 -18
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.ts +8 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.mjs +25250 -2529
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/lib/cuadraChatClient.d.ts +2 -1
  17. package/dist/lib/cuadraChatClient.d.ts.map +1 -1
  18. package/dist/magic-string.es-B81Zo59j.cjs +11 -0
  19. package/dist/magic-string.es-B81Zo59j.cjs.map +1 -0
  20. package/dist/magic-string.es-uPKorP4O.js +664 -0
  21. package/dist/magic-string.es-uPKorP4O.js.map +1 -0
  22. package/dist/test/fixtures/index.d.ts +7 -0
  23. package/dist/test/fixtures/index.d.ts.map +1 -0
  24. package/dist/test/fixtures/mockChats.d.ts +41 -0
  25. package/dist/test/fixtures/mockChats.d.ts.map +1 -0
  26. package/dist/test/fixtures/mockModels.d.ts +31 -0
  27. package/dist/test/fixtures/mockModels.d.ts.map +1 -0
  28. package/dist/test/fixtures/mockStreams.d.ts +60 -0
  29. package/dist/test/fixtures/mockStreams.d.ts.map +1 -0
  30. package/dist/test/utils/index.d.ts +6 -0
  31. package/dist/test/utils/index.d.ts.map +1 -0
  32. package/dist/test/utils/mockFetch.d.ts +67 -0
  33. package/dist/test/utils/mockFetch.d.ts.map +1 -0
  34. package/dist/test/utils/renderWithProviders.d.ts +136 -0
  35. package/dist/test/utils/renderWithProviders.d.ts.map +1 -0
  36. package/dist/types/props.d.ts +500 -0
  37. package/dist/types/props.d.ts.map +1 -0
  38. package/dist/uikit.css +1 -1
  39. package/dist/utils/sanitize.d.ts +90 -0
  40. package/dist/utils/sanitize.d.ts.map +1 -0
  41. package/dist/widget/cuadra-uikit.css +1 -1
  42. package/dist/widget/cuadra-uikit.umd.js +24 -24
  43. package/dist/widget/cuadra-uikit.umd.js.map +1 -1
  44. package/package.json +1 -1
package/README.md CHANGED
@@ -113,7 +113,104 @@ function App() {
113
113
  }
114
114
  ```
115
115
 
116
- #### Customization Options
116
+ #### New V2 Props (Recommended)
117
+
118
+ The new V2 props API groups related options for better organization:
119
+
120
+ ```tsx
121
+ import { CuadraChat } from '@cuadra-ai/uikit';
122
+
123
+ function App() {
124
+ return (
125
+ <div style={{ height: '100vh' }}>
126
+ <CuadraChat
127
+ connection={{
128
+ baseUrl: "https://api.cuadra.ai",
129
+ sessionToken: "your-session-token",
130
+ }}
131
+ chat={{
132
+ mode: "multiChat",
133
+ modelMode: "fixed",
134
+ modelId: "your-model-id",
135
+ enableReasoning: true,
136
+ }}
137
+ ui={{
138
+ theme: "system",
139
+ welcomeTitle: "Welcome to Chat",
140
+ welcomeSubtitle: "How can I help you today?",
141
+ suggestions: [
142
+ { prompt: "What is Cuadra AI?" },
143
+ { prompt: "How do I get started?" }
144
+ ],
145
+ }}
146
+ callbacks={{
147
+ onChatCreated: (chatId) => console.log('Chat:', chatId),
148
+ onError: (error) => console.error(error),
149
+ }}
150
+ className="my-custom-class"
151
+ />
152
+ </div>
153
+ );
154
+ }
155
+ ```
156
+
157
+ #### With Context Provider (External Control)
158
+
159
+ Use `CuadraChatProvider` to control the chat from anywhere in your component tree:
160
+
161
+ ```tsx
162
+ import { CuadraChat, CuadraChatProvider, useCuadraChat } from '@cuadra-ai/uikit';
163
+
164
+ function ChatControls() {
165
+ const { controls, isReady } = useCuadraChat();
166
+
167
+ return (
168
+ <button
169
+ onClick={() => controls?.sendMessage('Hello!')}
170
+ disabled={!isReady}
171
+ >
172
+ Send Hello
173
+ </button>
174
+ );
175
+ }
176
+
177
+ function App() {
178
+ return (
179
+ <CuadraChatProvider>
180
+ <ChatControls />
181
+ <CuadraChat
182
+ connection={{ baseUrl: "https://api.cuadra.ai" }}
183
+ chat={{ modelId: "your-model-id" }}
184
+ />
185
+ </CuadraChatProvider>
186
+ );
187
+ }
188
+ ```
189
+
190
+ #### With Error Boundary
191
+
192
+ CuadraChat includes built-in error handling:
193
+
194
+ ```tsx
195
+ import { CuadraChat } from '@cuadra-ai/uikit';
196
+
197
+ function App() {
198
+ return (
199
+ <CuadraChat
200
+ connection={{ baseUrl: "https://api.cuadra.ai" }}
201
+ chat={{ modelId: "your-model-id" }}
202
+ errorFallback={(error, reset) => (
203
+ <div>
204
+ <p>Something went wrong: {error.message}</p>
205
+ <button onClick={reset}>Retry</button>
206
+ </div>
207
+ )}
208
+ />
209
+ );
210
+ }
211
+ ```
212
+
213
+ #### Legacy Props (Still Supported)
117
214
 
118
215
  ```tsx
119
216
  import { CuadraChat } from '@cuadra-ai/uikit';
@@ -231,7 +328,50 @@ For detailed widget API documentation, see the [full documentation](https://docs
231
328
 
232
329
  ## API Reference
233
330
 
234
- ### CuadraChat Props
331
+ ### V2 Props (Recommended)
332
+
333
+ | Prop Group | Prop | Type | Description |
334
+ |------------|------|------|-------------|
335
+ | `connection` | `baseUrl` | `string` | Cuadra API base URL |
336
+ | | `proxyUrl` | `string` | Proxy URL for backend auth |
337
+ | | `sessionToken` | `string \| null` | Bearer token |
338
+ | `chat` | `mode` | `'singleChat' \| 'multiChat'` | Chat mode (default: `'multiChat'`) |
339
+ | | `modelMode` | `'fixed' \| 'selector'` | Model selection mode (default: `'fixed'`) |
340
+ | | `modelId` | `string` | Model ID from dashboard |
341
+ | | `systemPrompt` | `string` | System prompt |
342
+ | | `ephemeral` | `boolean` | Auto-delete chats on close |
343
+ | | `enableReasoning` | `boolean` | Enable thinking output |
344
+ | | `enableAttachments` | `boolean` | Enable file attachments |
345
+ | `ui` | `theme` | `'light' \| 'dark' \| 'system'` | Theme mode (default: `'system'`) |
346
+ | | `showThemeToggle` | `boolean` | Show toggle (default: `true`) |
347
+ | | `welcomeTitle` | `string` | Welcome screen title |
348
+ | | `welcomeSubtitle` | `string` | Welcome screen subtitle |
349
+ | | `suggestions` | `Array<Suggestion>` | Welcome screen suggestions |
350
+ | | `inputPlaceholder` | `string` | Input field placeholder |
351
+ | `callbacks` | `onChatCreated` | `(id: string) => void` | Called when chat created |
352
+ | | `onError` | `(error: Error) => void` | Error callback |
353
+ | | `onModelChange` | `(id: string) => void` | Model change callback |
354
+ | `errorFallback` | | `ReactNode \| Function` | Custom error UI |
355
+ | `className` | | `string` | Container CSS class |
356
+
357
+ ### Exported Hooks
358
+
359
+ | Hook | Description |
360
+ |------|-------------|
361
+ | `useCuadraChat()` | Access chat controls from context (requires `CuadraChatProvider`) |
362
+ | `useCuadraChatOptional()` | Same as above, returns null if no provider |
363
+
364
+ ### Exported Utilities
365
+
366
+ | Utility | Description |
367
+ |---------|-------------|
368
+ | `sanitizeSystemPrompt()` | Remove injection patterns from prompts |
369
+ | `isValidUrl()` | Validate URL uses http/https |
370
+ | `validateBaseUrl()` | Validate API base URL with details |
371
+ | `generateSecureUUID()` | Crypto-secure UUID generation |
372
+ | `createAttachmentAdapter()` | Create file attachment adapter with validation |
373
+
374
+ ### Legacy Props (Still Supported)
235
375
 
236
376
  | Prop | Type | Required | Default | Description |
237
377
  |------|------|----------|---------|-------------|
@@ -1,7 +1,66 @@
1
- import type { AttachmentAdapter } from '@assistant-ui/react';
1
+ import type { AttachmentAdapter, PendingAttachment } from '@assistant-ui/react';
2
2
  /**
3
- * Simple attachment adapter that handles file attachments
4
- * Files are kept as File objects and sent with messages
3
+ * Attachment validation configuration
5
4
  */
6
- export declare function createAttachmentAdapter(): AttachmentAdapter;
5
+ export interface AttachmentValidationConfig {
6
+ /**
7
+ * Maximum file size in bytes
8
+ * @default 10 * 1024 * 1024 (10MB)
9
+ */
10
+ maxFileSizeBytes?: number;
11
+ /**
12
+ * Allowed MIME types (e.g., ['image/png', 'image/jpeg'])
13
+ * If not provided, defaults to common document and image types
14
+ */
15
+ allowedMimeTypes?: string[];
16
+ /**
17
+ * Allowed file extensions (e.g., ['.pdf', '.docx'])
18
+ * If not provided, defaults to common document and image extensions
19
+ */
20
+ allowedExtensions?: string[];
21
+ /**
22
+ * Maximum number of attachments per message
23
+ * @default 5
24
+ */
25
+ maxAttachments?: number;
26
+ /**
27
+ * Whether to validate file content type matches extension
28
+ * @default true
29
+ */
30
+ validateContentType?: boolean;
31
+ }
32
+ /**
33
+ * Attachment validation error
34
+ */
35
+ export declare class AttachmentValidationError extends Error {
36
+ readonly code: 'FILE_TOO_LARGE' | 'INVALID_TYPE' | 'TOO_MANY_FILES' | 'VALIDATION_FAILED';
37
+ readonly file?: File | undefined;
38
+ constructor(message: string, code: 'FILE_TOO_LARGE' | 'INVALID_TYPE' | 'TOO_MANY_FILES' | 'VALIDATION_FAILED', file?: File | undefined);
39
+ }
40
+ /**
41
+ * Attachment adapter options
42
+ */
43
+ export interface AttachmentAdapterOptions {
44
+ /**
45
+ * Validation configuration
46
+ */
47
+ validation?: AttachmentValidationConfig;
48
+ /**
49
+ * Callback when validation fails
50
+ * Allows custom error handling (e.g., show toast notification)
51
+ */
52
+ onValidationError?: (error: AttachmentValidationError) => void;
53
+ /**
54
+ * Callback when attachment is added
55
+ */
56
+ onAttachmentAdded?: (attachment: PendingAttachment) => void;
57
+ /**
58
+ * Callback when attachment is removed
59
+ */
60
+ onAttachmentRemoved?: (attachmentId: string) => void;
61
+ }
62
+ /**
63
+ * Create an attachment adapter with enhanced validation
64
+ */
65
+ export declare function createAttachmentAdapter(options?: AttachmentAdapterOptions): AttachmentAdapter;
7
66
  //# sourceMappingURL=attachmentAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachmentAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/attachmentAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,qBAAqB,CAAC;AAE7B;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,iBAAiB,CAoE3D"}
1
+ {"version":3,"file":"attachmentAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/attachmentAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAEjB,iBAAiB,EAClB,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE7B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;aAGhC,IAAI,EAAE,gBAAgB,GAAG,cAAc,GAAG,gBAAgB,GAAG,mBAAmB;aAChF,IAAI,CAAC,EAAE,IAAI;gBAF3B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,gBAAgB,GAAG,cAAc,GAAG,gBAAgB,GAAG,mBAAmB,EAChF,IAAI,CAAC,EAAE,IAAI,YAAA;CAK9B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,UAAU,CAAC,EAAE,0BAA0B,CAAC;IAExC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAE/D;;OAEG;IACH,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAE5D;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAiHD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,GAAE,wBAA6B,GACrC,iBAAiB,CAwJnB"}
@@ -1,5 +1,4 @@
1
- import type { CuadraRuntimeProviderProps } from './CuadraRuntimeProvider';
2
- import type { CuadraTheme } from '../types/theme';
1
+ import { type CuadraChatProps } from '../types/props';
3
2
  /**
4
3
  * Handle for controlling CuadraChat externally
5
4
  */
@@ -17,123 +16,68 @@ export interface CuadraChatHandle {
17
16
  /** Clear the current chat and start fresh */
18
17
  clearChat: () => void;
19
18
  }
20
- export interface CuadraChatProps extends Omit<CuadraRuntimeProviderProps, 'children' | 'isProxyMode'> {
21
- /** Proxy URL for backend-handled authentication (e.g., '/api/chat' or 'http://localhost:3000') */
22
- proxyUrl?: string;
23
- /** Container className for styling */
24
- className?: string;
25
- /** Enable reasoning/thinking output for supported models (e.g., o1, o3) - explicit for better TS compatibility */
26
- enableReasoning?: boolean;
27
- /** Show theme toggle button */
28
- showThemeToggle?: boolean;
29
- /** Initial theme ('light' | 'dark' | 'system') */
30
- theme?: 'light' | 'dark' | 'system';
31
- /** Custom theme colors to override defaults */
32
- customTheme?: CuadraTheme;
33
- /** Language/locale for i18n (e.g., 'en', 'es', 'fr') */
34
- language?: string;
35
- /** Welcome screen title */
36
- welcomeTitle?: string;
37
- /** Welcome screen subtitle */
38
- welcomeSubtitle?: string;
39
- /** Extra top padding for thread viewport (e.g., '1rem', '2rem') */
40
- extraTopPadding?: string;
41
- /** Suggestions to show in welcome screen (with optional pre-made responses) */
42
- suggestions?: Array<{
43
- /** Suggestion prompt text */
44
- prompt: string;
45
- /** Pre-made response (optional) - if provided, response appears instantly with simulated streaming */
46
- response?: string;
47
- /** Delay before showing response in ms (overrides preMadeResponseDelay) */
48
- responseDelay?: number;
49
- }>;
50
- /** Placeholder text for the input field */
51
- inputPlaceholder?: string;
52
- /** Default delay before pre-made responses in ms (default: 1000) */
53
- preMadeResponseDelay?: number;
54
- /** Speed of simulated streaming in ms per word (default: 50) */
55
- streamingSpeed?: number;
56
- /** Called when a user message is sent */
57
- onUserMessage?: () => void;
58
- /** Called when logout button is clicked */
59
- onLogout?: () => void;
60
- /** Enable file attachments in the chat input */
61
- enableAttachments?: boolean;
62
- /**
63
- * Initial message to send automatically when chat loads
64
- * (triggers normal API call after a short delay)
65
- */
66
- initialMessage?: string;
67
- /**
68
- * Initial pre-made Q&A to display when chat loads
69
- * (instant display with simulated streaming, no API call)
70
- */
71
- initialPreMadeQA?: {
72
- question: string;
73
- answer: string;
74
- };
75
- /**
76
- * Interceptor called before each outgoing API request.
77
- * Return `true` to allow the request, `false` to block it.
78
- * Can be async (e.g., to show a login modal).
79
- * If not provided, all requests are allowed.
80
- *
81
- * @example
82
- * // Block requests and show login modal
83
- * onBeforeRequest={async () => {
84
- * if (!isLoggedIn) {
85
- * showLoginModal();
86
- * return false; // Block the request
87
- * }
88
- * return true; // Allow the request
89
- * }}
90
- */
91
- onBeforeRequest?: () => boolean | Promise<boolean>;
92
- /**
93
- * Mock response to show when onBeforeRequest returns false.
94
- * If set, instead of throwing an error, this message will be streamed as a response.
95
- * Can be a string or a function that returns a string (called each time a request is blocked).
96
- * Useful for showing helpful messages like "Complete setup before chatting".
97
- *
98
- * @example
99
- * // Show friendly message when chat is not ready (static)
100
- * mockResponseOnBlocked="Complete the setup on the left before we can start chatting!"
101
- *
102
- * @example
103
- * // Show different messages each time (dynamic)
104
- * const messages = ["First message", "Second message", "Third message"];
105
- * let count = 0;
106
- * mockResponseOnBlocked={() => messages[count++ % messages.length]}
107
- */
108
- mockResponseOnBlocked?: string | (() => string);
109
- }
19
+ export type { CuadraChatProps, CuadraChatPropsV2, CuadraChatPropsLegacy, CuadraConnectionConfig, CuadraChatConfig, CuadraUIConfig, CuadraCallbacks, CuadraInterceptors, CuadraPreMadeConfig, CuadraInitialState, CuadraSuggestion, } from '../types/props';
110
20
  /**
111
21
  * All-in-one Cuadra Chat component
112
22
  *
113
- * This component uses the widget implementation internally, ensuring
114
- * consistent styling and behavior with the widget version.
23
+ * Supports both V2 grouped props (recommended) and legacy flat props.
115
24
  *
116
- * Styles are automatically bundled and injected. Users can optionally
117
- * import '@cuadra-ai/uikit/styles' if they need explicit control.
25
+ * ## V2 Props (Recommended)
118
26
  *
119
- * @example
120
- * // Basic usage
121
- * <CuadraChat baseUrl="https://api.cuadra.ai" modelId="model-123" />
27
+ * ```tsx
28
+ * <CuadraChat
29
+ * connection={{
30
+ * baseUrl: 'https://api.cuadra.ai',
31
+ * sessionToken: 'your-token',
32
+ * }}
33
+ * chat={{
34
+ * mode: 'multiChat',
35
+ * modelId: 'your-model-id',
36
+ * enableReasoning: true,
37
+ * }}
38
+ * ui={{
39
+ * theme: 'dark',
40
+ * welcomeTitle: 'Welcome!',
41
+ * suggestions: [{ prompt: 'What can you do?' }],
42
+ * }}
43
+ * callbacks={{
44
+ * onChatCreated: (id) => console.log('Chat:', id),
45
+ * }}
46
+ * />
47
+ * ```
122
48
  *
123
- * @example
124
- * // With ref for external control
125
- * const chatRef = useRef<CuadraChatHandle>(null);
126
- * <CuadraChat ref={chatRef} ... />
127
- * chatRef.current?.sendMessage("Hello!");
49
+ * ## Legacy Props (Still Supported)
128
50
  *
129
- * @example
130
- * // With pre-made suggestions
51
+ * ```tsx
131
52
  * <CuadraChat
132
- * suggestions={[
133
- * { prompt: "What is Cuadra?", response: "Cuadra AI is..." },
134
- * { prompt: "How do I start?" } // No response = normal API call
135
- * ]}
53
+ * baseUrl="https://api.cuadra.ai"
54
+ * sessionToken="your-token"
55
+ * mode="multiChat"
56
+ * modelId="your-model-id"
57
+ * enableReasoning={true}
58
+ * theme="dark"
59
+ * welcomeTitle="Welcome!"
136
60
  * />
61
+ * ```
62
+ *
63
+ * ## External Control
64
+ *
65
+ * Use `CuadraChatProvider` and `useCuadraChat()` hook for context-based control:
66
+ *
67
+ * ```tsx
68
+ * <CuadraChatProvider>
69
+ * <CuadraChat connection={{ baseUrl: '...' }} />
70
+ * <MyControlsComponent /> {/* Can use useCuadraChat() *\/}
71
+ * </CuadraChatProvider>
72
+ * ```
73
+ *
74
+ * Or use a ref for direct control:
75
+ *
76
+ * ```tsx
77
+ * const chatRef = useRef<CuadraChatHandle>(null);
78
+ * <CuadraChat ref={chatRef} connection={{ baseUrl: '...' }} />
79
+ * chatRef.current?.sendMessage('Hello!');
80
+ * ```
137
81
  */
138
82
  export declare const CuadraChat: import("react").ForwardRefExoticComponent<CuadraChatProps & import("react").RefAttributes<CuadraChatHandle>>;
139
83
  //# sourceMappingURL=CuadraChat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CuadraChat.d.ts","sourceRoot":"","sources":["../../src/components/CuadraChat.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC;;;OAGG;IACH,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACjH,6CAA6C;IAC7C,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAGD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,0BAA0B,EAAE,UAAU,GAAG,aAAa,CAAC;IACnG,kGAAkG;IAClG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kHAAkH;IAClH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+BAA+B;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IACpC,+CAA+C;IAC/C,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,6BAA6B;QAC7B,MAAM,EAAE,MAAM,CAAC;QACf,sGAAsG;QACtG,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,2EAA2E;QAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC,CAAC;IACH,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF;;;;;;;;;;;;;;;OAeG;IACH,eAAe,CAAC,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD;;;;;;;;;;;;;;;OAeG;IACH,qBAAqB,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;CACjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,UAAU,8GA8EtB,CAAC"}
1
+ {"version":3,"file":"CuadraChat.d.ts","sourceRoot":"","sources":["../../src/components/CuadraChat.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,eAAe,EAA6D,MAAM,gBAAgB,CAAC;AAEjH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC;;;OAGG;IACH,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACjH,6CAA6C;IAC7C,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAGD,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAkHxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,eAAO,MAAM,UAAU,8GAyBtB,CAAC"}
@@ -0,0 +1,141 @@
1
+ import { type ReactNode, type RefObject } from 'react';
2
+ import type { CuadraChatHandle } from './CuadraChat';
3
+ /**
4
+ * Context for accessing CuadraChat controls from any child component
5
+ *
6
+ * This provides a React-idiomatic way to control the chat component
7
+ * from anywhere in your component tree without prop drilling.
8
+ *
9
+ * @example Using in a parent component
10
+ * ```tsx
11
+ * import { CuadraChat, CuadraChatProvider, useCuadraChat } from '@cuadra-ai/uikit';
12
+ *
13
+ * function App() {
14
+ * return (
15
+ * <CuadraChatProvider>
16
+ * <CuadraChat connection={{ baseUrl: '...' }} />
17
+ * <MyCustomControls />
18
+ * </CuadraChatProvider>
19
+ * );
20
+ * }
21
+ *
22
+ * function MyCustomControls() {
23
+ * const { controls } = useCuadraChat();
24
+ *
25
+ * return (
26
+ * <button onClick={() => controls?.sendMessage('Hello!')}>
27
+ * Send Hello
28
+ * </button>
29
+ * );
30
+ * }
31
+ * ```
32
+ */
33
+ export interface CuadraChatContextValue {
34
+ /**
35
+ * Reference to the CuadraChat controls
36
+ * May be null before the CuadraChat component mounts
37
+ */
38
+ controls: CuadraChatHandle | null;
39
+ /**
40
+ * Internal: Reference setter for CuadraChat to register itself
41
+ * @internal
42
+ */
43
+ registerControls: (controls: CuadraChatHandle) => void;
44
+ /**
45
+ * Internal: Reference clearer for CuadraChat to unregister on unmount
46
+ * @internal
47
+ */
48
+ unregisterControls: () => void;
49
+ }
50
+ /**
51
+ * Context for CuadraChat controls
52
+ *
53
+ * Default value is null - use CuadraChatProvider to provide an actual value.
54
+ * Consumers can check if context is null to detect missing provider.
55
+ */
56
+ export declare const CuadraChatContext: import("react").Context<CuadraChatContextValue | null>;
57
+ /**
58
+ * Hook to access CuadraChat controls from any child component
59
+ *
60
+ * @returns Object containing `controls` (CuadraChatHandle | null) and `isReady` boolean
61
+ * @throws Error if used outside of CuadraChatProvider
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * function MyComponent() {
66
+ * const { controls, isReady } = useCuadraChat();
67
+ *
68
+ * if (!isReady) {
69
+ * return <span>Chat is loading...</span>;
70
+ * }
71
+ *
72
+ * return (
73
+ * <button onClick={() => controls.sendMessage('Hi!')}>
74
+ * Send Message
75
+ * </button>
76
+ * );
77
+ * }
78
+ * ```
79
+ */
80
+ export declare function useCuadraChat(): {
81
+ controls: CuadraChatHandle | null;
82
+ isReady: boolean;
83
+ };
84
+ /**
85
+ * Hook to optionally access CuadraChat controls
86
+ *
87
+ * Unlike useCuadraChat, this doesn't throw if the provider is missing.
88
+ * Returns null if CuadraChatProvider is not present.
89
+ *
90
+ * @returns Object with controls and isReady, or null if no provider
91
+ *
92
+ * @example
93
+ * ```tsx
94
+ * function OptionalChatControl() {
95
+ * const chat = useCuadraChatOptional();
96
+ *
97
+ * if (!chat) {
98
+ * // No CuadraChatProvider in tree - gracefully handle
99
+ * return null;
100
+ * }
101
+ *
102
+ * return chat.isReady ? (
103
+ * <button onClick={() => chat.controls?.sendMessage('Hi!')}>Send</button>
104
+ * ) : null;
105
+ * }
106
+ * ```
107
+ */
108
+ export declare function useCuadraChatOptional(): {
109
+ controls: CuadraChatHandle | null;
110
+ isReady: boolean;
111
+ } | null;
112
+ /**
113
+ * Provider component for CuadraChat context
114
+ *
115
+ * Wrap your component tree with this to enable useCuadraChat hook
116
+ * access from any descendant component.
117
+ *
118
+ * @example
119
+ * ```tsx
120
+ * function App() {
121
+ * return (
122
+ * <CuadraChatProvider>
123
+ * <Header />
124
+ * <CuadraChat connection={{ baseUrl: '...' }} />
125
+ * <Sidebar />
126
+ * </CuadraChatProvider>
127
+ * );
128
+ * }
129
+ * ```
130
+ */
131
+ export interface CuadraChatProviderProps {
132
+ children: ReactNode;
133
+ }
134
+ export declare function CuadraChatProvider({ children }: CuadraChatProviderProps): import("react/jsx-runtime").JSX.Element;
135
+ /**
136
+ * Helper to create a ref object that syncs with context
137
+ * Used internally by CuadraChat to register itself with the context
138
+ * @internal
139
+ */
140
+ export declare function createContextualRef(registerControls: (controls: CuadraChatHandle) => void, unregisterControls: () => void): RefObject<CuadraChatHandle | null>;
141
+ //# sourceMappingURL=CuadraChatContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CuadraChatContext.d.ts","sourceRoot":"","sources":["../../src/components/CuadraChatContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAqC,MAAM,OAAO,CAAC;AACzG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAElC;;;OAGG;IACH,gBAAgB,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAEvD;;;OAGG;IACH,kBAAkB,EAAE,MAAM,IAAI,CAAC;CAChC;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,wDAAqD,CAAC;AAIpF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,aAAa,IAAI;IAAE,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAcvF;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,IAAI;IAAE,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAWtG;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,EAAE,uBAAuB,2CAsBvE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,EACtD,kBAAkB,EAAE,MAAM,IAAI,GAC7B,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAgBpC"}
@@ -0,0 +1,79 @@
1
+ import { Component, type ErrorInfo, type ReactNode } from 'react';
2
+ /**
3
+ * Props for CuadraErrorBoundary
4
+ */
5
+ export interface CuadraErrorBoundaryProps {
6
+ /** Child components to wrap */
7
+ children: ReactNode;
8
+ /**
9
+ * Custom fallback UI or render function
10
+ * If not provided, DefaultErrorFallback is used
11
+ */
12
+ fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
13
+ /**
14
+ * Callback when an error is caught
15
+ * Use for logging, analytics, etc.
16
+ */
17
+ onError?: (error: Error, errorInfo: ErrorInfo) => void;
18
+ }
19
+ interface ErrorBoundaryState {
20
+ hasError: boolean;
21
+ error: Error | null;
22
+ }
23
+ /**
24
+ * Error boundary component for CuadraChat
25
+ *
26
+ * Catches JavaScript errors in child component tree and displays
27
+ * a fallback UI instead of crashing the entire application.
28
+ *
29
+ * @example Basic usage (uses default fallback)
30
+ * ```tsx
31
+ * <CuadraErrorBoundary>
32
+ * <CuadraChat {...props} />
33
+ * </CuadraErrorBoundary>
34
+ * ```
35
+ *
36
+ * @example With custom fallback
37
+ * ```tsx
38
+ * <CuadraErrorBoundary
39
+ * fallback={<div>Oops! Something went wrong.</div>}
40
+ * >
41
+ * <CuadraChat {...props} />
42
+ * </CuadraErrorBoundary>
43
+ * ```
44
+ *
45
+ * @example With render function fallback
46
+ * ```tsx
47
+ * <CuadraErrorBoundary
48
+ * fallback={(error, reset) => (
49
+ * <div>
50
+ * <p>Error: {error.message}</p>
51
+ * <button onClick={reset}>Retry</button>
52
+ * </div>
53
+ * )}
54
+ * onError={(error, info) => {
55
+ * console.error('Chat error:', error);
56
+ * analytics.track('chat_error', { message: error.message });
57
+ * }}
58
+ * >
59
+ * <CuadraChat {...props} />
60
+ * </CuadraErrorBoundary>
61
+ * ```
62
+ */
63
+ export declare class CuadraErrorBoundary extends Component<CuadraErrorBoundaryProps, ErrorBoundaryState> {
64
+ constructor(props: CuadraErrorBoundaryProps);
65
+ static getDerivedStateFromError(error: Error): ErrorBoundaryState;
66
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
67
+ /**
68
+ * Reset the error state and attempt to re-render children
69
+ */
70
+ reset: () => void;
71
+ render(): ReactNode;
72
+ }
73
+ /**
74
+ * Hook-friendly wrapper for error boundary
75
+ * Use when you need to reset error boundary from a child component
76
+ */
77
+ export declare function withErrorBoundary<P extends object>(WrappedComponent: React.ComponentType<P>, errorBoundaryProps?: Omit<CuadraErrorBoundaryProps, 'children'>): React.FC<P>;
78
+ export {};
79
+ //# sourceMappingURL=ErrorBoundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/components/ErrorBoundary.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,+BAA+B;IAC/B,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC,CAAC;IACxE;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;CACxD;AAED,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAiDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,mBAAoB,SAAQ,SAAS,CAAC,wBAAwB,EAAE,kBAAkB,CAAC;gBAClF,KAAK,EAAE,wBAAwB;IAK3C,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,kBAAkB;IAIjE,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAI3D;;OAEG;IACH,KAAK,QAAO,IAAI,CAEd;IAEF,MAAM,IAAI,SAAS;CAqBpB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAChD,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EACxC,kBAAkB,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,UAAU,CAAC,GAC9D,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAUb"}