@devicai/ui 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -0
- package/dist/cjs/components/AIGenerationButton/AIGenerationButton.js +254 -0
- package/dist/cjs/components/AIGenerationButton/AIGenerationButton.js.map +1 -0
- package/dist/cjs/components/AIGenerationButton/useAIGenerationButton.js +348 -0
- package/dist/cjs/components/AIGenerationButton/useAIGenerationButton.js.map +1 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/styles.css +1 -1
- package/dist/esm/components/AIGenerationButton/AIGenerationButton.d.ts +42 -0
- package/dist/esm/components/AIGenerationButton/AIGenerationButton.js +252 -0
- package/dist/esm/components/AIGenerationButton/AIGenerationButton.js.map +1 -0
- package/dist/esm/components/AIGenerationButton/AIGenerationButton.types.d.ts +260 -0
- package/dist/esm/components/AIGenerationButton/index.d.ts +3 -0
- package/dist/esm/components/AIGenerationButton/useAIGenerationButton.d.ts +40 -0
- package/dist/esm/components/AIGenerationButton/useAIGenerationButton.js +346 -0
- package/dist/esm/components/AIGenerationButton/useAIGenerationButton.js.map +1 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,8 +5,10 @@ React component library for integrating Devic AI assistants into your applicatio
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **ChatDrawer** - A ready-to-use chat drawer component
|
|
8
|
+
- **AICommandBar** - A spotlight-style command bar for quick AI interactions
|
|
8
9
|
- **useDevicChat** - Hook for building custom chat UIs
|
|
9
10
|
- **Model Interface Protocol** - Support for client-side tool execution
|
|
11
|
+
- **Message Feedback** - Built-in thumbs up/down feedback with comments
|
|
10
12
|
- **CSS Variables** - Easy theming with CSS custom properties
|
|
11
13
|
- **TypeScript** - Full type definitions included
|
|
12
14
|
- **React 17+** - Compatible with React 17 and above
|
|
@@ -152,6 +154,102 @@ A complete chat drawer component.
|
|
|
152
154
|
/>
|
|
153
155
|
```
|
|
154
156
|
|
|
157
|
+
### AICommandBar
|
|
158
|
+
|
|
159
|
+
A floating command bar (similar to Spotlight/Command Palette) for quick AI interactions.
|
|
160
|
+
|
|
161
|
+
```tsx
|
|
162
|
+
import { AICommandBar } from '@devicai/ui';
|
|
163
|
+
|
|
164
|
+
<AICommandBar
|
|
165
|
+
assistantId="my-assistant"
|
|
166
|
+
options={{
|
|
167
|
+
shortcut: 'cmd+k', // Keyboard shortcut to open
|
|
168
|
+
placeholder: 'Ask AI...',
|
|
169
|
+
position: 'fixed', // 'inline' | 'fixed'
|
|
170
|
+
fixedPlacement: { bottom: 20, right: 20 },
|
|
171
|
+
showResultCard: true, // Show response in a card
|
|
172
|
+
showShortcutHint: true, // Show shortcut badge
|
|
173
|
+
|
|
174
|
+
// Commands (slash commands)
|
|
175
|
+
commands: [
|
|
176
|
+
{
|
|
177
|
+
keyword: 'summarize',
|
|
178
|
+
description: 'Summarize content',
|
|
179
|
+
message: 'Please summarize this page.',
|
|
180
|
+
icon: <SummarizeIcon />,
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
|
|
184
|
+
// History
|
|
185
|
+
enableHistory: true,
|
|
186
|
+
maxHistoryItems: 50,
|
|
187
|
+
|
|
188
|
+
// Theming
|
|
189
|
+
backgroundColor: '#ffffff',
|
|
190
|
+
textColor: '#1f2937',
|
|
191
|
+
borderColor: '#e5e7eb',
|
|
192
|
+
borderRadius: 12,
|
|
193
|
+
}}
|
|
194
|
+
|
|
195
|
+
// Callbacks
|
|
196
|
+
onResponse={({ message, toolCalls, chatUid }) => {}}
|
|
197
|
+
onSubmit={(message) => {}}
|
|
198
|
+
onToolCall={(toolName, params) => {}}
|
|
199
|
+
onError={(error) => {}}
|
|
200
|
+
onOpen={() => {}}
|
|
201
|
+
onClose={() => {}}
|
|
202
|
+
|
|
203
|
+
// Integration with ChatDrawer
|
|
204
|
+
onExecute="openDrawer" // 'callback' | 'openDrawer'
|
|
205
|
+
chatDrawerRef={drawerRef} // Required when onExecute="openDrawer"
|
|
206
|
+
|
|
207
|
+
// Controlled mode
|
|
208
|
+
isVisible={true}
|
|
209
|
+
onVisibilityChange={(visible) => {}}
|
|
210
|
+
/>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### AICommandBar with ChatDrawer Integration
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
import { useRef } from 'react';
|
|
217
|
+
import { AICommandBar, ChatDrawer, ChatDrawerHandle } from '@devicai/ui';
|
|
218
|
+
|
|
219
|
+
function App() {
|
|
220
|
+
const drawerRef = useRef<ChatDrawerHandle>(null);
|
|
221
|
+
|
|
222
|
+
return (
|
|
223
|
+
<>
|
|
224
|
+
<AICommandBar
|
|
225
|
+
assistantId="my-assistant"
|
|
226
|
+
onExecute="openDrawer"
|
|
227
|
+
chatDrawerRef={drawerRef}
|
|
228
|
+
options={{
|
|
229
|
+
shortcut: 'cmd+k',
|
|
230
|
+
showResultCard: false,
|
|
231
|
+
}}
|
|
232
|
+
/>
|
|
233
|
+
<ChatDrawer ref={drawerRef} assistantId="my-assistant" />
|
|
234
|
+
</>
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
#### AICommandBar Handle (ref methods)
|
|
240
|
+
|
|
241
|
+
```tsx
|
|
242
|
+
const commandBarRef = useRef<AICommandBarHandle>(null);
|
|
243
|
+
|
|
244
|
+
// Methods available via ref
|
|
245
|
+
commandBarRef.current?.open();
|
|
246
|
+
commandBarRef.current?.close();
|
|
247
|
+
commandBarRef.current?.toggle();
|
|
248
|
+
commandBarRef.current?.focus();
|
|
249
|
+
commandBarRef.current?.submit('Hello!');
|
|
250
|
+
commandBarRef.current?.reset();
|
|
251
|
+
```
|
|
252
|
+
|
|
155
253
|
## Hooks
|
|
156
254
|
|
|
157
255
|
### useDevicChat
|
|
@@ -186,6 +284,42 @@ const {
|
|
|
186
284
|
});
|
|
187
285
|
```
|
|
188
286
|
|
|
287
|
+
### useAICommandBar
|
|
288
|
+
|
|
289
|
+
Hook for building custom command bar UIs.
|
|
290
|
+
|
|
291
|
+
```tsx
|
|
292
|
+
import { useAICommandBar } from '@devicai/ui';
|
|
293
|
+
|
|
294
|
+
const {
|
|
295
|
+
isVisible, // boolean
|
|
296
|
+
open, // () => void
|
|
297
|
+
close, // () => void
|
|
298
|
+
toggle, // () => void
|
|
299
|
+
inputValue, // string
|
|
300
|
+
setInputValue, // (value: string) => void
|
|
301
|
+
inputRef, // RefObject<HTMLInputElement>
|
|
302
|
+
focus, // () => void
|
|
303
|
+
isProcessing, // boolean
|
|
304
|
+
currentToolSummary, // string | null
|
|
305
|
+
toolCalls, // ToolCallSummary[]
|
|
306
|
+
result, // CommandBarResult | null
|
|
307
|
+
error, // Error | null
|
|
308
|
+
history, // string[]
|
|
309
|
+
showingHistory, // boolean
|
|
310
|
+
showingCommands, // boolean
|
|
311
|
+
filteredCommands, // AICommandBarCommand[]
|
|
312
|
+
submit, // (message?: string) => Promise<void>
|
|
313
|
+
reset, // () => void
|
|
314
|
+
handleKeyDown, // (e: KeyboardEvent) => void
|
|
315
|
+
} = useAICommandBar({
|
|
316
|
+
assistantId: 'my-assistant',
|
|
317
|
+
options: { shortcut: 'cmd+k' },
|
|
318
|
+
onResponse: (result) => {},
|
|
319
|
+
onError: (error) => {},
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
189
323
|
### useModelInterface
|
|
190
324
|
|
|
191
325
|
Hook for implementing the Model Interface Protocol.
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var useAIGenerationButton = require('./useAIGenerationButton.js');
|
|
6
|
+
|
|
7
|
+
const DEFAULT_OPTIONS = {
|
|
8
|
+
mode: 'modal',
|
|
9
|
+
prompt: '',
|
|
10
|
+
placeholder: 'Describe what you want to generate...',
|
|
11
|
+
modalTitle: 'Generate with AI',
|
|
12
|
+
modalDescription: '',
|
|
13
|
+
confirmText: 'Generate',
|
|
14
|
+
cancelText: 'Cancel',
|
|
15
|
+
tooltipPlacement: 'top',
|
|
16
|
+
tooltipWidth: 300,
|
|
17
|
+
variant: 'primary',
|
|
18
|
+
size: 'medium',
|
|
19
|
+
icon: undefined,
|
|
20
|
+
hideIcon: false,
|
|
21
|
+
label: 'Generate with AI',
|
|
22
|
+
hideLabel: false,
|
|
23
|
+
loadingLabel: 'Generating...',
|
|
24
|
+
color: '#3b82f6',
|
|
25
|
+
backgroundColor: '',
|
|
26
|
+
textColor: '',
|
|
27
|
+
borderColor: '',
|
|
28
|
+
borderRadius: 8,
|
|
29
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
30
|
+
fontSize: 14,
|
|
31
|
+
zIndex: 10000,
|
|
32
|
+
animationDuration: 200,
|
|
33
|
+
toolRenderers: undefined,
|
|
34
|
+
toolIcons: undefined,
|
|
35
|
+
processingMessage: 'Processing...',
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* AIGenerationButton component - a button that triggers AI generation with configurable interaction modes
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* // Direct mode - sends predefined prompt on click
|
|
43
|
+
* <AIGenerationButton
|
|
44
|
+
* assistantId="my-assistant"
|
|
45
|
+
* options={{
|
|
46
|
+
* mode: 'direct',
|
|
47
|
+
* prompt: 'Generate a summary of the current page',
|
|
48
|
+
* label: 'Summarize',
|
|
49
|
+
* }}
|
|
50
|
+
* onResponse={({ message }) => console.log(message.content)}
|
|
51
|
+
* />
|
|
52
|
+
*
|
|
53
|
+
* // Modal mode - opens modal for user input
|
|
54
|
+
* <AIGenerationButton
|
|
55
|
+
* assistantId="my-assistant"
|
|
56
|
+
* options={{
|
|
57
|
+
* mode: 'modal',
|
|
58
|
+
* modalTitle: 'Generate Content',
|
|
59
|
+
* placeholder: 'Describe what you want...',
|
|
60
|
+
* }}
|
|
61
|
+
* onResponse={({ message }) => setContent(message.content.message)}
|
|
62
|
+
* />
|
|
63
|
+
*
|
|
64
|
+
* // Tooltip mode - quick inline input
|
|
65
|
+
* <AIGenerationButton
|
|
66
|
+
* assistantId="my-assistant"
|
|
67
|
+
* options={{
|
|
68
|
+
* mode: 'tooltip',
|
|
69
|
+
* tooltipPlacement: 'bottom',
|
|
70
|
+
* }}
|
|
71
|
+
* onResponse={handleGeneration}
|
|
72
|
+
* />
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
const AIGenerationButton = React.forwardRef(function AIGenerationButton(props, ref) {
|
|
76
|
+
const { assistantId, apiKey, baseUrl, tenantId, tenantMetadata, options = {}, modelInterfaceTools, onResponse, onBeforeSend, onError, onStart, onOpen, onClose, disabled, className, containerClassName, children, theme, } = props;
|
|
77
|
+
const mergedOptions = React.useMemo(() => ({ ...DEFAULT_OPTIONS, ...options }), [options]);
|
|
78
|
+
const hook = useAIGenerationButton.useAIGenerationButton({
|
|
79
|
+
assistantId,
|
|
80
|
+
apiKey,
|
|
81
|
+
baseUrl,
|
|
82
|
+
tenantId,
|
|
83
|
+
tenantMetadata,
|
|
84
|
+
options: mergedOptions,
|
|
85
|
+
modelInterfaceTools,
|
|
86
|
+
onResponse,
|
|
87
|
+
onBeforeSend,
|
|
88
|
+
onError,
|
|
89
|
+
onStart,
|
|
90
|
+
onOpen,
|
|
91
|
+
onClose,
|
|
92
|
+
disabled,
|
|
93
|
+
});
|
|
94
|
+
// Expose handle
|
|
95
|
+
React.useImperativeHandle(ref, () => ({
|
|
96
|
+
generate: hook.generate,
|
|
97
|
+
open: hook.open,
|
|
98
|
+
close: hook.close,
|
|
99
|
+
reset: hook.reset,
|
|
100
|
+
isProcessing: hook.isProcessing,
|
|
101
|
+
}));
|
|
102
|
+
// Container ref for theming
|
|
103
|
+
const containerRef = React.useRef(null);
|
|
104
|
+
const tooltipRef = React.useRef(null);
|
|
105
|
+
// Apply CSS variables for theming
|
|
106
|
+
React.useEffect(() => {
|
|
107
|
+
const el = containerRef.current;
|
|
108
|
+
if (!el)
|
|
109
|
+
return;
|
|
110
|
+
const vars = [
|
|
111
|
+
['--devic-gen-primary', mergedOptions.color],
|
|
112
|
+
['----devic-gen-bg', mergedOptions.backgroundColor || undefined],
|
|
113
|
+
['--devic-gen-text', mergedOptions.textColor || undefined],
|
|
114
|
+
['--devic-gen-border', mergedOptions.borderColor || undefined],
|
|
115
|
+
['--devic-gen-font-family', mergedOptions.fontFamily],
|
|
116
|
+
['--devic-gen-font-size', typeof mergedOptions.fontSize === 'number' ? `${mergedOptions.fontSize}px` : mergedOptions.fontSize],
|
|
117
|
+
['--devic-gen-radius', typeof mergedOptions.borderRadius === 'number' ? `${mergedOptions.borderRadius}px` : mergedOptions.borderRadius],
|
|
118
|
+
['--devic-gen-z-index', String(mergedOptions.zIndex)],
|
|
119
|
+
['--devic-gen-animation-duration', `${mergedOptions.animationDuration}ms`],
|
|
120
|
+
];
|
|
121
|
+
// Apply theme from parent if provided
|
|
122
|
+
if (theme) {
|
|
123
|
+
if (theme.backgroundColor)
|
|
124
|
+
vars.push(['--devic-gen-modal-bg', theme.backgroundColor]);
|
|
125
|
+
if (theme.textColor)
|
|
126
|
+
vars.push(['--devic-gen-modal-text', theme.textColor]);
|
|
127
|
+
if (theme.borderColor)
|
|
128
|
+
vars.push(['--devic-gen-modal-border', theme.borderColor]);
|
|
129
|
+
if (theme.primaryColor)
|
|
130
|
+
vars.push(['--devic-gen-primary', theme.primaryColor]);
|
|
131
|
+
}
|
|
132
|
+
for (const [name, value] of vars) {
|
|
133
|
+
if (value) {
|
|
134
|
+
el.style.setProperty(name, value);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
el.style.removeProperty(name);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}, [mergedOptions, theme]);
|
|
141
|
+
// Click outside to close tooltip
|
|
142
|
+
React.useEffect(() => {
|
|
143
|
+
if (!hook.isOpen || mergedOptions.mode !== 'tooltip')
|
|
144
|
+
return;
|
|
145
|
+
const handleClickOutside = (e) => {
|
|
146
|
+
const tooltip = tooltipRef.current;
|
|
147
|
+
const container = containerRef.current;
|
|
148
|
+
if (tooltip &&
|
|
149
|
+
container &&
|
|
150
|
+
!tooltip.contains(e.target) &&
|
|
151
|
+
!container.contains(e.target)) {
|
|
152
|
+
hook.close();
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
156
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
157
|
+
}, [hook.isOpen, mergedOptions.mode, hook.close]);
|
|
158
|
+
// Handle button click
|
|
159
|
+
const handleButtonClick = React.useCallback(() => {
|
|
160
|
+
if (disabled || hook.isProcessing)
|
|
161
|
+
return;
|
|
162
|
+
if (mergedOptions.mode === 'direct') {
|
|
163
|
+
hook.generate();
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
hook.open();
|
|
167
|
+
}
|
|
168
|
+
}, [disabled, hook.isProcessing, mergedOptions.mode, hook.generate, hook.open]);
|
|
169
|
+
// Handle confirm in modal/tooltip
|
|
170
|
+
const handleConfirm = React.useCallback(() => {
|
|
171
|
+
hook.generate();
|
|
172
|
+
}, [hook.generate]);
|
|
173
|
+
// Tooltip position styles
|
|
174
|
+
const tooltipPositionStyle = React.useMemo(() => {
|
|
175
|
+
const placement = mergedOptions.tooltipPlacement;
|
|
176
|
+
const width = typeof mergedOptions.tooltipWidth === 'number'
|
|
177
|
+
? `${mergedOptions.tooltipWidth}px`
|
|
178
|
+
: mergedOptions.tooltipWidth;
|
|
179
|
+
const baseStyle = {
|
|
180
|
+
width,
|
|
181
|
+
position: 'absolute',
|
|
182
|
+
zIndex: mergedOptions.zIndex,
|
|
183
|
+
};
|
|
184
|
+
switch (placement) {
|
|
185
|
+
case 'top':
|
|
186
|
+
return { ...baseStyle, bottom: '100%', left: '50%', transform: 'translateX(-50%)', marginBottom: '8px' };
|
|
187
|
+
case 'bottom':
|
|
188
|
+
return { ...baseStyle, top: '100%', left: '50%', transform: 'translateX(-50%)', marginTop: '8px' };
|
|
189
|
+
case 'left':
|
|
190
|
+
return { ...baseStyle, right: '100%', top: '50%', transform: 'translateY(-50%)', marginRight: '8px' };
|
|
191
|
+
case 'right':
|
|
192
|
+
return { ...baseStyle, left: '100%', top: '50%', transform: 'translateY(-50%)', marginLeft: '8px' };
|
|
193
|
+
default:
|
|
194
|
+
return baseStyle;
|
|
195
|
+
}
|
|
196
|
+
}, [mergedOptions.tooltipPlacement, mergedOptions.tooltipWidth, mergedOptions.zIndex]);
|
|
197
|
+
// Render button content
|
|
198
|
+
// Only show loading state on button for direct mode (modal/tooltip have their own loading)
|
|
199
|
+
const showButtonLoading = hook.isProcessing && mergedOptions.mode === 'direct';
|
|
200
|
+
const renderButtonContent = () => {
|
|
201
|
+
if (children) {
|
|
202
|
+
return children;
|
|
203
|
+
}
|
|
204
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [!mergedOptions.hideIcon && (jsxRuntime.jsx("span", { className: "devic-gen-button-icon", children: showButtonLoading ? (jsxRuntime.jsx("span", { className: "devic-gen-spinner" })) : (mergedOptions.icon || jsxRuntime.jsx(SparklesIcon, {})) })), !mergedOptions.hideLabel && (jsxRuntime.jsx("span", { className: "devic-gen-button-label", children: showButtonLoading ? mergedOptions.loadingLabel : mergedOptions.label }))] }));
|
|
205
|
+
};
|
|
206
|
+
// Render tool calls display
|
|
207
|
+
const renderToolCalls = () => {
|
|
208
|
+
if (!hook.isProcessing || hook.toolCalls.length === 0) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
return (jsxRuntime.jsx("div", { className: "devic-gen-tool-calls", children: hook.toolCalls.map((tc) => {
|
|
212
|
+
// Check for custom renderer
|
|
213
|
+
const customRenderer = mergedOptions.toolRenderers?.[tc.name];
|
|
214
|
+
if (customRenderer && tc.status === 'completed') {
|
|
215
|
+
return (jsxRuntime.jsx("div", { className: "devic-gen-tool-item devic-gen-tool-custom", children: customRenderer(tc.input, tc.output) }, tc.id));
|
|
216
|
+
}
|
|
217
|
+
// Use custom icon or default
|
|
218
|
+
const customIcon = mergedOptions.toolIcons?.[tc.name];
|
|
219
|
+
const isExecuting = tc.status === 'executing';
|
|
220
|
+
return (jsxRuntime.jsxs("div", { className: "devic-gen-tool-item", "data-status": tc.status, children: [jsxRuntime.jsx("span", { className: "devic-gen-tool-icon", children: isExecuting ? (jsxRuntime.jsx("span", { className: "devic-gen-spinner devic-gen-spinner-small" })) : customIcon ? (customIcon) : (jsxRuntime.jsx(CheckIcon, {})) }), jsxRuntime.jsx("span", { className: "devic-gen-tool-name", children: tc.summary || tc.name })] }, tc.id));
|
|
221
|
+
}) }));
|
|
222
|
+
};
|
|
223
|
+
// Render processing status
|
|
224
|
+
const renderProcessingStatus = () => {
|
|
225
|
+
if (!hook.isProcessing)
|
|
226
|
+
return null;
|
|
227
|
+
return (jsxRuntime.jsxs("div", { className: "devic-gen-processing-status", children: [jsxRuntime.jsx("span", { className: "devic-gen-spinner devic-gen-spinner-small" }), jsxRuntime.jsx("span", { className: "devic-gen-processing-text", children: hook.currentToolSummary || mergedOptions.processingMessage })] }));
|
|
228
|
+
};
|
|
229
|
+
return (jsxRuntime.jsxs("div", { ref: containerRef, className: `devic-gen-container ${containerClassName || ''}`, style: { position: 'relative', display: 'inline-block' }, children: [jsxRuntime.jsx("button", { type: "button", className: `devic-gen-button ${className || ''}`, "data-variant": mergedOptions.variant, "data-size": mergedOptions.size, "data-processing": showButtonLoading, onClick: handleButtonClick, disabled: disabled || showButtonLoading, children: renderButtonContent() }), mergedOptions.mode === 'tooltip' && hook.isOpen && (jsxRuntime.jsxs("div", { ref: tooltipRef, className: "devic-gen-tooltip", style: tooltipPositionStyle, "data-placement": mergedOptions.tooltipPlacement, children: [renderToolCalls(), hook.isProcessing && hook.toolCalls.length === 0 && renderProcessingStatus(), jsxRuntime.jsx("textarea", { ref: hook.inputRef, className: "devic-gen-input", placeholder: mergedOptions.placeholder, value: hook.inputValue, onChange: (e) => hook.setInputValue(e.target.value), onKeyDown: hook.handleKeyDown, rows: 3, disabled: hook.isProcessing }), hook.error && (jsxRuntime.jsx("div", { className: "devic-gen-error", children: hook.error.message })), jsxRuntime.jsxs("div", { className: "devic-gen-tooltip-actions", children: [jsxRuntime.jsx("button", { type: "button", className: "devic-gen-tooltip-cancel", onClick: hook.close, disabled: hook.isProcessing, children: mergedOptions.cancelText }), jsxRuntime.jsx("button", { type: "button", className: "devic-gen-tooltip-confirm", onClick: handleConfirm, disabled: hook.isProcessing || !hook.inputValue.trim(), children: hook.isProcessing ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "devic-gen-spinner devic-gen-spinner-small" }), mergedOptions.loadingLabel] })) : (mergedOptions.confirmText) })] })] })), mergedOptions.mode === 'modal' && hook.isOpen && (jsxRuntime.jsx("div", { className: "devic-gen-modal-overlay", onClick: (e) => {
|
|
230
|
+
if (e.target === e.currentTarget && !hook.isProcessing)
|
|
231
|
+
hook.close();
|
|
232
|
+
}, children: jsxRuntime.jsxs("div", { className: "devic-gen-modal", children: [jsxRuntime.jsxs("div", { className: "devic-gen-modal-header", children: [jsxRuntime.jsx("h3", { className: "devic-gen-modal-title", children: mergedOptions.modalTitle }), jsxRuntime.jsx("button", { type: "button", className: "devic-gen-modal-close", onClick: hook.close, "aria-label": "Close", disabled: hook.isProcessing, children: jsxRuntime.jsx(CloseIcon, {}) })] }), mergedOptions.modalDescription && (jsxRuntime.jsx("p", { className: "devic-gen-modal-description", children: mergedOptions.modalDescription })), jsxRuntime.jsxs("div", { className: "devic-gen-modal-body", children: [renderToolCalls(), hook.isProcessing && hook.toolCalls.length === 0 && renderProcessingStatus(), jsxRuntime.jsx("textarea", { ref: hook.inputRef, className: "devic-gen-input", placeholder: mergedOptions.placeholder, value: hook.inputValue, onChange: (e) => hook.setInputValue(e.target.value), onKeyDown: hook.handleKeyDown, rows: 4, disabled: hook.isProcessing }), hook.error && (jsxRuntime.jsx("div", { className: "devic-gen-error", children: hook.error.message }))] }), jsxRuntime.jsxs("div", { className: "devic-gen-modal-footer", children: [jsxRuntime.jsx("button", { type: "button", className: "devic-gen-modal-cancel", onClick: hook.close, disabled: hook.isProcessing, children: mergedOptions.cancelText }), jsxRuntime.jsx("button", { type: "button", className: "devic-gen-modal-confirm", onClick: handleConfirm, disabled: hook.isProcessing || !hook.inputValue.trim(), children: hook.isProcessing ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "devic-gen-spinner devic-gen-spinner-small" }), mergedOptions.loadingLabel] })) : (mergedOptions.confirmText) })] })] }) }))] }));
|
|
233
|
+
});
|
|
234
|
+
/**
|
|
235
|
+
* Default sparkles icon
|
|
236
|
+
*/
|
|
237
|
+
function SparklesIcon() {
|
|
238
|
+
return (jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsxRuntime.jsx("path", { d: "M10 2L11.5 8.5L18 10L11.5 11.5L10 18L8.5 11.5L2 10L8.5 8.5L10 2Z", fill: "currentColor", opacity: "0.9" }), jsxRuntime.jsx("path", { d: "M16 3L16.5 5L18.5 5.5L16.5 6L16 8L15.5 6L13.5 5.5L15.5 5L16 3Z", fill: "currentColor", opacity: "0.6" }), jsxRuntime.jsx("circle", { cx: "4", cy: "15", r: "1", fill: "currentColor", opacity: "0.4" })] }));
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Close icon
|
|
242
|
+
*/
|
|
243
|
+
function CloseIcon() {
|
|
244
|
+
return (jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }));
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Check icon for completed tool calls
|
|
248
|
+
*/
|
|
249
|
+
function CheckIcon() {
|
|
250
|
+
return (jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) }));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
exports.AIGenerationButton = AIGenerationButton;
|
|
254
|
+
//# sourceMappingURL=AIGenerationButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AIGenerationButton.js","sources":["../../../../../src/components/AIGenerationButton/AIGenerationButton.tsx"],"sourcesContent":["import React, { forwardRef, useImperativeHandle, useMemo, useEffect, useRef, useCallback } from 'react';\nimport { useAIGenerationButton } from './useAIGenerationButton';\nimport type {\n AIGenerationButtonProps,\n AIGenerationButtonHandle,\n AIGenerationButtonOptions,\n} from './AIGenerationButton.types';\nimport './AIGenerationButton.css';\n\nconst DEFAULT_OPTIONS: Required<AIGenerationButtonOptions> = {\n mode: 'modal',\n prompt: '',\n placeholder: 'Describe what you want to generate...',\n modalTitle: 'Generate with AI',\n modalDescription: '',\n confirmText: 'Generate',\n cancelText: 'Cancel',\n tooltipPlacement: 'top',\n tooltipWidth: 300,\n variant: 'primary',\n size: 'medium',\n icon: undefined as any,\n hideIcon: false,\n label: 'Generate with AI',\n hideLabel: false,\n loadingLabel: 'Generating...',\n color: '#3b82f6',\n backgroundColor: '',\n textColor: '',\n borderColor: '',\n borderRadius: 8,\n fontFamily: \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\n fontSize: 14,\n zIndex: 10000,\n animationDuration: 200,\n toolRenderers: undefined as any,\n toolIcons: undefined as any,\n processingMessage: 'Processing...',\n};\n\n/**\n * AIGenerationButton component - a button that triggers AI generation with configurable interaction modes\n *\n * @example\n * ```tsx\n * // Direct mode - sends predefined prompt on click\n * <AIGenerationButton\n * assistantId=\"my-assistant\"\n * options={{\n * mode: 'direct',\n * prompt: 'Generate a summary of the current page',\n * label: 'Summarize',\n * }}\n * onResponse={({ message }) => console.log(message.content)}\n * />\n *\n * // Modal mode - opens modal for user input\n * <AIGenerationButton\n * assistantId=\"my-assistant\"\n * options={{\n * mode: 'modal',\n * modalTitle: 'Generate Content',\n * placeholder: 'Describe what you want...',\n * }}\n * onResponse={({ message }) => setContent(message.content.message)}\n * />\n *\n * // Tooltip mode - quick inline input\n * <AIGenerationButton\n * assistantId=\"my-assistant\"\n * options={{\n * mode: 'tooltip',\n * tooltipPlacement: 'bottom',\n * }}\n * onResponse={handleGeneration}\n * />\n * ```\n */\nexport const AIGenerationButton = forwardRef<AIGenerationButtonHandle, AIGenerationButtonProps>(\n function AIGenerationButton(props, ref) {\n const {\n assistantId,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n options = {},\n modelInterfaceTools,\n onResponse,\n onBeforeSend,\n onError,\n onStart,\n onOpen,\n onClose,\n disabled,\n className,\n containerClassName,\n children,\n theme,\n } = props;\n\n const mergedOptions = useMemo(\n () => ({ ...DEFAULT_OPTIONS, ...options }),\n [options]\n );\n\n const hook = useAIGenerationButton({\n assistantId,\n apiKey,\n baseUrl,\n tenantId,\n tenantMetadata,\n options: mergedOptions,\n modelInterfaceTools,\n onResponse,\n onBeforeSend,\n onError,\n onStart,\n onOpen,\n onClose,\n disabled,\n });\n\n // Expose handle\n useImperativeHandle(ref, () => ({\n generate: hook.generate,\n open: hook.open,\n close: hook.close,\n reset: hook.reset,\n isProcessing: hook.isProcessing,\n }));\n\n // Container ref for theming\n const containerRef = useRef<HTMLDivElement>(null);\n const tooltipRef = useRef<HTMLDivElement>(null);\n\n // Apply CSS variables for theming\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n\n const vars: [string, string | undefined][] = [\n ['--devic-gen-primary', mergedOptions.color],\n ['----devic-gen-bg', mergedOptions.backgroundColor || undefined],\n ['--devic-gen-text', mergedOptions.textColor || undefined],\n ['--devic-gen-border', mergedOptions.borderColor || undefined],\n ['--devic-gen-font-family', mergedOptions.fontFamily],\n ['--devic-gen-font-size', typeof mergedOptions.fontSize === 'number' ? `${mergedOptions.fontSize}px` : mergedOptions.fontSize],\n ['--devic-gen-radius', typeof mergedOptions.borderRadius === 'number' ? `${mergedOptions.borderRadius}px` : mergedOptions.borderRadius],\n ['--devic-gen-z-index', String(mergedOptions.zIndex)],\n ['--devic-gen-animation-duration', `${mergedOptions.animationDuration}ms`],\n ];\n\n // Apply theme from parent if provided\n if (theme) {\n if (theme.backgroundColor) vars.push(['--devic-gen-modal-bg', theme.backgroundColor]);\n if (theme.textColor) vars.push(['--devic-gen-modal-text', theme.textColor]);\n if (theme.borderColor) vars.push(['--devic-gen-modal-border', theme.borderColor]);\n if (theme.primaryColor) vars.push(['--devic-gen-primary', theme.primaryColor]);\n }\n\n for (const [name, value] of vars) {\n if (value) {\n el.style.setProperty(name, value);\n } else {\n el.style.removeProperty(name);\n }\n }\n }, [mergedOptions, theme]);\n\n // Click outside to close tooltip\n useEffect(() => {\n if (!hook.isOpen || mergedOptions.mode !== 'tooltip') return;\n\n const handleClickOutside = (e: MouseEvent) => {\n const tooltip = tooltipRef.current;\n const container = containerRef.current;\n if (\n tooltip &&\n container &&\n !tooltip.contains(e.target as Node) &&\n !container.contains(e.target as Node)\n ) {\n hook.close();\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [hook.isOpen, mergedOptions.mode, hook.close]);\n\n // Handle button click\n const handleButtonClick = useCallback(() => {\n if (disabled || hook.isProcessing) return;\n\n if (mergedOptions.mode === 'direct') {\n hook.generate();\n } else {\n hook.open();\n }\n }, [disabled, hook.isProcessing, mergedOptions.mode, hook.generate, hook.open]);\n\n // Handle confirm in modal/tooltip\n const handleConfirm = useCallback(() => {\n hook.generate();\n }, [hook.generate]);\n\n // Tooltip position styles\n const tooltipPositionStyle = useMemo(() => {\n const placement = mergedOptions.tooltipPlacement;\n const width = typeof mergedOptions.tooltipWidth === 'number'\n ? `${mergedOptions.tooltipWidth}px`\n : mergedOptions.tooltipWidth;\n\n const baseStyle: React.CSSProperties = {\n width,\n position: 'absolute',\n zIndex: mergedOptions.zIndex,\n };\n\n switch (placement) {\n case 'top':\n return { ...baseStyle, bottom: '100%', left: '50%', transform: 'translateX(-50%)', marginBottom: '8px' };\n case 'bottom':\n return { ...baseStyle, top: '100%', left: '50%', transform: 'translateX(-50%)', marginTop: '8px' };\n case 'left':\n return { ...baseStyle, right: '100%', top: '50%', transform: 'translateY(-50%)', marginRight: '8px' };\n case 'right':\n return { ...baseStyle, left: '100%', top: '50%', transform: 'translateY(-50%)', marginLeft: '8px' };\n default:\n return baseStyle;\n }\n }, [mergedOptions.tooltipPlacement, mergedOptions.tooltipWidth, mergedOptions.zIndex]);\n\n // Render button content\n // Only show loading state on button for direct mode (modal/tooltip have their own loading)\n const showButtonLoading = hook.isProcessing && mergedOptions.mode === 'direct';\n\n const renderButtonContent = () => {\n if (children) {\n return children;\n }\n\n return (\n <>\n {!mergedOptions.hideIcon && (\n <span className=\"devic-gen-button-icon\">\n {showButtonLoading ? (\n <span className=\"devic-gen-spinner\" />\n ) : (\n mergedOptions.icon || <SparklesIcon />\n )}\n </span>\n )}\n {!mergedOptions.hideLabel && (\n <span className=\"devic-gen-button-label\">\n {showButtonLoading ? mergedOptions.loadingLabel : mergedOptions.label}\n </span>\n )}\n </>\n );\n };\n\n // Render tool calls display\n const renderToolCalls = () => {\n if (!hook.isProcessing || hook.toolCalls.length === 0) {\n return null;\n }\n\n return (\n <div className=\"devic-gen-tool-calls\">\n {hook.toolCalls.map((tc) => {\n // Check for custom renderer\n const customRenderer = mergedOptions.toolRenderers?.[tc.name];\n if (customRenderer && tc.status === 'completed') {\n return (\n <div key={tc.id} className=\"devic-gen-tool-item devic-gen-tool-custom\">\n {customRenderer(tc.input, tc.output)}\n </div>\n );\n }\n\n // Use custom icon or default\n const customIcon = mergedOptions.toolIcons?.[tc.name];\n const isExecuting = tc.status === 'executing';\n\n return (\n <div\n key={tc.id}\n className=\"devic-gen-tool-item\"\n data-status={tc.status}\n >\n <span className=\"devic-gen-tool-icon\">\n {isExecuting ? (\n <span className=\"devic-gen-spinner devic-gen-spinner-small\" />\n ) : customIcon ? (\n customIcon\n ) : (\n <CheckIcon />\n )}\n </span>\n <span className=\"devic-gen-tool-name\">{tc.summary || tc.name}</span>\n </div>\n );\n })}\n </div>\n );\n };\n\n // Render processing status\n const renderProcessingStatus = () => {\n if (!hook.isProcessing) return null;\n\n return (\n <div className=\"devic-gen-processing-status\">\n <span className=\"devic-gen-spinner devic-gen-spinner-small\" />\n <span className=\"devic-gen-processing-text\">\n {hook.currentToolSummary || mergedOptions.processingMessage}\n </span>\n </div>\n );\n };\n\n return (\n <div\n ref={containerRef}\n className={`devic-gen-container ${containerClassName || ''}`}\n style={{ position: 'relative', display: 'inline-block' }}\n >\n {/* Button */}\n <button\n type=\"button\"\n className={`devic-gen-button ${className || ''}`}\n data-variant={mergedOptions.variant}\n data-size={mergedOptions.size}\n data-processing={showButtonLoading}\n onClick={handleButtonClick}\n disabled={disabled || showButtonLoading}\n >\n {renderButtonContent()}\n </button>\n\n {/* Tooltip */}\n {mergedOptions.mode === 'tooltip' && hook.isOpen && (\n <div\n ref={tooltipRef}\n className=\"devic-gen-tooltip\"\n style={tooltipPositionStyle}\n data-placement={mergedOptions.tooltipPlacement}\n >\n {/* Tool calls display */}\n {renderToolCalls()}\n {/* Processing status when no tool calls yet */}\n {hook.isProcessing && hook.toolCalls.length === 0 && renderProcessingStatus()}\n <textarea\n ref={hook.inputRef}\n className=\"devic-gen-input\"\n placeholder={mergedOptions.placeholder}\n value={hook.inputValue}\n onChange={(e) => hook.setInputValue(e.target.value)}\n onKeyDown={hook.handleKeyDown}\n rows={3}\n disabled={hook.isProcessing}\n />\n {hook.error && (\n <div className=\"devic-gen-error\">{hook.error.message}</div>\n )}\n <div className=\"devic-gen-tooltip-actions\">\n <button\n type=\"button\"\n className=\"devic-gen-tooltip-cancel\"\n onClick={hook.close}\n disabled={hook.isProcessing}\n >\n {mergedOptions.cancelText}\n </button>\n <button\n type=\"button\"\n className=\"devic-gen-tooltip-confirm\"\n onClick={handleConfirm}\n disabled={hook.isProcessing || !hook.inputValue.trim()}\n >\n {hook.isProcessing ? (\n <>\n <span className=\"devic-gen-spinner devic-gen-spinner-small\" />\n {mergedOptions.loadingLabel}\n </>\n ) : (\n mergedOptions.confirmText\n )}\n </button>\n </div>\n </div>\n )}\n\n {/* Modal */}\n {mergedOptions.mode === 'modal' && hook.isOpen && (\n <div\n className=\"devic-gen-modal-overlay\"\n onClick={(e) => {\n if (e.target === e.currentTarget && !hook.isProcessing) hook.close();\n }}\n >\n <div className=\"devic-gen-modal\">\n <div className=\"devic-gen-modal-header\">\n <h3 className=\"devic-gen-modal-title\">{mergedOptions.modalTitle}</h3>\n <button\n type=\"button\"\n className=\"devic-gen-modal-close\"\n onClick={hook.close}\n aria-label=\"Close\"\n disabled={hook.isProcessing}\n >\n <CloseIcon />\n </button>\n </div>\n {mergedOptions.modalDescription && (\n <p className=\"devic-gen-modal-description\">{mergedOptions.modalDescription}</p>\n )}\n <div className=\"devic-gen-modal-body\">\n {/* Tool calls display */}\n {renderToolCalls()}\n {/* Processing status when no tool calls yet */}\n {hook.isProcessing && hook.toolCalls.length === 0 && renderProcessingStatus()}\n <textarea\n ref={hook.inputRef}\n className=\"devic-gen-input\"\n placeholder={mergedOptions.placeholder}\n value={hook.inputValue}\n onChange={(e) => hook.setInputValue(e.target.value)}\n onKeyDown={hook.handleKeyDown}\n rows={4}\n disabled={hook.isProcessing}\n />\n {hook.error && (\n <div className=\"devic-gen-error\">{hook.error.message}</div>\n )}\n </div>\n <div className=\"devic-gen-modal-footer\">\n <button\n type=\"button\"\n className=\"devic-gen-modal-cancel\"\n onClick={hook.close}\n disabled={hook.isProcessing}\n >\n {mergedOptions.cancelText}\n </button>\n <button\n type=\"button\"\n className=\"devic-gen-modal-confirm\"\n onClick={handleConfirm}\n disabled={hook.isProcessing || !hook.inputValue.trim()}\n >\n {hook.isProcessing ? (\n <>\n <span className=\"devic-gen-spinner devic-gen-spinner-small\" />\n {mergedOptions.loadingLabel}\n </>\n ) : (\n mergedOptions.confirmText\n )}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n }\n);\n\n/**\n * Default sparkles icon\n */\nfunction SparklesIcon(): JSX.Element {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 2L11.5 8.5L18 10L11.5 11.5L10 18L8.5 11.5L2 10L8.5 8.5L10 2Z\"\n fill=\"currentColor\"\n opacity=\"0.9\"\n />\n <path\n d=\"M16 3L16.5 5L18.5 5.5L16.5 6L16 8L15.5 6L13.5 5.5L15.5 5L16 3Z\"\n fill=\"currentColor\"\n opacity=\"0.6\"\n />\n <circle cx=\"4\" cy=\"15\" r=\"1\" fill=\"currentColor\" opacity=\"0.4\" />\n </svg>\n );\n}\n\n/**\n * Close icon\n */\nfunction CloseIcon(): JSX.Element {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\n/**\n * Check icon for completed tool calls\n */\nfunction CheckIcon(): JSX.Element {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n );\n}\n"],"names":["forwardRef","useMemo","useAIGenerationButton","useImperativeHandle","useRef","useEffect","useCallback","_jsxs","_Fragment","_jsx"],"mappings":"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"}
|