dynim-react 1.0.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 +447 -0
- package/dist/builder/BuilderProvider.d.ts +99 -0
- package/dist/builder/BuilderProvider.d.ts.map +1 -0
- package/dist/builder/BuilderProvider.js +339 -0
- package/dist/builder/ChatContext.d.ts +11 -0
- package/dist/builder/ChatContext.d.ts.map +1 -0
- package/dist/builder/ChatContext.js +18 -0
- package/dist/builder/ChatInput.d.ts +11 -0
- package/dist/builder/ChatInput.d.ts.map +1 -0
- package/dist/builder/ChatInput.js +20 -0
- package/dist/builder/CodeChatPanel.d.ts +24 -0
- package/dist/builder/CodeChatPanel.d.ts.map +1 -0
- package/dist/builder/CodeChatPanel.js +299 -0
- package/dist/builder/EditableZone.d.ts +73 -0
- package/dist/builder/EditableZone.d.ts.map +1 -0
- package/dist/builder/EditableZone.js +83 -0
- package/dist/builder/MessageList.d.ts +14 -0
- package/dist/builder/MessageList.d.ts.map +1 -0
- package/dist/builder/MessageList.js +23 -0
- package/dist/builder/index.d.ts +18 -0
- package/dist/builder/index.d.ts.map +1 -0
- package/dist/builder/index.js +15 -0
- package/dist/builder/useChatbot.d.ts +24 -0
- package/dist/builder/useChatbot.d.ts.map +1 -0
- package/dist/builder/useChatbot.js +85 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/inference/DynimProvider.d.ts +23 -0
- package/dist/inference/DynimProvider.d.ts.map +1 -0
- package/dist/inference/DynimProvider.js +231 -0
- package/dist/inference/InferenceProvider.d.ts +23 -0
- package/dist/inference/InferenceProvider.d.ts.map +1 -0
- package/dist/inference/InferenceProvider.js +270 -0
- package/dist/inference/createDynimSDK.d.ts +39 -0
- package/dist/inference/createDynimSDK.d.ts.map +1 -0
- package/dist/inference/createDynimSDK.js +61 -0
- package/dist/inference/index.d.ts +7 -0
- package/dist/inference/index.d.ts.map +1 -0
- package/dist/inference/index.js +7 -0
- package/dist/inference/sharedContext.d.ts +39 -0
- package/dist/inference/sharedContext.d.ts.map +1 -0
- package/dist/inference/sharedContext.js +61 -0
- package/dist/inference/types.d.ts +67 -0
- package/dist/inference/types.d.ts.map +1 -0
- package/dist/inference/types.js +1 -0
- package/package.json +30 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* BuilderProvider - React integration for the visual builder
|
|
4
|
+
*
|
|
5
|
+
* Integrates the visual builder UI (floating bar, drag engine, overlays)
|
|
6
|
+
* from dynim-core.
|
|
7
|
+
*/
|
|
8
|
+
import { createContext, useContext, useEffect, useRef, useCallback, useMemo, useState, } from 'react';
|
|
9
|
+
import { createBuilderClient, createBuilder, createCodeClient, createBundleManager, createStyleApplier, hasStyleChanges, } from 'dynim-core';
|
|
10
|
+
const BuilderContext = createContext(null);
|
|
11
|
+
/**
|
|
12
|
+
* BuilderProvider - Wraps your app with builder support
|
|
13
|
+
*/
|
|
14
|
+
export function BuilderProvider({ children, config = {}, onBuilderReady, }) {
|
|
15
|
+
const builderClientRef = useRef(null);
|
|
16
|
+
const builderRef = useRef(null);
|
|
17
|
+
const codeClientRef = useRef(null);
|
|
18
|
+
const bundleManagerRef = useRef(null);
|
|
19
|
+
const styleApplierRef = useRef(null);
|
|
20
|
+
const [internalContainer, setInternalContainer] = useState(null);
|
|
21
|
+
const [isBuilderActive, setIsBuilderActive] = useState(false);
|
|
22
|
+
const [isBundleLoaded, setIsBundleLoaded] = useState(false);
|
|
23
|
+
const [isBundleLoading, setIsBundleLoading] = useState(false);
|
|
24
|
+
const [hasBundleManager, setHasBundleManager] = useState(false);
|
|
25
|
+
const [codeMessage, setCodeMessage] = useState({
|
|
26
|
+
thinking: '',
|
|
27
|
+
text: '',
|
|
28
|
+
edits: [],
|
|
29
|
+
status: 'idle',
|
|
30
|
+
bundleReady: false,
|
|
31
|
+
bundleError: undefined,
|
|
32
|
+
});
|
|
33
|
+
// Initialize visual builder (createBuilder from core)
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const { apiBase = 'http://localhost:8080', pageId = window.location.pathname, logo = 'Builder', contentRoot = document.body, sessionToken, refreshToken, getSession, } = config;
|
|
36
|
+
// Create the visual builder instance
|
|
37
|
+
builderRef.current = createBuilder({
|
|
38
|
+
logo,
|
|
39
|
+
contentRoot,
|
|
40
|
+
pageId,
|
|
41
|
+
apiBase,
|
|
42
|
+
sessionToken,
|
|
43
|
+
refreshToken,
|
|
44
|
+
getSession,
|
|
45
|
+
onEnter: () => {
|
|
46
|
+
console.log('[BuilderProvider] Visual builder entered');
|
|
47
|
+
setIsBuilderActive(true);
|
|
48
|
+
},
|
|
49
|
+
onExit: () => {
|
|
50
|
+
console.log('[BuilderProvider] Visual builder exited');
|
|
51
|
+
setIsBuilderActive(false);
|
|
52
|
+
},
|
|
53
|
+
onSave: (diffs) => {
|
|
54
|
+
console.log('[BuilderProvider] Changes saved:', diffs);
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
return () => {
|
|
58
|
+
builderRef.current?.destroy();
|
|
59
|
+
};
|
|
60
|
+
}, [config]);
|
|
61
|
+
// Initialize builder client for visual builder operations (saveDiffs, preview, exit)
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
const { apiBase = 'http://localhost:8080', sessionToken, refreshToken, getSession, onError, } = config;
|
|
64
|
+
builderClientRef.current = createBuilderClient({
|
|
65
|
+
apiBase,
|
|
66
|
+
sessionToken,
|
|
67
|
+
refreshToken,
|
|
68
|
+
getSession,
|
|
69
|
+
onError: (error) => {
|
|
70
|
+
console.error('[BuilderProvider] Error:', error);
|
|
71
|
+
onError?.(error);
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}, [config]);
|
|
75
|
+
// Initialize bundle manager
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
const { previewContainer, inPlacePreview = true, previewTransitionDuration = 300, onStyleApplied, onBundleLoadStart, onBundleLoadComplete, onError, } = config;
|
|
78
|
+
// Determine which container to use
|
|
79
|
+
const container = inPlacePreview ? internalContainer : previewContainer;
|
|
80
|
+
if (!container) {
|
|
81
|
+
// For inPlacePreview, container may not be ready on first render
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
bundleManagerRef.current = createBundleManager({
|
|
85
|
+
parent: container,
|
|
86
|
+
transitionDuration: previewTransitionDuration,
|
|
87
|
+
onLoadStart: (url) => {
|
|
88
|
+
setIsBundleLoading(true);
|
|
89
|
+
onBundleLoadStart?.(url);
|
|
90
|
+
},
|
|
91
|
+
onLoadComplete: (url) => {
|
|
92
|
+
setIsBundleLoading(false);
|
|
93
|
+
setIsBundleLoaded(true);
|
|
94
|
+
onBundleLoadComplete?.(url);
|
|
95
|
+
},
|
|
96
|
+
onError: (error) => {
|
|
97
|
+
setIsBundleLoading(false);
|
|
98
|
+
console.error('[BuilderProvider] Bundle load error:', error);
|
|
99
|
+
onError?.(error);
|
|
100
|
+
},
|
|
101
|
+
onUnload: () => {
|
|
102
|
+
setIsBundleLoaded(false);
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
setHasBundleManager(true);
|
|
106
|
+
// Create style applier that targets the bundle manager's container
|
|
107
|
+
styleApplierRef.current = createStyleApplier({
|
|
108
|
+
queryElements: (selector) => {
|
|
109
|
+
const container = bundleManagerRef.current?.getActiveContainer();
|
|
110
|
+
return container?.querySelectorAll(selector) ?? document.querySelectorAll(selector);
|
|
111
|
+
},
|
|
112
|
+
onApply: (change, elements) => {
|
|
113
|
+
console.log('[BuilderProvider] Style applied:', change, elements.length, 'elements');
|
|
114
|
+
onStyleApplied?.(change, elements);
|
|
115
|
+
},
|
|
116
|
+
onError: (change, error) => {
|
|
117
|
+
console.error('[BuilderProvider] Style apply error:', error, change);
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
return () => {
|
|
121
|
+
bundleManagerRef.current?.destroy();
|
|
122
|
+
bundleManagerRef.current = null;
|
|
123
|
+
styleApplierRef.current = null;
|
|
124
|
+
setHasBundleManager(false);
|
|
125
|
+
};
|
|
126
|
+
}, [config, internalContainer]);
|
|
127
|
+
// Initialize code client for flexcode integration
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
const { apiBase = 'http://localhost:8080', sessionToken, refreshToken, getSession, onCodeMessageUpdate, onCodeMessage, // deprecated
|
|
130
|
+
onCodeEdit, onError, autoApplyStyles = true, } = config;
|
|
131
|
+
codeClientRef.current = createCodeClient({
|
|
132
|
+
apiBase,
|
|
133
|
+
sessionToken,
|
|
134
|
+
refreshToken,
|
|
135
|
+
getSession,
|
|
136
|
+
onMessageUpdate: (message) => {
|
|
137
|
+
// Update local state with the structured message
|
|
138
|
+
setCodeMessage(message);
|
|
139
|
+
// Forward to consumer callback
|
|
140
|
+
onCodeMessageUpdate?.(message);
|
|
141
|
+
},
|
|
142
|
+
onRawEvent: (event) => {
|
|
143
|
+
// Forward raw events for debugging/advanced use
|
|
144
|
+
onCodeMessage?.(event);
|
|
145
|
+
},
|
|
146
|
+
onEdit: (edit) => {
|
|
147
|
+
console.log('[BuilderProvider] Code edit:', edit);
|
|
148
|
+
// Auto-apply style changes if enabled and style applier is available
|
|
149
|
+
if (autoApplyStyles && styleApplierRef.current && hasStyleChanges(edit)) {
|
|
150
|
+
const result = styleApplierRef.current.processEdit(edit);
|
|
151
|
+
console.log('[BuilderProvider] Style changes:', result.changes.length, 'applied:', result.applied);
|
|
152
|
+
}
|
|
153
|
+
onCodeEdit?.(edit);
|
|
154
|
+
},
|
|
155
|
+
onError: (error) => {
|
|
156
|
+
console.error('[BuilderProvider] Code error:', error);
|
|
157
|
+
onError?.(error);
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
}, [config]);
|
|
161
|
+
// Enter builder mode - activates the visual builder UI
|
|
162
|
+
const enterBuilder = useCallback(() => {
|
|
163
|
+
if (builderRef.current && !builderRef.current.isActive()) {
|
|
164
|
+
builderRef.current.enter();
|
|
165
|
+
}
|
|
166
|
+
}, []);
|
|
167
|
+
// Exit builder mode - deactivates the visual builder UI
|
|
168
|
+
const exitBuilder = useCallback(() => {
|
|
169
|
+
if (builderRef.current && builderRef.current.isActive()) {
|
|
170
|
+
builderRef.current.exit();
|
|
171
|
+
}
|
|
172
|
+
}, []);
|
|
173
|
+
// Save and exit builder mode
|
|
174
|
+
const saveBuilder = useCallback(async () => {
|
|
175
|
+
if (builderRef.current && builderRef.current.isActive()) {
|
|
176
|
+
await builderRef.current.save();
|
|
177
|
+
}
|
|
178
|
+
}, []);
|
|
179
|
+
// Bundle manager methods (defined first since saveCode depends on loadProjectBundle)
|
|
180
|
+
const loadBundle = useCallback(async (bundleUrl) => {
|
|
181
|
+
if (!bundleManagerRef.current) {
|
|
182
|
+
console.warn('[BuilderProvider] Bundle manager not initialized (no previewContainer)');
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
await bundleManagerRef.current.load(bundleUrl);
|
|
186
|
+
}, []);
|
|
187
|
+
const loadProjectBundle = useCallback(async (projectId, forceReload = false) => {
|
|
188
|
+
const { getBundleUrl, apiBase = 'http://localhost:8080' } = config;
|
|
189
|
+
let bundleUrl;
|
|
190
|
+
if (getBundleUrl) {
|
|
191
|
+
bundleUrl = await getBundleUrl(projectId);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
bundleUrl = `${apiBase.replace(':8080', ':8081')}/bundles/preview?project_id=${projectId}`;
|
|
195
|
+
}
|
|
196
|
+
// Cache bust to force reload (bypasses bundle manager's same-URL skip)
|
|
197
|
+
if (forceReload) {
|
|
198
|
+
bundleUrl += `&_t=${Date.now()}`;
|
|
199
|
+
}
|
|
200
|
+
await loadBundle(bundleUrl);
|
|
201
|
+
}, [config, loadBundle]);
|
|
202
|
+
// Load saved (permanent) bundle - used for initial load, after save, and after abandon
|
|
203
|
+
const loadSavedBundle = useCallback(async (projectId) => {
|
|
204
|
+
const { apiBase = 'http://localhost:8080' } = config;
|
|
205
|
+
const bundleUrl = `${apiBase.replace(':8080', ':8081')}/bundles/saved?project_id=${projectId}`;
|
|
206
|
+
await loadBundle(bundleUrl);
|
|
207
|
+
}, [config, loadBundle]);
|
|
208
|
+
// Load temp bundle - used when AI finishes editing to preview changes
|
|
209
|
+
const loadTempBundle = useCallback(async (projectId) => {
|
|
210
|
+
const { apiBase = 'http://localhost:8080' } = config;
|
|
211
|
+
const bundleUrl = `${apiBase.replace(':8080', ':8081')}/bundles/temp?project_id=${projectId}`;
|
|
212
|
+
console.log('[BuilderProvider] Loading temp bundle:', bundleUrl);
|
|
213
|
+
await loadBundle(bundleUrl);
|
|
214
|
+
console.log('[BuilderProvider] Temp bundle loaded');
|
|
215
|
+
}, [config, loadBundle]);
|
|
216
|
+
// Auto-reload temp bundle when bundle is ready (projectId comes from server event)
|
|
217
|
+
useEffect(() => {
|
|
218
|
+
if (codeMessage.bundleReady &&
|
|
219
|
+
codeMessage.projectId &&
|
|
220
|
+
bundleManagerRef.current) {
|
|
221
|
+
console.log('[BuilderProvider] Bundle ready - loading temp bundle:', codeMessage.projectId);
|
|
222
|
+
loadTempBundle(codeMessage.projectId);
|
|
223
|
+
}
|
|
224
|
+
}, [codeMessage.bundleReady, codeMessage.projectId, loadTempBundle]);
|
|
225
|
+
const applyStyles = useCallback((selector, styles) => {
|
|
226
|
+
bundleManagerRef.current?.applyStyles(selector, styles);
|
|
227
|
+
}, []);
|
|
228
|
+
const applyClassName = useCallback((selector, className) => {
|
|
229
|
+
bundleManagerRef.current?.applyClassName(selector, className);
|
|
230
|
+
}, []);
|
|
231
|
+
const toggleClasses = useCallback((selector, add, remove) => {
|
|
232
|
+
bundleManagerRef.current?.toggleClasses(selector, add, remove);
|
|
233
|
+
}, []);
|
|
234
|
+
const unloadBundle = useCallback(() => {
|
|
235
|
+
bundleManagerRef.current?.unload();
|
|
236
|
+
}, []);
|
|
237
|
+
// Code client methods (projectId comes from JWT on server, or from codeMessage for bundles)
|
|
238
|
+
const sendCode = useCallback(async (query) => {
|
|
239
|
+
await codeClientRef.current?.sendCode(query);
|
|
240
|
+
}, []);
|
|
241
|
+
const saveCode = useCallback(async () => {
|
|
242
|
+
// 1. Persist changes to backend (promotes temp to saved)
|
|
243
|
+
await codeClientRef.current?.saveCode();
|
|
244
|
+
// 2. Load the newly saved bundle (projectId from last bundle_ready event)
|
|
245
|
+
if (bundleManagerRef.current && codeMessage.projectId) {
|
|
246
|
+
await loadSavedBundle(codeMessage.projectId);
|
|
247
|
+
}
|
|
248
|
+
}, [loadSavedBundle, codeMessage.projectId]);
|
|
249
|
+
const abandonCode = useCallback(async () => {
|
|
250
|
+
// 1. Discard temp changes on server
|
|
251
|
+
await codeClientRef.current?.abandonCode();
|
|
252
|
+
// 2. Revert to saved bundle (projectId from last bundle_ready event)
|
|
253
|
+
if (bundleManagerRef.current && codeMessage.projectId) {
|
|
254
|
+
await loadSavedBundle(codeMessage.projectId);
|
|
255
|
+
}
|
|
256
|
+
}, [loadSavedBundle, codeMessage.projectId]);
|
|
257
|
+
const warmCache = useCallback(async () => {
|
|
258
|
+
await codeClientRef.current?.warmCache();
|
|
259
|
+
}, []);
|
|
260
|
+
const resetCodeMessage = useCallback(() => {
|
|
261
|
+
codeClientRef.current?.resetMessage();
|
|
262
|
+
}, []);
|
|
263
|
+
const contextValue = useMemo(() => ({
|
|
264
|
+
enterBuilder,
|
|
265
|
+
exitBuilder,
|
|
266
|
+
saveBuilder,
|
|
267
|
+
isBuilderActive,
|
|
268
|
+
getBuilder: () => builderRef.current,
|
|
269
|
+
// Code client methods (all AI chat goes through sendCode)
|
|
270
|
+
sendCode,
|
|
271
|
+
saveCode,
|
|
272
|
+
abandonCode,
|
|
273
|
+
warmCache,
|
|
274
|
+
codeMessage,
|
|
275
|
+
resetCodeMessage,
|
|
276
|
+
// Deprecated - use codeMessage.edits instead
|
|
277
|
+
codeEdits: codeMessage.edits,
|
|
278
|
+
// Bundle manager methods
|
|
279
|
+
loadBundle,
|
|
280
|
+
loadProjectBundle,
|
|
281
|
+
loadSavedBundle,
|
|
282
|
+
loadTempBundle,
|
|
283
|
+
applyStyles,
|
|
284
|
+
applyClassName,
|
|
285
|
+
toggleClasses,
|
|
286
|
+
hasBundleManager,
|
|
287
|
+
isBundleLoaded,
|
|
288
|
+
isBundleLoading,
|
|
289
|
+
unloadBundle,
|
|
290
|
+
}), [
|
|
291
|
+
enterBuilder,
|
|
292
|
+
exitBuilder,
|
|
293
|
+
saveBuilder,
|
|
294
|
+
isBuilderActive,
|
|
295
|
+
sendCode,
|
|
296
|
+
saveCode,
|
|
297
|
+
abandonCode,
|
|
298
|
+
warmCache,
|
|
299
|
+
codeMessage,
|
|
300
|
+
resetCodeMessage,
|
|
301
|
+
loadBundle,
|
|
302
|
+
loadProjectBundle,
|
|
303
|
+
loadSavedBundle,
|
|
304
|
+
loadTempBundle,
|
|
305
|
+
applyStyles,
|
|
306
|
+
applyClassName,
|
|
307
|
+
toggleClasses,
|
|
308
|
+
hasBundleManager,
|
|
309
|
+
isBundleLoaded,
|
|
310
|
+
isBundleLoading,
|
|
311
|
+
unloadBundle,
|
|
312
|
+
]);
|
|
313
|
+
// Notify parent when ready (only once on mount)
|
|
314
|
+
const hasNotifiedRef = useRef(false);
|
|
315
|
+
useEffect(() => {
|
|
316
|
+
if (!hasNotifiedRef.current && onBuilderReady) {
|
|
317
|
+
hasNotifiedRef.current = true;
|
|
318
|
+
onBuilderReady(contextValue);
|
|
319
|
+
}
|
|
320
|
+
}, [contextValue, onBuilderReady]);
|
|
321
|
+
const { inPlacePreview = true } = config;
|
|
322
|
+
// Callback ref to capture container element
|
|
323
|
+
const containerRefCallback = useCallback((node) => {
|
|
324
|
+
if (node) {
|
|
325
|
+
setInternalContainer(node);
|
|
326
|
+
}
|
|
327
|
+
}, []);
|
|
328
|
+
return (_jsxs(BuilderContext.Provider, { value: contextValue, children: [(!inPlacePreview || !isBundleLoaded) && children, inPlacePreview && (_jsx("div", { ref: containerRefCallback, style: { display: isBundleLoaded ? 'block' : 'none' } }))] }));
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Hook to access builder functionality
|
|
332
|
+
*/
|
|
333
|
+
export function useBuilder() {
|
|
334
|
+
const context = useContext(BuilderContext);
|
|
335
|
+
if (!context) {
|
|
336
|
+
throw new Error('useBuilder must be used within a BuilderProvider');
|
|
337
|
+
}
|
|
338
|
+
return context;
|
|
339
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Context for sharing chatbot state across components
|
|
3
|
+
*/
|
|
4
|
+
import { type ReactNode } from 'react';
|
|
5
|
+
import { type UseChatbotConfig, type UseChatbotReturn } from './useChatbot';
|
|
6
|
+
export interface ChatProviderProps extends UseChatbotConfig {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare function ChatProvider({ children, ...config }: ChatProviderProps): JSX.Element;
|
|
10
|
+
export declare function useChatContext(): UseChatbotReturn;
|
|
11
|
+
//# sourceMappingURL=ChatContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatContext.d.ts","sourceRoot":"","sources":["../../src/builder/ChatContext.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EAAc,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIxF,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,EAAE,iBAAiB,GAAG,GAAG,CAAC,OAAO,CAIpF;AAED,wBAAgB,cAAc,IAAI,gBAAgB,CAMjD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* React Context for sharing chatbot state across components
|
|
4
|
+
*/
|
|
5
|
+
import { createContext, useContext } from 'react';
|
|
6
|
+
import { useChatbot } from './useChatbot';
|
|
7
|
+
const ChatContext = createContext(null);
|
|
8
|
+
export function ChatProvider({ children, ...config }) {
|
|
9
|
+
const chatbot = useChatbot(config);
|
|
10
|
+
return _jsx(ChatContext.Provider, { value: chatbot, children: children });
|
|
11
|
+
}
|
|
12
|
+
export function useChatContext() {
|
|
13
|
+
const context = useContext(ChatContext);
|
|
14
|
+
if (!context) {
|
|
15
|
+
throw new Error('useChatContext must be used within a ChatProvider');
|
|
16
|
+
}
|
|
17
|
+
return context;
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat input component
|
|
3
|
+
*/
|
|
4
|
+
export interface ChatInputProps {
|
|
5
|
+
className?: string;
|
|
6
|
+
placeholder?: string;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
onSubmit?: (text: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function ChatInput({ className, placeholder, disabled, onSubmit, }: ChatInputProps): JSX.Element;
|
|
11
|
+
//# sourceMappingURL=ChatInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatInput.d.ts","sourceRoot":"","sources":["../../src/builder/ChatInput.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAc,EACd,WAAiC,EACjC,QAAgB,EAChB,QAAQ,GACT,EAAE,cAAc,GAAG,GAAG,CAAC,OAAO,CAuC9B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Chat input component
|
|
4
|
+
*/
|
|
5
|
+
import { useState, useCallback } from 'react';
|
|
6
|
+
import { useChatContext } from './ChatContext';
|
|
7
|
+
export function ChatInput({ className = '', placeholder = 'Type a message...', disabled = false, onSubmit, }) {
|
|
8
|
+
const { sendMessage, isLoading } = useChatContext();
|
|
9
|
+
const [value, setValue] = useState('');
|
|
10
|
+
const handleSubmit = useCallback((e) => {
|
|
11
|
+
e.preventDefault();
|
|
12
|
+
const text = value.trim();
|
|
13
|
+
if (!text || isLoading)
|
|
14
|
+
return;
|
|
15
|
+
setValue('');
|
|
16
|
+
onSubmit?.(text);
|
|
17
|
+
sendMessage(text);
|
|
18
|
+
}, [value, isLoading, sendMessage, onSubmit]);
|
|
19
|
+
return (_jsxs("form", { className: `chatbot-form ${className}`, onSubmit: handleSubmit, children: [_jsx("input", { type: "text", className: "chatbot-input", placeholder: placeholder, value: value, onChange: (e) => setValue(e.target.value), disabled: disabled || isLoading, autoComplete: "off" }), _jsx("button", { type: "submit", className: "chatbot-send", disabled: disabled || isLoading || !value.trim(), children: _jsx("svg", { viewBox: "0 0 24 24", width: "20", height: "20", fill: "currentColor", children: _jsx("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" }) }) })] }));
|
|
20
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CodeChatPanel - Self-contained code chat UI component
|
|
3
|
+
*
|
|
4
|
+
* Handles all the complexity internally:
|
|
5
|
+
* - Streaming responses with thinking/text differentiation
|
|
6
|
+
* - Code edit display with accept/reject
|
|
7
|
+
* - Loading states, errors
|
|
8
|
+
*
|
|
9
|
+
* Consuming app just drops this in and it works.
|
|
10
|
+
*/
|
|
11
|
+
export interface CodeChatPanelProps {
|
|
12
|
+
/** Optional placeholder text for input */
|
|
13
|
+
placeholder?: string;
|
|
14
|
+
/** Optional class name for the container */
|
|
15
|
+
className?: string;
|
|
16
|
+
/** Called when edits are saved */
|
|
17
|
+
onSave?: () => void;
|
|
18
|
+
/** Called when edits are abandoned */
|
|
19
|
+
onAbandon?: () => void;
|
|
20
|
+
/** Called on errors */
|
|
21
|
+
onError?: (error: string) => void;
|
|
22
|
+
}
|
|
23
|
+
export declare function CodeChatPanel({ placeholder, className, onSave, onAbandon, onError, }: CodeChatPanelProps): JSX.Element;
|
|
24
|
+
//# sourceMappingURL=CodeChatPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeChatPanel.d.ts","sourceRoot":"","sources":["../../src/builder/CodeChatPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,MAAM,WAAW,kBAAkB;IACjC,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,uBAAuB;IACvB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAwMD,wBAAgB,aAAa,CAAC,EAC5B,WAAsD,EACtD,SAAc,EACd,MAAM,EACN,SAAS,EACT,OAAO,GACR,EAAE,kBAAkB,GAAG,GAAG,CAAC,OAAO,CA6LlC"}
|