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