@asgard-js/react 0.2.44 → 0.2.45

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 CHANGED
@@ -320,6 +320,7 @@ config: {
320
320
  - **renderHeader?**: `() => ReactNode` - Custom header renderer. When provided, completely replaces the default header. Use `useAsgardContext()` inside the render function to access `resetChannel`, `isResetting`, and other internal state.
321
321
  - **renderMenu?**: `() => ReactNode` - Custom menu renderer. When provided, renders content between the chat body and footer. Useful for quick menus, suggested questions, or navigation panels. See [Custom Menu](#custom-menu) section for details.
322
322
  - **footerEndActions?**: `ReactNode[]` - Extra action nodes rendered at the end of the footer input row, after the send/mic button. Pure additive slot — built-in textarea / attachment buttons / send / mic remain unchanged. See [Footer End Actions](#footer-end-actions) section for details.
323
+ - **renderFooter?**: `() => ReactNode` - Custom footer renderer. When provided, completely replaces the default footer — built-in textarea, send/mic, upload, export, IME guard, and `footerEndActions` are not rendered. Use `useAsgardContext()` to access `sendMessage`, `isConnecting`, `pendingInputValue` / `setPendingInputValue`, etc. See [Custom Footer](#custom-footer) section for details.
323
324
  - **renderMessageContent?**: `(props: MessageContentRendererProps) => ReactNode` - Custom renderer for message content. Allows customizing how messages are rendered based on message properties. See [Custom Message Renderer](#custom-message-renderer) section for details.
324
325
  - **renderToolCallGroup?**: `(props: ToolCallGroupRendererProps) => ReactNode` - Custom renderer for tool call group. Return `null` to hide, return JSX to fully customize, or call `renderDefaultContent()` to use the default UI with optional overrides (e.g., `renderDefaultContent({ title: 'AI is thinking...' })`). See [Tool Call Group Renderer](#tool-call-group-renderer) section for details.
325
326
  - **onBeforeSendMessage?**: `(params: SendMessageParams) => SendMessageParams` - Callback to modify message params before sending. Allows injecting contextual data (payload, metadata) from parent components. See [Before Send Message Hook](#before-send-message-hook) section for details.
@@ -1377,6 +1378,107 @@ const App = () => {
1377
1378
  - Use `chatbotRef.current?.serviceContext?.sendMessage` (or `useAsgardContext()` inside a wrapper component) to send messages from the consumer-owned UI that the action triggers (e.g. modal Submit button).
1378
1379
  - Distinct from `customActions` (header trailing): `customActions` appends to the **header** title bar, `footerEndActions` appends to the **footer** input row.
1379
1380
 
1381
+ <a id="custom-footer"></a>
1382
+ <br/>
1383
+
1384
+ ### Custom Footer
1385
+
1386
+ The `renderFooter` prop completely replaces the default `<ChatbotFooter />`. Reach for it when you need to redesign the entire input area — for example a single-line input, a custom voice-only flow, or a different layout. If you only need to add a button next to send, use [`footerEndActions`](#footer-end-actions) instead, which keeps every built-in feature intact.
1387
+
1388
+ What `renderFooter` removes from the default footer:
1389
+
1390
+ - Built-in textarea (with auto-resize)
1391
+ - Send button, microphone button
1392
+ - Image upload, document upload, conversation export
1393
+ - IME composition guard (skip submit while composing)
1394
+ - The `footerEndActions` slot
1395
+
1396
+ The container-level drag-and-drop overlay still appears when `enableUpload` or `enableDocumentUpload` is set, but textarea-side file handling is gone. If your custom footer needs to react to dropped files, read them from `useFileDropContext()`.
1397
+
1398
+ Use `useAsgardContext()` to access runtime state:
1399
+
1400
+ - `sendMessage(params)` — submit a message (`undefined` in preview mode, e.g. while config is loading)
1401
+ - `isConnecting` — disable send while the channel is busy
1402
+ - `pendingInputValue` / `setPendingInputValue` — receive values pushed in via `ChatbotRef.setInputValue` or `renderMenu` selection, then clear them
1403
+ - `inputPlaceholder`, `title`, `avatar`, `messages`, etc.
1404
+
1405
+ Use `useAsgardThemeContext()` for theme tokens to stay visually consistent with the rest of the chatbot.
1406
+
1407
+ #### Usage Example
1408
+
1409
+ ```typescript
1410
+ import { useEffect, useRef, useState } from 'react';
1411
+ import { Chatbot, ChatbotRef, useAsgardContext } from '@asgard-js/react';
1412
+
1413
+ function CustomFooter() {
1414
+ const { sendMessage, isConnecting, pendingInputValue, setPendingInputValue, inputPlaceholder } = useAsgardContext();
1415
+
1416
+ const [value, setValue] = useState('');
1417
+ const textareaRef = useRef<HTMLTextAreaElement>(null);
1418
+
1419
+ // Receive text pushed in via ChatbotRef.setInputValue or renderMenu
1420
+ useEffect(() => {
1421
+ if (pendingInputValue == null) return;
1422
+ setValue(pendingInputValue);
1423
+ setPendingInputValue(null);
1424
+ textareaRef.current?.focus();
1425
+ }, [pendingInputValue, setPendingInputValue]);
1426
+
1427
+ const submit = () => {
1428
+ const text = value.trim();
1429
+ if (!text || isConnecting) return;
1430
+ sendMessage?.({ text });
1431
+ setValue('');
1432
+ };
1433
+
1434
+ return (
1435
+ <div style={{ display: 'flex', gap: 8, padding: '8px 12px' }}>
1436
+ <textarea
1437
+ ref={textareaRef}
1438
+ placeholder={inputPlaceholder ?? 'Type a message...'}
1439
+ value={value}
1440
+ onChange={e => setValue(e.target.value)}
1441
+ onKeyDown={e => {
1442
+ // Skip submit while IME is composing
1443
+ if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) {
1444
+ e.preventDefault();
1445
+ submit();
1446
+ }
1447
+ }}
1448
+ rows={1}
1449
+ style={{ flex: 1 }}
1450
+ />
1451
+ <button onClick={submit} disabled={!value.trim() || isConnecting}>
1452
+ Send
1453
+ </button>
1454
+ </div>
1455
+ );
1456
+ }
1457
+
1458
+ const App = () => {
1459
+ const chatbotRef = useRef<ChatbotRef>(null);
1460
+
1461
+ return (
1462
+ <Chatbot
1463
+ ref={chatbotRef}
1464
+ config={{
1465
+ apiKey: 'your-api-key',
1466
+ botProviderEndpoint: 'https://api.asgard-ai.com/ns/{namespace}/bot-provider/{botProviderId}',
1467
+ }}
1468
+ customChannelId="your-channel-id"
1469
+ renderFooter={() => <CustomFooter />}
1470
+ />
1471
+ );
1472
+ };
1473
+ ```
1474
+
1475
+ #### Notes
1476
+
1477
+ - `renderFooter` is a full replacement, not an additive slot. If you only want to add buttons after send, use [`footerEndActions`](#footer-end-actions).
1478
+ - When `renderFooter` is provided, `footerEndActions` is silently ignored.
1479
+ - `sendMessage` is `undefined` while the chatbot is in preview / not yet connected — guard with `?.()` and disable your submit UI until it's defined.
1480
+ - The `<ToolCallConsentGate />` is rendered outside `renderFooter`, so tool-call consent modals still appear normally.
1481
+
1380
1482
  <a id="custom-menu"></a>
1381
1483
  <br/>
1382
1484
 
@@ -56,7 +56,16 @@ interface ChatbotProps extends AsgardTemplateContextValue {
56
56
  * guard ref in the consumer if the work should only happen once.
57
57
  */
58
58
  onChannelReady?: () => void;
59
- /** Custom header renderer. When provided, replaces the default header entirely. */
59
+ /**
60
+ * Custom header renderer. When provided, replaces the default `<ChatbotHeader />`
61
+ * entirely — `title`, `onReset`, `onClose`, `customActions`, and
62
+ * `maintainConnectionWhenClosed` are no longer applied automatically; the
63
+ * renderer owns the header area in full.
64
+ *
65
+ * Use `useAsgardContext()` inside the renderer to access runtime state
66
+ * (`resetChannel`, `isResetting`, `avatar`, `title`, etc.) and
67
+ * `useAsgardThemeContext()` for theme tokens.
68
+ */
60
69
  renderHeader?: () => ReactNode;
61
70
  /** Custom menu renderer. When provided, renders between chat body and footer. */
62
71
  renderMenu?: () => ReactNode;
@@ -67,6 +76,29 @@ interface ChatbotProps extends AsgardTemplateContextValue {
67
76
  * "open SQL editor modal", "switch input mode", etc.
68
77
  */
69
78
  footerEndActions?: ReactNode[];
79
+ /**
80
+ * Custom footer renderer. When provided, replaces the default `<ChatbotFooter />`
81
+ * entirely. The built-in textarea, send / mic button, image upload, document
82
+ * upload, export, IME composition guard, and `footerEndActions` are **not**
83
+ * rendered — the renderer fully owns the footer area.
84
+ *
85
+ * The container-level drag-and-drop overlay (`<DropZoneOverlay />`) still
86
+ * appears when `enableUpload` or `enableDocumentUpload` is set, but the
87
+ * default consumption path (textarea-side handling) is gone. If your custom
88
+ * footer wants to react to dropped files, read them from
89
+ * `useFileDropContext()`.
90
+ *
91
+ * Use `useAsgardContext()` inside the renderer to access:
92
+ * - `sendMessage(params)` — submit a message (undefined in preview mode)
93
+ * - `isConnecting` — disable send while the channel is busy
94
+ * - `pendingInputValue` / `setPendingInputValue` — receive values pushed in
95
+ * via `ChatbotRef.setInputValue` or `renderMenu` selection, then clear them
96
+ * - `inputPlaceholder`, `title`, `avatar`, `messages`, etc.
97
+ *
98
+ * Use `useAsgardThemeContext()` for theme tokens to stay visually consistent
99
+ * with the rest of the chatbot.
100
+ */
101
+ renderFooter?: () => ReactNode;
70
102
  /** Custom renderer for tool call group. Return null to hide, or return custom JSX. */
71
103
  renderToolCallGroup?: AsgardTemplateContextValue['renderToolCallGroup'];
72
104
  /** Whether to automatically reset channel on mount. Defaults to true. When false, the channel is created without sending RESET_CHANNEL, allowing history messages to be preserved via initMessages. */
@@ -1 +1 @@
1
- {"version":3,"file":"chatbot.d.ts","sourceRoot":"","sources":["../../../src/components/chatbot/chatbot.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chatbot.d.ts","sourceRoot":"","sources":["../../../src/components/chatbot/chatbot.tsx"],"names":[],"mappings":"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"}