reactbridge-sdk 0.1.15 → 0.1.16
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/dist/components/ReactBridgeChatbox.d.ts.map +1 -1
- package/dist/components/ReactBridgeSearch.d.ts.map +1 -1
- package/dist/hooks/useReactBridge.d.ts.map +1 -1
- package/dist/index.esm.js +512 -30
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +512 -30
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +8 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/api.d.ts +3 -0
- package/dist/utils/api.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -62,10 +62,46 @@ class ReactBridgeAPI {
|
|
|
62
62
|
timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
|
+
// Check if this is a multimodal request (has image or document)
|
|
66
|
+
const hasFile = request.image || request.document;
|
|
67
|
+
let headers = Object.assign({ 'X-API-Key': this.config.apiKey }, this.config.headers);
|
|
68
|
+
let body;
|
|
69
|
+
if (hasFile) {
|
|
70
|
+
// Use FormData for file uploads
|
|
71
|
+
const formData = new FormData();
|
|
72
|
+
// Add text fields
|
|
73
|
+
formData.append('userId', request.userId);
|
|
74
|
+
formData.append('query', request.query);
|
|
75
|
+
if (request.userName)
|
|
76
|
+
formData.append('userName', request.userName);
|
|
77
|
+
if (request.userPreferences)
|
|
78
|
+
formData.append('userPreferences', request.userPreferences);
|
|
79
|
+
if (request.userRecentActivity)
|
|
80
|
+
formData.append('userRecentActivity', request.userRecentActivity);
|
|
81
|
+
if (request.interfaceState)
|
|
82
|
+
formData.append('interfaceState', JSON.stringify(request.interfaceState));
|
|
83
|
+
if (request.sessionId)
|
|
84
|
+
formData.append('sessionId', request.sessionId);
|
|
85
|
+
if (request.modalityHint)
|
|
86
|
+
formData.append('modalityHint', request.modalityHint);
|
|
87
|
+
// Add files
|
|
88
|
+
if (request.image)
|
|
89
|
+
formData.append('image', request.image);
|
|
90
|
+
if (request.document)
|
|
91
|
+
formData.append('document', request.document);
|
|
92
|
+
body = formData;
|
|
93
|
+
// Don't set Content-Type for FormData - let browser set it with boundary
|
|
94
|
+
delete headers['Content-Type'];
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// Use JSON for text-only requests
|
|
98
|
+
headers['Content-Type'] = 'application/json';
|
|
99
|
+
body = JSON.stringify(request);
|
|
100
|
+
}
|
|
65
101
|
const response = yield fetch(url, {
|
|
66
102
|
method: 'POST',
|
|
67
|
-
headers
|
|
68
|
-
body
|
|
103
|
+
headers,
|
|
104
|
+
body,
|
|
69
105
|
signal,
|
|
70
106
|
});
|
|
71
107
|
// Clear any manual timeout timer if set
|
|
@@ -93,6 +129,28 @@ class ReactBridgeAPI {
|
|
|
93
129
|
return this.sendMessage(request);
|
|
94
130
|
});
|
|
95
131
|
}
|
|
132
|
+
// Helper methods for different request types
|
|
133
|
+
sendTextRequest(userId, query, context) {
|
|
134
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
135
|
+
const request = Object.assign({ userId,
|
|
136
|
+
query }, context);
|
|
137
|
+
return this.sendMessage(request);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
sendImageRequest(userId_1, imageFile_1) {
|
|
141
|
+
return __awaiter(this, arguments, void 0, function* (userId, imageFile, query = '', context) {
|
|
142
|
+
const request = Object.assign({ userId,
|
|
143
|
+
query, image: imageFile, modalityHint: 'image' }, context);
|
|
144
|
+
return this.sendMessage(request);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
sendDocumentRequest(userId_1, documentFile_1) {
|
|
148
|
+
return __awaiter(this, arguments, void 0, function* (userId, documentFile, query = '', context) {
|
|
149
|
+
const request = Object.assign({ userId,
|
|
150
|
+
query, document: documentFile, modalityHint: 'document' }, context);
|
|
151
|
+
return this.sendMessage(request);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
96
154
|
}
|
|
97
155
|
|
|
98
156
|
const lightTheme = {
|
|
@@ -283,16 +341,27 @@ function useReactBridge({ onIntentDetected, currentContext, onError, onSpeechSta
|
|
|
283
341
|
previousContextRef.current = currentContext;
|
|
284
342
|
}
|
|
285
343
|
}, [currentContext]);
|
|
286
|
-
const sendChatQuery = React.useCallback((
|
|
287
|
-
|
|
344
|
+
const sendChatQuery = React.useCallback((queryOrOptions) => __awaiter(this, void 0, void 0, function* () {
|
|
345
|
+
const isMultimodal = typeof queryOrOptions === 'object';
|
|
346
|
+
const query = isMultimodal ? (queryOrOptions.query || '') : queryOrOptions;
|
|
347
|
+
const image = isMultimodal ? queryOrOptions.image : undefined;
|
|
348
|
+
const document = isMultimodal ? queryOrOptions.document : undefined;
|
|
349
|
+
if (!query.trim() && !image && !document)
|
|
288
350
|
return;
|
|
289
351
|
setIsLoading(true);
|
|
290
352
|
setError(null);
|
|
291
|
-
// Add user message
|
|
353
|
+
// Add user message with file info if present
|
|
354
|
+
let messageContent = query;
|
|
355
|
+
if (image) {
|
|
356
|
+
messageContent = messageContent ? `${messageContent} [Image: ${image.name}]` : `[Image: ${image.name}]`;
|
|
357
|
+
}
|
|
358
|
+
else if (document) {
|
|
359
|
+
messageContent = messageContent ? `${messageContent} [Document: ${document.name}]` : `[Document: ${document.name}]`;
|
|
360
|
+
}
|
|
292
361
|
const userMessage = {
|
|
293
362
|
id: `user-${Date.now()}`,
|
|
294
363
|
role: 'user',
|
|
295
|
-
content:
|
|
364
|
+
content: messageContent,
|
|
296
365
|
timestamp: new Date(),
|
|
297
366
|
};
|
|
298
367
|
setMessages(prev => [...prev, userMessage]);
|
|
@@ -307,6 +376,10 @@ function useReactBridge({ onIntentDetected, currentContext, onError, onSpeechSta
|
|
|
307
376
|
userRecentActivity: currentContext.userRecentActivity,
|
|
308
377
|
interfaceState: currentContext.interfaceState,
|
|
309
378
|
sessionId: sessionId || undefined,
|
|
379
|
+
// Add multimodal fields
|
|
380
|
+
image,
|
|
381
|
+
document,
|
|
382
|
+
modalityHint: image ? 'image' : document ? 'document' : undefined,
|
|
310
383
|
};
|
|
311
384
|
lastRequestRef.current = request;
|
|
312
385
|
const response = yield api.sendMessage(request);
|
|
@@ -448,6 +521,15 @@ const MESSAGE_ICON_SVG = (React.createElement("svg", { xmlns: "http://www.w3.org
|
|
|
448
521
|
// Microphone Icon SVG
|
|
449
522
|
const MIC_ICON_SVG$1 = (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "currentColor" },
|
|
450
523
|
React.createElement("path", { d: "M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z" })));
|
|
524
|
+
// Plus Icon SVG
|
|
525
|
+
const PLUS_ICON_SVG$1 = (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "currentColor" },
|
|
526
|
+
React.createElement("path", { d: "M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" })));
|
|
527
|
+
// Photo Icon SVG
|
|
528
|
+
const PHOTO_ICON_SVG = (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "currentColor" },
|
|
529
|
+
React.createElement("path", { d: "M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z" })));
|
|
530
|
+
// File Icon SVG
|
|
531
|
+
const FILE_ICON_SVG = (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "currentColor" },
|
|
532
|
+
React.createElement("path", { d: "M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z" })));
|
|
451
533
|
// Default styling constants for the widget wrapper
|
|
452
534
|
const defaultToggleButtonClass = "fixed bottom-6 right-6 z-40 w-14 h-14 rounded-full shadow-lg text-white bg-blue-600 hover:bg-blue-700 transition-all flex justify-center items-center cursor-pointer text-2xl";
|
|
453
535
|
function ReactBridgeChatbox({ onIntentDetected, currentContext, placeholder = "Type your message...", height = "500px", width = "100%", theme: themeOverride, renderMessage, onError,
|
|
@@ -473,7 +555,12 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
|
|
|
473
555
|
const [inputValue, setInputValue] = React.useState("");
|
|
474
556
|
// New: Manage widget open/closed state
|
|
475
557
|
const [isOpen, setIsOpen] = React.useState(defaultOpen);
|
|
558
|
+
// Upload functionality state
|
|
559
|
+
const [isUploadMenuOpen, setIsUploadMenuOpen] = React.useState(false);
|
|
560
|
+
const [selectedFile, setSelectedFile] = React.useState(null);
|
|
561
|
+
const [filePreview, setFilePreview] = React.useState(null);
|
|
476
562
|
const messagesEndRef = React.useRef(null);
|
|
563
|
+
const containerRef = React.useRef(null);
|
|
477
564
|
// Fallback styles for header
|
|
478
565
|
const finalHeaderBgColor = headerBgColor || theme.colors.primary;
|
|
479
566
|
const finalTitleTextColor = titleTextColor || "#ffffff"; // Default to white for contrast
|
|
@@ -482,14 +569,83 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
|
|
|
482
569
|
var _a;
|
|
483
570
|
(_a = messagesEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: "smooth" });
|
|
484
571
|
}, [messages]);
|
|
572
|
+
// Close upload menu and widget when clicking outside
|
|
573
|
+
React.useEffect(() => {
|
|
574
|
+
const handleClickOutside = (event) => {
|
|
575
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
576
|
+
setIsUploadMenuOpen(false);
|
|
577
|
+
if (isOpen) {
|
|
578
|
+
setIsOpen(false);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
583
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
584
|
+
}, [isUploadMenuOpen, isOpen]);
|
|
485
585
|
const handleSubmit = (e) => __awaiter(this, void 0, void 0, function* () {
|
|
486
586
|
e.preventDefault();
|
|
487
|
-
if (!inputValue.trim() || isLoading)
|
|
587
|
+
if ((!inputValue.trim() && !selectedFile) || isLoading)
|
|
488
588
|
return;
|
|
589
|
+
const query = inputValue.trim();
|
|
489
590
|
setInputValue("");
|
|
490
|
-
//
|
|
491
|
-
|
|
591
|
+
// Handle multimodal request
|
|
592
|
+
if (selectedFile && filePreview) {
|
|
593
|
+
if (filePreview.type === 'image') {
|
|
594
|
+
yield sendChatQuery({ image: selectedFile, query });
|
|
595
|
+
}
|
|
596
|
+
else if (filePreview.type === 'document') {
|
|
597
|
+
yield sendChatQuery({ document: selectedFile, query });
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
yield sendChatQuery(query);
|
|
602
|
+
}
|
|
603
|
+
// Clear file selection after sending
|
|
604
|
+
setSelectedFile(null);
|
|
605
|
+
setFilePreview(null);
|
|
492
606
|
});
|
|
607
|
+
// File validation and handling
|
|
608
|
+
const validateAndSetFile = (file, type) => {
|
|
609
|
+
const imageTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/webp'];
|
|
610
|
+
const documentTypes = ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'text/plain'];
|
|
611
|
+
const allowedTypes = type === 'image' ? imageTypes : documentTypes;
|
|
612
|
+
if (!allowedTypes.includes(file.type)) {
|
|
613
|
+
if (onError) {
|
|
614
|
+
onError(new Error(`Invalid file type. Please select a valid ${type} file.`));
|
|
615
|
+
}
|
|
616
|
+
return false;
|
|
617
|
+
}
|
|
618
|
+
setSelectedFile(file);
|
|
619
|
+
if (type === 'image') {
|
|
620
|
+
const url = URL.createObjectURL(file);
|
|
621
|
+
setFilePreview({ type: 'image', url, name: file.name });
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
setFilePreview({ type: 'document', name: file.name });
|
|
625
|
+
}
|
|
626
|
+
setIsUploadMenuOpen(false);
|
|
627
|
+
return true;
|
|
628
|
+
};
|
|
629
|
+
const handleFileSelect = (type) => {
|
|
630
|
+
const input = document.createElement('input');
|
|
631
|
+
input.type = 'file';
|
|
632
|
+
input.accept = type === 'image' ? 'image/png,image/jpeg,image/jpg,image/webp' : 'application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,text/plain';
|
|
633
|
+
input.onchange = (e) => {
|
|
634
|
+
var _a;
|
|
635
|
+
const file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
636
|
+
if (file) {
|
|
637
|
+
validateAndSetFile(file, type);
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
input.click();
|
|
641
|
+
};
|
|
642
|
+
const removeFile = () => {
|
|
643
|
+
if (filePreview === null || filePreview === void 0 ? void 0 : filePreview.url) {
|
|
644
|
+
URL.revokeObjectURL(filePreview.url);
|
|
645
|
+
}
|
|
646
|
+
setSelectedFile(null);
|
|
647
|
+
setFilePreview(null);
|
|
648
|
+
};
|
|
493
649
|
const defaultRenderMessage = (message) => {
|
|
494
650
|
const isUser = message.role === "user";
|
|
495
651
|
const isSystem = message.role === "system";
|
|
@@ -516,7 +672,7 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
|
|
|
516
672
|
// --- RENDER LOGIC FOR 'BASIC' MODE (Original Behavior) ---
|
|
517
673
|
if (renderMode === "basic") {
|
|
518
674
|
// Renders the chat component only, using the height/width props directly
|
|
519
|
-
return (React.createElement("div", { style: {
|
|
675
|
+
return (React.createElement("div", { ref: containerRef, style: {
|
|
520
676
|
width,
|
|
521
677
|
height,
|
|
522
678
|
display: "flex",
|
|
@@ -550,6 +706,60 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
|
|
|
550
706
|
color: theme.colors.text,
|
|
551
707
|
outline: "none",
|
|
552
708
|
} }),
|
|
709
|
+
React.createElement("button", { type: "button", onClick: () => setIsUploadMenuOpen(!isUploadMenuOpen), disabled: isLoading, title: "Attach file", style: {
|
|
710
|
+
padding: theme.spacing.sm,
|
|
711
|
+
backgroundColor: theme.colors.secondary,
|
|
712
|
+
color: "#ffffff",
|
|
713
|
+
border: "none",
|
|
714
|
+
borderRadius: theme.borderRadius,
|
|
715
|
+
cursor: isLoading ? "not-allowed" : "pointer",
|
|
716
|
+
opacity: isLoading ? 0.5 : 1,
|
|
717
|
+
display: "flex",
|
|
718
|
+
alignItems: "center",
|
|
719
|
+
justifyContent: "center",
|
|
720
|
+
width: "40px",
|
|
721
|
+
height: "40px",
|
|
722
|
+
} }, PLUS_ICON_SVG$1),
|
|
723
|
+
isUploadMenuOpen && (React.createElement("div", { style: {
|
|
724
|
+
position: 'absolute',
|
|
725
|
+
bottom: '60px',
|
|
726
|
+
right: '10px',
|
|
727
|
+
backgroundColor: theme.colors.background,
|
|
728
|
+
border: `1px solid ${theme.colors.border}`,
|
|
729
|
+
borderRadius: theme.borderRadius,
|
|
730
|
+
boxShadow: theme.boxShadow,
|
|
731
|
+
zIndex: 1000,
|
|
732
|
+
minWidth: '150px',
|
|
733
|
+
} },
|
|
734
|
+
React.createElement("button", { onClick: () => handleFileSelect('image'), style: {
|
|
735
|
+
width: '100%',
|
|
736
|
+
padding: theme.spacing.md,
|
|
737
|
+
border: 'none',
|
|
738
|
+
backgroundColor: 'transparent',
|
|
739
|
+
color: theme.colors.text,
|
|
740
|
+
cursor: 'pointer',
|
|
741
|
+
display: 'flex',
|
|
742
|
+
alignItems: 'center',
|
|
743
|
+
gap: theme.spacing.sm,
|
|
744
|
+
borderRadius: `${theme.borderRadius} ${theme.borderRadius} 0 0`,
|
|
745
|
+
} },
|
|
746
|
+
PHOTO_ICON_SVG,
|
|
747
|
+
"Upload Image"),
|
|
748
|
+
React.createElement("button", { onClick: () => handleFileSelect('document'), style: {
|
|
749
|
+
width: '100%',
|
|
750
|
+
padding: theme.spacing.md,
|
|
751
|
+
border: 'none',
|
|
752
|
+
backgroundColor: 'transparent',
|
|
753
|
+
color: theme.colors.text,
|
|
754
|
+
cursor: 'pointer',
|
|
755
|
+
display: 'flex',
|
|
756
|
+
alignItems: 'center',
|
|
757
|
+
gap: theme.spacing.sm,
|
|
758
|
+
borderRadius: `0 0 ${theme.borderRadius} ${theme.borderRadius}`,
|
|
759
|
+
borderTop: `1px solid ${theme.colors.border}`,
|
|
760
|
+
} },
|
|
761
|
+
FILE_ICON_SVG,
|
|
762
|
+
"Upload Document"))),
|
|
553
763
|
React.createElement("button", { type: "button", onClick: isListening ? stopVoiceInput : startVoiceInput, disabled: isLoading, title: isListening ? "Stop recording" : "Start voice input", style: {
|
|
554
764
|
padding: theme.spacing.sm,
|
|
555
765
|
backgroundColor: isListening ? theme.colors.error : theme.colors.secondary,
|
|
@@ -564,16 +774,41 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
|
|
|
564
774
|
width: "40px",
|
|
565
775
|
height: "40px",
|
|
566
776
|
} }, MIC_ICON_SVG$1),
|
|
567
|
-
React.createElement("button", { type: "submit", disabled: isLoading || !inputValue.trim(), style: {
|
|
777
|
+
React.createElement("button", { type: "submit", disabled: isLoading || (!inputValue.trim() && !selectedFile), style: {
|
|
568
778
|
padding: `${theme.spacing.sm} ${theme.spacing.md}`,
|
|
569
779
|
fontSize: theme.fontSizes.md,
|
|
570
780
|
backgroundColor: theme.colors.primary,
|
|
571
781
|
color: "#ffffff",
|
|
572
782
|
border: "none",
|
|
573
783
|
borderRadius: theme.borderRadius,
|
|
574
|
-
cursor: isLoading || !inputValue.trim() ? "not-allowed" : "pointer",
|
|
575
|
-
opacity: isLoading || !inputValue.trim() ? 0.5 : 1,
|
|
576
|
-
} }, isLoading ? "Sending..." : "Send"))
|
|
784
|
+
cursor: isLoading || (!inputValue.trim() && !selectedFile) ? "not-allowed" : "pointer",
|
|
785
|
+
opacity: isLoading || (!inputValue.trim() && !selectedFile) ? 0.5 : 1,
|
|
786
|
+
} }, isLoading ? "Sending..." : "Send")),
|
|
787
|
+
filePreview && (React.createElement("div", { style: {
|
|
788
|
+
marginTop: theme.spacing.sm,
|
|
789
|
+
padding: theme.spacing.sm,
|
|
790
|
+
backgroundColor: theme.colors.surface,
|
|
791
|
+
border: `1px solid ${theme.colors.border}`,
|
|
792
|
+
borderRadius: theme.borderRadius,
|
|
793
|
+
display: 'flex',
|
|
794
|
+
alignItems: 'center',
|
|
795
|
+
gap: theme.spacing.sm,
|
|
796
|
+
} },
|
|
797
|
+
filePreview.type === 'image' && filePreview.url ? (React.createElement("img", { src: filePreview.url, alt: "Preview", style: {
|
|
798
|
+
width: '40px',
|
|
799
|
+
height: '40px',
|
|
800
|
+
objectFit: 'cover',
|
|
801
|
+
borderRadius: theme.borderRadius,
|
|
802
|
+
} })) : (React.createElement("div", { style: { width: '40px', height: '40px', backgroundColor: theme.colors.secondary, borderRadius: theme.borderRadius, display: 'flex', alignItems: 'center', justifyContent: 'center' } }, FILE_ICON_SVG)),
|
|
803
|
+
React.createElement("div", { style: { flex: 1, fontSize: theme.fontSizes.sm, color: theme.colors.text } }, filePreview.name),
|
|
804
|
+
React.createElement("button", { type: "button", onClick: removeFile, style: {
|
|
805
|
+
padding: '4px',
|
|
806
|
+
backgroundColor: 'transparent',
|
|
807
|
+
border: 'none',
|
|
808
|
+
color: theme.colors.error,
|
|
809
|
+
cursor: 'pointer',
|
|
810
|
+
fontSize: '18px',
|
|
811
|
+
}, title: "Remove file" }, "\u00D7"))))));
|
|
577
812
|
}
|
|
578
813
|
// --- RENDER LOGIC FOR 'STANDARD' MODE (Widget Behavior) ---
|
|
579
814
|
// Determine fixed positioning class for the widget
|
|
@@ -593,7 +828,7 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
|
|
|
593
828
|
})) }, toggleIcon));
|
|
594
829
|
}
|
|
595
830
|
// Render the full widget when open
|
|
596
|
-
return (React.createElement("div", { style: Object.assign({ width: width, height: height, display: "flex", flexDirection: "column", boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)", borderRadius: theme.borderRadius, overflow: "hidden", fontFamily: "system-ui, -apple-system, sans-serif", position: "fixed", zIndex: 50 }, widgetPositionClass) },
|
|
831
|
+
return (React.createElement("div", { ref: containerRef, style: Object.assign({ width: width, height: height, display: "flex", flexDirection: "column", boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)", borderRadius: theme.borderRadius, overflow: "hidden", fontFamily: "system-ui, -apple-system, sans-serif", position: "fixed", zIndex: 50 }, widgetPositionClass) },
|
|
597
832
|
React.createElement("div", { style: {
|
|
598
833
|
padding: "10px 15px",
|
|
599
834
|
backgroundColor: finalHeaderBgColor,
|
|
@@ -643,9 +878,62 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
|
|
|
643
878
|
color: theme.colors.text,
|
|
644
879
|
outline: "none",
|
|
645
880
|
} }),
|
|
881
|
+
React.createElement("button", { type: "button", onClick: () => setIsUploadMenuOpen(!isUploadMenuOpen), disabled: isLoading, title: "Attach file", style: {
|
|
882
|
+
padding: theme.spacing.sm,
|
|
883
|
+
backgroundColor: theme.colors.secondary,
|
|
884
|
+
color: "#ffffff",
|
|
885
|
+
border: "none",
|
|
886
|
+
borderRadius: theme.borderRadius,
|
|
887
|
+
cursor: isLoading ? "not-allowed" : "pointer",
|
|
888
|
+
opacity: isLoading ? 0.5 : 1,
|
|
889
|
+
display: "flex",
|
|
890
|
+
alignItems: "center",
|
|
891
|
+
justifyContent: "center",
|
|
892
|
+
width: "40px",
|
|
893
|
+
height: "40px",
|
|
894
|
+
} }, PLUS_ICON_SVG$1),
|
|
895
|
+
isUploadMenuOpen && (React.createElement("div", { style: {
|
|
896
|
+
position: 'absolute',
|
|
897
|
+
bottom: '60px',
|
|
898
|
+
right: '10px',
|
|
899
|
+
backgroundColor: theme.colors.background,
|
|
900
|
+
border: `1px solid ${theme.colors.border}`,
|
|
901
|
+
borderRadius: theme.borderRadius,
|
|
902
|
+
boxShadow: theme.boxShadow,
|
|
903
|
+
zIndex: 1000,
|
|
904
|
+
minWidth: '150px',
|
|
905
|
+
} },
|
|
906
|
+
React.createElement("button", { onClick: () => handleFileSelect('image'), style: {
|
|
907
|
+
width: '100%',
|
|
908
|
+
padding: theme.spacing.md,
|
|
909
|
+
border: 'none',
|
|
910
|
+
backgroundColor: 'transparent',
|
|
911
|
+
color: theme.colors.text,
|
|
912
|
+
cursor: 'pointer',
|
|
913
|
+
display: 'flex',
|
|
914
|
+
alignItems: 'center',
|
|
915
|
+
gap: theme.spacing.sm,
|
|
916
|
+
borderRadius: `${theme.borderRadius} ${theme.borderRadius} 0 0`,
|
|
917
|
+
} },
|
|
918
|
+
PHOTO_ICON_SVG,
|
|
919
|
+
"Upload Image"),
|
|
920
|
+
React.createElement("button", { onClick: () => handleFileSelect('document'), style: {
|
|
921
|
+
width: '100%',
|
|
922
|
+
padding: theme.spacing.md,
|
|
923
|
+
border: 'none',
|
|
924
|
+
backgroundColor: 'transparent',
|
|
925
|
+
color: theme.colors.text,
|
|
926
|
+
cursor: 'pointer',
|
|
927
|
+
display: 'flex',
|
|
928
|
+
alignItems: 'center',
|
|
929
|
+
gap: theme.spacing.sm,
|
|
930
|
+
borderRadius: `0 0 ${theme.borderRadius} ${theme.borderRadius}`,
|
|
931
|
+
borderTop: `1px solid ${theme.colors.border}`,
|
|
932
|
+
} },
|
|
933
|
+
FILE_ICON_SVG,
|
|
934
|
+
"Upload Document"))),
|
|
646
935
|
React.createElement("button", { type: "button", onClick: isListening ? stopVoiceInput : startVoiceInput, disabled: isLoading, title: isListening ? "Stop recording" : "Start voice input", style: {
|
|
647
936
|
padding: theme.spacing.sm,
|
|
648
|
-
// backgroundColor: isListening ? theme.colors.error : theme.colors.primary,
|
|
649
937
|
color: isListening ? theme.colors.primary : theme.colors.border,
|
|
650
938
|
border: "none",
|
|
651
939
|
borderRadius: theme.borderRadius,
|
|
@@ -657,21 +945,49 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
|
|
|
657
945
|
width: "40px",
|
|
658
946
|
height: "40px",
|
|
659
947
|
} }, MIC_ICON_SVG$1),
|
|
660
|
-
React.createElement("button", { type: "submit", disabled: isLoading || !inputValue.trim(), style: {
|
|
948
|
+
React.createElement("button", { type: "submit", disabled: isLoading || (!inputValue.trim() && !selectedFile), style: {
|
|
661
949
|
padding: `${theme.spacing.sm} ${theme.spacing.md}`,
|
|
662
950
|
fontSize: theme.fontSizes.md,
|
|
663
951
|
backgroundColor: theme.colors.primary,
|
|
664
952
|
color: theme.colors.background,
|
|
665
953
|
border: "none",
|
|
666
954
|
borderRadius: theme.borderRadius,
|
|
667
|
-
cursor: isLoading || !inputValue.trim() ? "not-allowed" : "pointer",
|
|
668
|
-
opacity: isLoading || !inputValue.trim() ? 0.5 : 1,
|
|
669
|
-
} }, isLoading ? "Sending..." : "Send"))
|
|
955
|
+
cursor: isLoading || (!inputValue.trim() && !selectedFile) ? "not-allowed" : "pointer",
|
|
956
|
+
opacity: isLoading || (!inputValue.trim() && !selectedFile) ? 0.5 : 1,
|
|
957
|
+
} }, isLoading ? "Sending..." : "Send")),
|
|
958
|
+
filePreview && (React.createElement("div", { style: {
|
|
959
|
+
marginTop: theme.spacing.sm,
|
|
960
|
+
padding: theme.spacing.sm,
|
|
961
|
+
backgroundColor: theme.colors.surface,
|
|
962
|
+
border: `1px solid ${theme.colors.border}`,
|
|
963
|
+
borderRadius: theme.borderRadius,
|
|
964
|
+
display: 'flex',
|
|
965
|
+
alignItems: 'center',
|
|
966
|
+
gap: theme.spacing.sm,
|
|
967
|
+
} },
|
|
968
|
+
filePreview.type === 'image' && filePreview.url ? (React.createElement("img", { src: filePreview.url, alt: "Preview", style: {
|
|
969
|
+
width: '40px',
|
|
970
|
+
height: '40px',
|
|
971
|
+
objectFit: 'cover',
|
|
972
|
+
borderRadius: theme.borderRadius,
|
|
973
|
+
} })) : (React.createElement("div", { style: { width: '40px', height: '40px', backgroundColor: theme.colors.secondary, borderRadius: theme.borderRadius, display: 'flex', alignItems: 'center', justifyContent: 'center' } }, FILE_ICON_SVG)),
|
|
974
|
+
React.createElement("div", { style: { flex: 1, fontSize: theme.fontSizes.sm, color: theme.colors.text } }, filePreview.name),
|
|
975
|
+
React.createElement("button", { type: "button", onClick: removeFile, style: {
|
|
976
|
+
padding: '4px',
|
|
977
|
+
backgroundColor: 'transparent',
|
|
978
|
+
border: 'none',
|
|
979
|
+
color: theme.colors.error,
|
|
980
|
+
cursor: 'pointer',
|
|
981
|
+
fontSize: '18px',
|
|
982
|
+
}, title: "Remove file" }, "\u00D7"))))));
|
|
670
983
|
}
|
|
671
984
|
|
|
672
985
|
// Microphone Icon SVG
|
|
673
986
|
const MIC_ICON_SVG = (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "currentColor" },
|
|
674
987
|
React.createElement("path", { d: "M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z" })));
|
|
988
|
+
// Plus Icon SVG
|
|
989
|
+
const PLUS_ICON_SVG = (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "currentColor" },
|
|
990
|
+
React.createElement("path", { d: "M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" })));
|
|
675
991
|
function ReactBridgeSearch({ onIntentDetected, currentContext, placeholder = 'Search...', width = '100%', maxResults = 5, theme: themeOverride, onError, onSpeechStart, onSpeechEnd, onTranscript, onAgentResponse, }) {
|
|
676
992
|
const { theme: contextTheme } = useReactBridgeContext();
|
|
677
993
|
const theme = Object.assign(Object.assign({}, contextTheme), themeOverride);
|
|
@@ -686,12 +1002,17 @@ function ReactBridgeSearch({ onIntentDetected, currentContext, placeholder = 'Se
|
|
|
686
1002
|
});
|
|
687
1003
|
const [inputValue, setInputValue] = React.useState('');
|
|
688
1004
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
1005
|
+
const [isUploadMenuOpen, setIsUploadMenuOpen] = React.useState(false);
|
|
1006
|
+
const [selectedFile, setSelectedFile] = React.useState(null);
|
|
1007
|
+
const [filePreview, setFilePreview] = React.useState(null);
|
|
689
1008
|
const containerRef = React.useRef(null);
|
|
690
|
-
|
|
1009
|
+
const fileInputRef = React.useRef(null);
|
|
1010
|
+
// Close dropdown and upload menu when clicking outside
|
|
691
1011
|
React.useEffect(() => {
|
|
692
1012
|
const handleClickOutside = (event) => {
|
|
693
1013
|
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
694
1014
|
setIsOpen(false);
|
|
1015
|
+
setIsUploadMenuOpen(false);
|
|
695
1016
|
}
|
|
696
1017
|
};
|
|
697
1018
|
document.addEventListener('mousedown', handleClickOutside);
|
|
@@ -703,12 +1024,78 @@ function ReactBridgeSearch({ onIntentDetected, currentContext, placeholder = 'Se
|
|
|
703
1024
|
setIsOpen(true);
|
|
704
1025
|
}
|
|
705
1026
|
}, [messages]);
|
|
1027
|
+
const handleFileSelect = (type) => {
|
|
1028
|
+
if (fileInputRef.current) {
|
|
1029
|
+
fileInputRef.current.accept = type === 'image'
|
|
1030
|
+
? 'image/png,image/jpeg,image/jpg,image/webp'
|
|
1031
|
+
: 'application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,text/plain';
|
|
1032
|
+
fileInputRef.current.click();
|
|
1033
|
+
}
|
|
1034
|
+
setIsUploadMenuOpen(false);
|
|
1035
|
+
};
|
|
1036
|
+
const handleFileChange = (event) => {
|
|
1037
|
+
var _a;
|
|
1038
|
+
const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
1039
|
+
if (!file)
|
|
1040
|
+
return;
|
|
1041
|
+
// Validate file type
|
|
1042
|
+
const imageTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/webp'];
|
|
1043
|
+
const documentTypes = ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'text/plain'];
|
|
1044
|
+
const allowedTypes = file.type.startsWith('image/') ? imageTypes : documentTypes;
|
|
1045
|
+
if (!allowedTypes.includes(file.type)) {
|
|
1046
|
+
if (onError) {
|
|
1047
|
+
onError(new Error(`Invalid file type. Please select a valid ${file.type.startsWith('image/') ? 'image' : 'document'} file.`));
|
|
1048
|
+
}
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
// Validate file size (10MB limit)
|
|
1052
|
+
const maxSize = 10 * 1024 * 1024; // 10MB
|
|
1053
|
+
if (file.size > maxSize) {
|
|
1054
|
+
if (onError) {
|
|
1055
|
+
onError(new Error('File size too large. Please select a file smaller than 10MB.'));
|
|
1056
|
+
}
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
setSelectedFile(file);
|
|
1060
|
+
// Create preview for images
|
|
1061
|
+
if (file.type.startsWith('image/')) {
|
|
1062
|
+
const reader = new FileReader();
|
|
1063
|
+
reader.onload = (e) => {
|
|
1064
|
+
var _a;
|
|
1065
|
+
setFilePreview((_a = e.target) === null || _a === void 0 ? void 0 : _a.result);
|
|
1066
|
+
};
|
|
1067
|
+
reader.readAsDataURL(file);
|
|
1068
|
+
}
|
|
1069
|
+
else {
|
|
1070
|
+
// For documents, show file name
|
|
1071
|
+
setFilePreview(file.name);
|
|
1072
|
+
}
|
|
1073
|
+
};
|
|
1074
|
+
const removeFile = () => {
|
|
1075
|
+
setSelectedFile(null);
|
|
1076
|
+
setFilePreview(null);
|
|
1077
|
+
if (fileInputRef.current) {
|
|
1078
|
+
fileInputRef.current.value = '';
|
|
1079
|
+
}
|
|
1080
|
+
};
|
|
706
1081
|
const handleSubmit = (e) => __awaiter(this, void 0, void 0, function* () {
|
|
707
1082
|
e.preventDefault();
|
|
708
|
-
if (!inputValue.trim() || isLoading)
|
|
1083
|
+
if ((!inputValue.trim() && !selectedFile) || isLoading)
|
|
709
1084
|
return;
|
|
710
|
-
|
|
1085
|
+
const query = inputValue.trim();
|
|
711
1086
|
setInputValue('');
|
|
1087
|
+
// Handle multimodal request
|
|
1088
|
+
if (selectedFile && filePreview) {
|
|
1089
|
+
yield sendChatQuery({
|
|
1090
|
+
query,
|
|
1091
|
+
image: selectedFile.type.startsWith('image/') ? selectedFile : undefined,
|
|
1092
|
+
document: selectedFile.type.startsWith('image/') ? undefined : selectedFile,
|
|
1093
|
+
});
|
|
1094
|
+
removeFile();
|
|
1095
|
+
}
|
|
1096
|
+
else {
|
|
1097
|
+
yield sendChatQuery(query);
|
|
1098
|
+
}
|
|
712
1099
|
});
|
|
713
1100
|
// Get only assistant messages (not system messages)
|
|
714
1101
|
const displayMessages = messages
|
|
@@ -721,10 +1108,11 @@ function ReactBridgeSearch({ onIntentDetected, currentContext, placeholder = 'Se
|
|
|
721
1108
|
} },
|
|
722
1109
|
React.createElement("form", { onSubmit: handleSubmit },
|
|
723
1110
|
React.createElement("div", { style: { position: 'relative' } },
|
|
724
|
-
React.createElement("input", {
|
|
1111
|
+
React.createElement("input", { ref: fileInputRef, type: "file", onChange: handleFileChange, style: { display: 'none' } }),
|
|
1112
|
+
React.createElement("input", { type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), onFocus: () => displayMessages.length > 0 && setIsOpen(true), placeholder: selectedFile ? `Search with ${selectedFile.name}...` : placeholder, disabled: isLoading, style: {
|
|
725
1113
|
width: '100%',
|
|
726
1114
|
padding: theme.spacing.md,
|
|
727
|
-
paddingRight: '
|
|
1115
|
+
paddingRight: '180px', // Increased to make room for plus, mic, and search buttons
|
|
728
1116
|
fontSize: theme.fontSizes.md,
|
|
729
1117
|
border: `1px solid ${theme.colors.border}`,
|
|
730
1118
|
borderRadius: theme.borderRadius,
|
|
@@ -733,6 +1121,56 @@ function ReactBridgeSearch({ onIntentDetected, currentContext, placeholder = 'Se
|
|
|
733
1121
|
outline: 'none',
|
|
734
1122
|
boxSizing: 'border-box',
|
|
735
1123
|
} }),
|
|
1124
|
+
React.createElement("button", { type: "button", onClick: () => setIsUploadMenuOpen(!isUploadMenuOpen), disabled: isLoading, title: "Upload file", style: {
|
|
1125
|
+
position: 'absolute',
|
|
1126
|
+
right: '105px', // Position before the mic button
|
|
1127
|
+
top: '50%',
|
|
1128
|
+
transform: 'translateY(-50%)',
|
|
1129
|
+
padding: theme.spacing.sm,
|
|
1130
|
+
marginRight: theme.spacing.xs,
|
|
1131
|
+
color: theme.colors.border,
|
|
1132
|
+
border: "none",
|
|
1133
|
+
borderRadius: theme.borderRadius,
|
|
1134
|
+
cursor: isLoading ? "not-allowed" : "pointer",
|
|
1135
|
+
opacity: isLoading ? 0.5 : 1,
|
|
1136
|
+
display: "flex",
|
|
1137
|
+
alignItems: "center",
|
|
1138
|
+
justifyContent: "center",
|
|
1139
|
+
width: "32px",
|
|
1140
|
+
height: "32px",
|
|
1141
|
+
} }, PLUS_ICON_SVG),
|
|
1142
|
+
isUploadMenuOpen && (React.createElement("div", { style: {
|
|
1143
|
+
position: 'absolute',
|
|
1144
|
+
right: '105px',
|
|
1145
|
+
top: '100%',
|
|
1146
|
+
marginTop: theme.spacing.xs,
|
|
1147
|
+
backgroundColor: theme.colors.background,
|
|
1148
|
+
border: `1px solid ${theme.colors.border}`,
|
|
1149
|
+
borderRadius: theme.borderRadius,
|
|
1150
|
+
boxShadow: theme.boxShadow,
|
|
1151
|
+
zIndex: 1000,
|
|
1152
|
+
minWidth: '120px',
|
|
1153
|
+
} },
|
|
1154
|
+
React.createElement("button", { type: "button", onClick: () => handleFileSelect('image'), style: {
|
|
1155
|
+
width: '100%',
|
|
1156
|
+
padding: theme.spacing.sm,
|
|
1157
|
+
backgroundColor: 'transparent',
|
|
1158
|
+
border: 'none',
|
|
1159
|
+
color: theme.colors.text,
|
|
1160
|
+
cursor: 'pointer',
|
|
1161
|
+
textAlign: 'left',
|
|
1162
|
+
fontSize: theme.fontSizes.sm,
|
|
1163
|
+
} }, "\uD83D\uDCF7 Image"),
|
|
1164
|
+
React.createElement("button", { type: "button", onClick: () => handleFileSelect('document'), style: {
|
|
1165
|
+
width: '100%',
|
|
1166
|
+
padding: theme.spacing.sm,
|
|
1167
|
+
backgroundColor: 'transparent',
|
|
1168
|
+
border: 'none',
|
|
1169
|
+
color: theme.colors.text,
|
|
1170
|
+
cursor: 'pointer',
|
|
1171
|
+
textAlign: 'left',
|
|
1172
|
+
fontSize: theme.fontSizes.sm,
|
|
1173
|
+
} }, "\uD83D\uDCC4 Document"))),
|
|
736
1174
|
React.createElement("button", { type: "button", onClick: isListening ? stopVoiceInput : startVoiceInput, disabled: isLoading, title: isListening ? "Stop recording" : "Start voice input", style: {
|
|
737
1175
|
position: 'absolute',
|
|
738
1176
|
right: '70px', // Position before the search button
|
|
@@ -740,7 +1178,6 @@ function ReactBridgeSearch({ onIntentDetected, currentContext, placeholder = 'Se
|
|
|
740
1178
|
transform: 'translateY(-50%)',
|
|
741
1179
|
padding: theme.spacing.sm,
|
|
742
1180
|
marginRight: theme.spacing.xs,
|
|
743
|
-
// backgroundColor: isListening ? theme.colors.error : theme.colors.primary,
|
|
744
1181
|
color: isListening ? theme.colors.primary : theme.colors.border,
|
|
745
1182
|
border: "none",
|
|
746
1183
|
borderRadius: theme.borderRadius,
|
|
@@ -752,7 +1189,7 @@ function ReactBridgeSearch({ onIntentDetected, currentContext, placeholder = 'Se
|
|
|
752
1189
|
width: "32px",
|
|
753
1190
|
height: "32px",
|
|
754
1191
|
} }, MIC_ICON_SVG),
|
|
755
|
-
React.createElement("button", { type: "submit", disabled: isLoading || !inputValue.trim(), style: {
|
|
1192
|
+
React.createElement("button", { type: "submit", disabled: isLoading || (!inputValue.trim() && !selectedFile), style: {
|
|
756
1193
|
position: 'absolute',
|
|
757
1194
|
right: theme.spacing.sm,
|
|
758
1195
|
top: '50%',
|
|
@@ -763,9 +1200,54 @@ function ReactBridgeSearch({ onIntentDetected, currentContext, placeholder = 'Se
|
|
|
763
1200
|
color: theme.colors.background,
|
|
764
1201
|
border: 'none',
|
|
765
1202
|
borderRadius: theme.borderRadius,
|
|
766
|
-
cursor: isLoading || !inputValue.trim() ? 'not-allowed' : 'pointer',
|
|
767
|
-
opacity: isLoading || !inputValue.trim() ? 0.5 : 1,
|
|
768
|
-
} }, isLoading ? 'Searching...' : 'Search'))
|
|
1203
|
+
cursor: isLoading || (!inputValue.trim() && !selectedFile) ? 'not-allowed' : 'pointer',
|
|
1204
|
+
opacity: isLoading || (!inputValue.trim() && !selectedFile) ? 0.5 : 1,
|
|
1205
|
+
} }, isLoading ? 'Searching...' : 'Search')),
|
|
1206
|
+
selectedFile && filePreview && (React.createElement("div", { style: {
|
|
1207
|
+
marginTop: theme.spacing.sm,
|
|
1208
|
+
padding: theme.spacing.sm,
|
|
1209
|
+
backgroundColor: theme.colors.surface,
|
|
1210
|
+
border: `1px solid ${theme.colors.border}`,
|
|
1211
|
+
borderRadius: theme.borderRadius,
|
|
1212
|
+
display: 'flex',
|
|
1213
|
+
alignItems: 'center',
|
|
1214
|
+
gap: theme.spacing.sm,
|
|
1215
|
+
} },
|
|
1216
|
+
selectedFile.type.startsWith('image/') ? (React.createElement("img", { src: filePreview, alt: "Preview", style: {
|
|
1217
|
+
width: '40px',
|
|
1218
|
+
height: '40px',
|
|
1219
|
+
objectFit: 'cover',
|
|
1220
|
+
borderRadius: theme.borderRadius,
|
|
1221
|
+
} })) : (React.createElement("div", { style: {
|
|
1222
|
+
width: '40px',
|
|
1223
|
+
height: '40px',
|
|
1224
|
+
backgroundColor: theme.colors.primary,
|
|
1225
|
+
borderRadius: theme.borderRadius,
|
|
1226
|
+
display: 'flex',
|
|
1227
|
+
alignItems: 'center',
|
|
1228
|
+
justifyContent: 'center',
|
|
1229
|
+
color: theme.colors.background,
|
|
1230
|
+
fontSize: theme.fontSizes.lg,
|
|
1231
|
+
} }, "\uD83D\uDCC4")),
|
|
1232
|
+
React.createElement("div", { style: { flex: 1, fontSize: theme.fontSizes.sm, color: theme.colors.text } },
|
|
1233
|
+
React.createElement("div", { style: { fontWeight: 'bold' } }, selectedFile.name),
|
|
1234
|
+
React.createElement("div", { style: { color: theme.colors.textSecondary } },
|
|
1235
|
+
(selectedFile.size / 1024 / 1024).toFixed(2),
|
|
1236
|
+
" MB")),
|
|
1237
|
+
React.createElement("button", { type: "button", onClick: removeFile, style: {
|
|
1238
|
+
padding: theme.spacing.xs,
|
|
1239
|
+
backgroundColor: 'transparent',
|
|
1240
|
+
border: 'none',
|
|
1241
|
+
color: theme.colors.textSecondary,
|
|
1242
|
+
cursor: 'pointer',
|
|
1243
|
+
borderRadius: theme.borderRadius,
|
|
1244
|
+
width: '24px',
|
|
1245
|
+
height: '24px',
|
|
1246
|
+
display: 'flex',
|
|
1247
|
+
alignItems: 'center',
|
|
1248
|
+
justifyContent: 'center',
|
|
1249
|
+
fontSize: '18px',
|
|
1250
|
+
}, title: "Remove file" }, "\u00D7")))),
|
|
769
1251
|
isOpen && displayMessages.length > 0 && (React.createElement("div", { style: {
|
|
770
1252
|
position: 'absolute',
|
|
771
1253
|
top: '100%',
|