open-chat-studio-widget 0.6.0 → 0.7.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.
Files changed (45) hide show
  1. package/README.md +27 -25
  2. package/dist/cjs/{index-CcvroTR_.js → index-CvB341El.js} +3 -3
  3. package/dist/cjs/{index-CcvroTR_.js.map → index-CvB341El.js.map} +1 -1
  4. package/dist/cjs/loader.cjs.js +2 -2
  5. package/dist/cjs/open-chat-studio-widget.cjs.entry.js +364 -142
  6. package/dist/cjs/open-chat-studio-widget.cjs.entry.js.map +1 -1
  7. package/dist/cjs/open-chat-studio-widget.cjs.js +2 -2
  8. package/dist/cjs/open-chat-studio-widget.entry.cjs.js.map +1 -1
  9. package/dist/collection/components/ocs-chat/icons.js +2 -2
  10. package/dist/collection/components/ocs-chat/icons.js.map +1 -1
  11. package/dist/collection/components/ocs-chat/ocs-chat.css +29 -34
  12. package/dist/collection/components/ocs-chat/ocs-chat.js +281 -78
  13. package/dist/collection/components/ocs-chat/ocs-chat.js.map +1 -1
  14. package/dist/collection/services/chat-session-service.js +4 -0
  15. package/dist/collection/services/chat-session-service.js.map +1 -1
  16. package/dist/collection/services/file-attachment-manager.js +4 -7
  17. package/dist/collection/services/file-attachment-manager.js.map +1 -1
  18. package/dist/collection/utils/cookies.js.map +1 -1
  19. package/dist/collection/utils/markdown.js +43 -17
  20. package/dist/collection/utils/markdown.js.map +1 -1
  21. package/dist/collection/utils/translations.js +1 -3
  22. package/dist/collection/utils/translations.js.map +1 -1
  23. package/dist/collection/utils/utils.js +2 -2
  24. package/dist/collection/utils/utils.js.map +1 -1
  25. package/dist/components/open-chat-studio-widget.js +369 -141
  26. package/dist/components/open-chat-studio-widget.js.map +1 -1
  27. package/dist/esm/{index-BKVXO_5E.js → index-C2QZK0Ui.js} +3 -3
  28. package/dist/esm/{index-BKVXO_5E.js.map → index-C2QZK0Ui.js.map} +1 -1
  29. package/dist/esm/loader.js +3 -3
  30. package/dist/esm/open-chat-studio-widget.entry.js +364 -142
  31. package/dist/esm/open-chat-studio-widget.entry.js.map +1 -1
  32. package/dist/esm/open-chat-studio-widget.js +3 -3
  33. package/dist/open-chat-studio-widget/open-chat-studio-widget.entry.esm.js.map +1 -1
  34. package/dist/open-chat-studio-widget/open-chat-studio-widget.esm.js +1 -1
  35. package/dist/open-chat-studio-widget/{p-BKVXO_5E.js → p-C2QZK0Ui.js} +2 -2
  36. package/dist/open-chat-studio-widget/{p-BKVXO_5E.js.map → p-C2QZK0Ui.js.map} +1 -1
  37. package/dist/open-chat-studio-widget/p-e87d4e31.entry.js +4 -0
  38. package/dist/open-chat-studio-widget/p-e87d4e31.entry.js.map +1 -0
  39. package/dist/types/components/ocs-chat/ocs-chat.d.ts +29 -1
  40. package/dist/types/components.d.ts +23 -2
  41. package/dist/types/services/chat-session-service.d.ts +1 -0
  42. package/dist/types/utils/markdown.d.ts +8 -0
  43. package/package.json +7 -2
  44. package/dist/open-chat-studio-widget/p-a0d04423.entry.js +0 -4
  45. package/dist/open-chat-studio-widget/p-a0d04423.entry.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2
2
  import { Host, h, Env } from "@stencil/core";
3
- import { XMarkIcon, GripDotsVerticalIcon, PlusWithCircleIcon, ArrowsPointingOutIcon, ArrowsPointingInIcon, PaperClipIcon, CheckDocumentIcon, XIcon, OcsWidgetAvatar } from "./icons";
3
+ import { XMarkIcon, GripDotsVerticalIcon, PlusWithCircleIcon, ArrowsPointingOutIcon, ArrowsPointingInIcon, PaperClipIcon, CheckDocumentIcon, XIcon, OcsWidgetAvatar, } from "./icons";
4
4
  import { renderMarkdownSync as renderMarkdownComplete } from "../../utils/markdown";
5
5
  import { varToPixels } from "../../utils/utils";
6
6
  import { TranslationManager, defaultTranslations } from "../../utils/translations";
@@ -11,11 +11,23 @@ export class OcsChat {
11
11
  /**
12
12
  * The base URL for the API.
13
13
  */
14
- this.apiBaseUrl = "https://www.openchatstudio.com";
14
+ this.apiBaseUrl = 'https://www.openchatstudio.com';
15
15
  /**
16
16
  * The shape of the chat button. 'round' makes it circular, 'square' keeps it rectangular.
17
17
  */
18
18
  this.buttonShape = 'square';
19
+ /**
20
+ * Whether to show the launcher button. Set to false to hide the button
21
+ * and open the chat window programmatically via the `visible` property.
22
+ */
23
+ this.showButton = true;
24
+ /**
25
+ * The operating mode of the widget.
26
+ * - 'standard': Default floating window with launcher button.
27
+ * - 'kiosk': Fills parent container, always visible, no header or launcher button.
28
+ * The parent element must establish a containing block (e.g. `position: relative`).
29
+ */
30
+ this.mode = 'standard';
19
31
  /**
20
32
  * Whether the chat widget is visible on load.
21
33
  */
@@ -41,12 +53,13 @@ export class OcsChat {
41
53
  * Allow the user to attach files to their messages.
42
54
  */
43
55
  this.allowAttachments = false;
44
- this.error = "";
56
+ this.error = '';
45
57
  this.messages = [];
46
58
  this.isLoading = false;
47
59
  this.isTyping = false;
48
- this.messageInput = "";
49
- this.currentPollTaskId = "";
60
+ this.typingProgressMessage = '';
61
+ this.messageInput = '';
62
+ this.currentPollTaskId = '';
50
63
  this.isDragging = false;
51
64
  this.dragOffset = { x: 0, y: 0 };
52
65
  this.windowPosition = { x: 0, y: 0 };
@@ -75,6 +88,7 @@ export class OcsChat {
75
88
  this.chatWindowWidth = 450;
76
89
  this.chatWindowFullscreenWidth = 1024;
77
90
  this.positionInitialized = false;
91
+ this.sessionEpoch = 0;
78
92
  this.handleMouseDown = (event) => {
79
93
  if (!this.isFullscreen && window.innerWidth < OcsChat.MOBILE_BREAKPOINT)
80
94
  return;
@@ -120,6 +134,8 @@ export class OcsChat {
120
134
  };
121
135
  this.handleWindowResize = () => {
122
136
  var _a, _b;
137
+ if (this.isKioskMode())
138
+ return;
123
139
  this.positionInitialized = false;
124
140
  this.initializePosition();
125
141
  // Revalidate button position after resize to keep it within viewport bounds
@@ -131,7 +147,7 @@ export class OcsChat {
131
147
  const minPadding = 10;
132
148
  this.buttonPosition = {
133
149
  x: Math.max(minPadding, Math.min(this.buttonPosition.x, windowWidth - buttonWidth - minPadding)),
134
- y: Math.max(minPadding, Math.min(this.buttonPosition.y, windowHeight - buttonHeight - minPadding))
150
+ y: Math.max(minPadding, Math.min(this.buttonPosition.y, windowHeight - buttonHeight - minPadding)),
135
151
  };
136
152
  this.updateHostPosition();
137
153
  }
@@ -149,7 +165,7 @@ export class OcsChat {
149
165
  const rect = this.host.getBoundingClientRect();
150
166
  this.buttonDragOffset = {
151
167
  x: pointer.clientX - rect.left,
152
- y: pointer.clientY - rect.top
168
+ y: pointer.clientY - rect.top,
153
169
  };
154
170
  this.addButtonEventListeners();
155
171
  };
@@ -166,7 +182,7 @@ export class OcsChat {
166
182
  const rect = this.host.getBoundingClientRect();
167
183
  this.buttonDragOffset = {
168
184
  x: pointer.clientX - rect.left,
169
- y: pointer.clientY - rect.top
185
+ y: pointer.clientY - rect.top,
170
186
  };
171
187
  this.addButtonEventListeners();
172
188
  };
@@ -213,6 +229,9 @@ export class OcsChat {
213
229
  this.error = 'Chatbot ID is required';
214
230
  return;
215
231
  }
232
+ if (this.isKioskMode()) {
233
+ this.visible = true;
234
+ }
216
235
  await this.initializeTranslations();
217
236
  // Always try to load existing session if localStorage is available
218
237
  if (this.persistentSession && this.isLocalStorageAvailable()) {
@@ -235,11 +254,20 @@ export class OcsChat {
235
254
  this.chatWindowWidth = varToPixels(windowWidthVar, window.innerWidth, this.chatWindowWidth);
236
255
  this.chatWindowFullscreenWidth = varToPixels(fullscreenWidthVar, window.innerWidth, this.chatWindowFullscreenWidth);
237
256
  // Initialize button position from computed styles
238
- this.initializeButtonPosition();
239
- // Defer position initialization to avoid state changes during componentDidLoad
257
+ if (this.showButton && !this.isKioskMode()) {
258
+ this.initializeButtonPosition();
259
+ }
260
+ // Defer state changes to avoid triggering them during componentDidLoad
240
261
  setTimeout(() => {
262
+ // Restore visible state after dimensions are read so initializePosition
263
+ // uses the correct CSS-derived chatWindowWidth/chatWindowHeight.
264
+ if (!this.isKioskMode() && this.showButton && this.persistentSession && this.isLocalStorageAvailable()) {
265
+ this.restoreVisibleState();
266
+ }
241
267
  if (this.visible) {
242
- this.initializePosition();
268
+ if (!this.isKioskMode()) {
269
+ this.initializePosition();
270
+ }
243
271
  }
244
272
  // Resume polling for existing session (don't auto-start new sessions)
245
273
  if (this.visible && this.sessionId) {
@@ -272,7 +300,7 @@ export class OcsChat {
272
300
  created_at: new Date().toISOString(),
273
301
  role: 'system',
274
302
  content: `**Error:** ${errorText}\nPlease try again.`,
275
- attachments: []
303
+ attachments: [],
276
304
  };
277
305
  this.messages = [...this.messages, errorMessage];
278
306
  this.saveSessionToStorage();
@@ -322,7 +350,7 @@ export class OcsChat {
322
350
  return;
323
351
  }
324
352
  if (typeof this.pageContext !== 'object' || Array.isArray(this.pageContext)) {
325
- console.error("pageContext is expected to be a plain JavaScript object.");
353
+ console.error('pageContext is expected to be a plain JavaScript object.');
326
354
  return;
327
355
  }
328
356
  this.internalPageContext = this.pageContext;
@@ -350,6 +378,7 @@ export class OcsChat {
350
378
  this.currentPollTaskId = '';
351
379
  }
352
380
  async startSession() {
381
+ const epoch = this.sessionEpoch;
353
382
  try {
354
383
  this.isLoading = true;
355
384
  const userId = this.getOrGenerateUserId();
@@ -357,19 +386,26 @@ export class OcsChat {
357
386
  chatbot_id: this.chatbotId,
358
387
  session_data: {
359
388
  source: 'widget',
360
- page_url: window.location.href
389
+ page_url: window.location.href,
361
390
  },
362
- participant_remote_id: userId
391
+ participant_remote_id: userId,
363
392
  };
364
393
  if (this.userName) {
365
394
  requestBody.participant_name = this.userName;
366
395
  }
396
+ if (this.versionNumber != null) {
397
+ requestBody.version_number = this.versionNumber;
398
+ }
367
399
  const data = await this.getChatService().startSession(requestBody);
400
+ if (epoch !== this.sessionEpoch)
401
+ return;
368
402
  this.sessionId = data.session_id;
369
403
  this.saveSessionToStorage();
370
404
  this.startMessagePolling();
371
405
  }
372
406
  catch (_error) {
407
+ if (epoch !== this.sessionEpoch)
408
+ return;
373
409
  this.handleError('Failed to start chat session');
374
410
  }
375
411
  finally {
@@ -398,6 +434,7 @@ export class OcsChat {
398
434
  async sendMessage(message) {
399
435
  if (!message.trim())
400
436
  return;
437
+ const epoch = this.sessionEpoch;
401
438
  // Start session if we don't have one yet
402
439
  if (!this.sessionId) {
403
440
  // Prevent concurrent session initialization
@@ -431,7 +468,7 @@ export class OcsChat {
431
468
  created_at: new Date(now.getTime() - (welcomeMessagesToAdd.length - index) * 1000).toISOString(),
432
469
  role: 'assistant',
433
470
  content: welcomeMsg,
434
- attachments: []
471
+ attachments: [],
435
472
  }));
436
473
  this.messages = [...this.messages, ...welcomeMessages];
437
474
  }
@@ -440,13 +477,15 @@ export class OcsChat {
440
477
  created_at: new Date().toISOString(),
441
478
  role: 'user',
442
479
  content: message.trim(),
443
- attachments: this.allowAttachments ? this.selectedFiles
444
- .filter(sf => !sf.error && sf.uploaded)
445
- .map(sf => ({
446
- name: sf.file.name,
447
- content_type: sf.file.type,
448
- size: sf.file.size,
449
- })) : []
480
+ attachments: this.allowAttachments
481
+ ? this.selectedFiles
482
+ .filter(sf => !sf.error && sf.uploaded)
483
+ .map(sf => ({
484
+ name: sf.file.name,
485
+ content_type: sf.file.type,
486
+ size: sf.file.size,
487
+ }))
488
+ : [],
450
489
  };
451
490
  this.messages = [...this.messages, userMessage];
452
491
  this.saveSessionToStorage();
@@ -462,7 +501,12 @@ export class OcsChat {
462
501
  if (this.internalPageContext) {
463
502
  requestBody.context = this.internalPageContext;
464
503
  }
504
+ if (this.versionNumber != null) {
505
+ requestBody.version_number = this.versionNumber;
506
+ }
465
507
  const data = await this.getChatService().sendMessage(this.sessionId, requestBody);
508
+ if (epoch !== this.sessionEpoch)
509
+ return;
466
510
  if (data.status === 'error') {
467
511
  throw new Error(data.error || 'Failed to send message');
468
512
  }
@@ -470,6 +514,8 @@ export class OcsChat {
470
514
  this.startTaskPolling(data.task_id);
471
515
  }
472
516
  catch (error) {
517
+ if (epoch !== this.sessionEpoch)
518
+ return;
473
519
  const errorText = error instanceof Error ? error.message : 'Failed to send message';
474
520
  this.handleError(errorText);
475
521
  }
@@ -492,10 +538,10 @@ export class OcsChat {
492
538
  const childRect = lastChild.getBoundingClientRect();
493
539
  const currentScrollTop = this.messageListRef.scrollTop;
494
540
  const childTopRelativeToParent = childRect.top - parentRect.top;
495
- const targetScroll = currentScrollTop + childTopRelativeToParent - (parentRect.height / 2);
541
+ const targetScroll = currentScrollTop + childTopRelativeToParent - parentRect.height / 2;
496
542
  this.messageListRef.scrollTo({
497
543
  top: targetScroll,
498
- behavior: 'smooth'
544
+ behavior: 'smooth',
499
545
  });
500
546
  }
501
547
  else {
@@ -540,10 +586,10 @@ export class OcsChat {
540
586
  const k = 1024;
541
587
  if (bytes < k * k) {
542
588
  // Less than 1MB, show in KB
543
- return Math.round(bytes / k * 100) / 100 + ' KB';
589
+ return Math.round((bytes / k) * 100) / 100 + ' KB';
544
590
  }
545
591
  else {
546
- return Math.round(bytes / (k * k) * 100) / 100 + ' MB';
592
+ return Math.round((bytes / (k * k)) * 100) / 100 + ' MB';
547
593
  }
548
594
  }
549
595
  formatTime(dateString) {
@@ -561,19 +607,30 @@ export class OcsChat {
561
607
  pageContextHandler() {
562
608
  this.loadInternalPageContext();
563
609
  }
610
+ async chatbotConfigHandler() {
611
+ await this.clearSession();
612
+ }
564
613
  /**
565
614
  * Watch for changes to the `visible` attribute and update accordingly.
566
615
  *
567
616
  * @param visible - The new value for the field.
568
617
  */
569
618
  async visibilityHandler(visible) {
619
+ // Kiosk mode is always visible
620
+ if (this.isKioskMode() && !visible) {
621
+ this.visible = true;
622
+ return;
623
+ }
624
+ this.saveVisibleState(visible);
570
625
  if (this.isButtonDragging) {
571
626
  this.isButtonDragging = false;
572
627
  this.buttonWasDragged = false;
573
628
  this.removeButtonEventListeners();
574
629
  }
575
630
  if (visible) {
576
- this.initializePosition();
631
+ if (!this.isKioskMode()) {
632
+ this.initializePosition();
633
+ }
577
634
  // Resume polling for existing session (don't auto-start new sessions)
578
635
  if (this.sessionId) {
579
636
  this.scrollToBottom(true);
@@ -594,37 +651,43 @@ export class OcsChat {
594
651
  this.taskPollingHandle.cancel();
595
652
  }
596
653
  this.taskPollingHandle = this.getChatService().pollTask(this.sessionId, taskId, {
597
- onMessage: (message) => {
654
+ onMessage: message => {
598
655
  this.messages = [...this.messages, message];
599
656
  this.saveSessionToStorage();
600
657
  this.scrollToBottom();
601
658
  this.isTyping = false;
659
+ this.typingProgressMessage = '';
602
660
  this.currentPollTaskId = '';
603
661
  this.taskPollingHandle = undefined;
604
662
  this.startMessagePolling();
605
663
  this.focusInput();
606
664
  },
665
+ onProgress: message => {
666
+ this.typingProgressMessage = message;
667
+ },
607
668
  onTimeout: () => {
608
669
  const timeoutMessage = {
609
670
  created_at: new Date().toISOString(),
610
671
  role: 'system',
611
672
  content: 'The response is taking longer than expected. The system may be experiencing delays. Please try sending your message again.',
612
- attachments: []
673
+ attachments: [],
613
674
  };
614
675
  this.messages = [...this.messages, timeoutMessage];
615
676
  this.saveSessionToStorage();
616
677
  this.scrollToBottom();
617
678
  this.isTyping = false;
679
+ this.typingProgressMessage = '';
618
680
  this.currentPollTaskId = '';
619
681
  this.taskPollingHandle = undefined;
620
682
  this.startMessagePolling();
621
683
  this.focusInput();
622
684
  },
623
- onError: (error) => {
685
+ onError: error => {
686
+ this.typingProgressMessage = '';
624
687
  this.handleError(error.message);
625
688
  this.taskPollingHandle = undefined;
626
689
  this.startMessagePolling();
627
- }
690
+ },
628
691
  });
629
692
  }
630
693
  startMessagePolling() {
@@ -635,8 +698,8 @@ export class OcsChat {
635
698
  return;
636
699
  }
637
700
  this.messagePollingHandle = this.getChatService().startMessagePolling(this.sessionId, {
638
- getSince: () => { var _a; return this.messages.length > 0 ? (_a = this.messages.at(-1)) === null || _a === void 0 ? void 0 : _a.created_at : undefined; },
639
- onMessages: (messages) => {
701
+ getSince: () => { var _a; return (this.messages.length > 0 ? (_a = this.messages.at(-1)) === null || _a === void 0 ? void 0 : _a.created_at : undefined); },
702
+ onMessages: messages => {
640
703
  if (messages.length === 0)
641
704
  return;
642
705
  this.messages = [...this.messages, ...messages];
@@ -646,7 +709,7 @@ export class OcsChat {
646
709
  },
647
710
  onError: () => {
648
711
  // Silently ignore polling errors to match previous behaviour
649
- }
712
+ },
650
713
  });
651
714
  }
652
715
  stopMessagePolling() {
@@ -665,6 +728,9 @@ export class OcsChat {
665
728
  this.position = position;
666
729
  }
667
730
  getPositionClasses() {
731
+ if (this.isKioskMode()) {
732
+ return 'chat-window-kiosk';
733
+ }
668
734
  if (this.isFullscreen) {
669
735
  return 'chat-window-fullscreen';
670
736
  }
@@ -680,6 +746,9 @@ export class OcsChat {
680
746
  return { windowWidth, actualChatWidth, centeredX, maxOffset };
681
747
  }
682
748
  getPositionStyles() {
749
+ if (this.isKioskMode()) {
750
+ return {};
751
+ }
683
752
  if (this.isFullscreen) {
684
753
  const { centeredX } = this.getFullscreenBounds();
685
754
  const finalX = centeredX + this.fullscreenPosition.x;
@@ -711,19 +780,19 @@ export class OcsChat {
711
780
  case 'left':
712
781
  this.windowPosition = {
713
782
  x: OcsChat.WINDOW_MARGIN,
714
- y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN
783
+ y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN,
715
784
  };
716
785
  break;
717
786
  case 'right':
718
787
  this.windowPosition = {
719
788
  x: windowWidth - chatWidth - OcsChat.WINDOW_MARGIN,
720
- y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN
789
+ y: windowHeight - this.chatWindowHeight - OcsChat.WINDOW_MARGIN,
721
790
  };
722
791
  break;
723
792
  case 'center':
724
793
  this.windowPosition = {
725
794
  x: (windowWidth - chatWidth) / 2,
726
- y: (windowHeight - this.chatWindowHeight) / 2
795
+ y: (windowHeight - this.chatWindowHeight) / 2,
727
796
  };
728
797
  break;
729
798
  }
@@ -746,14 +815,14 @@ export class OcsChat {
746
815
  // For fullscreen, track relative to current position
747
816
  this.dragOffset = {
748
817
  x: pointer.clientX,
749
- y: pointer.clientY
818
+ y: pointer.clientY,
750
819
  };
751
820
  }
752
821
  else {
753
822
  const rect = this.chatWindowRef.getBoundingClientRect();
754
823
  this.dragOffset = {
755
824
  x: pointer.clientX - rect.left,
756
- y: pointer.clientY - rect.top
825
+ y: pointer.clientY - rect.top,
757
826
  };
758
827
  }
759
828
  }
@@ -765,7 +834,7 @@ export class OcsChat {
765
834
  const { maxOffset } = this.getFullscreenBounds();
766
835
  const deltaX = pointer.clientX - this.dragOffset.x;
767
836
  this.fullscreenPosition = {
768
- x: Math.max(-maxOffset, Math.min(maxOffset, deltaX))
837
+ x: Math.max(-maxOffset, Math.min(maxOffset, deltaX)),
769
838
  };
770
839
  }
771
840
  else {
@@ -778,7 +847,7 @@ export class OcsChat {
778
847
  const chatHeight = this.chatWindowRef.offsetHeight;
779
848
  this.windowPosition = {
780
849
  x: Math.max(0, Math.min(newX, windowWidth - chatWidth)),
781
- y: Math.max(0, Math.min(newY, windowHeight - chatHeight))
850
+ y: Math.max(0, Math.min(newY, windowHeight - chatHeight)),
782
851
  };
783
852
  }
784
853
  }
@@ -825,7 +894,7 @@ export class OcsChat {
825
894
  const verticalValue = this.buttonVerticalSide === 'top' ? resolvedTop : resolvedBottom;
826
895
  this.buttonPosition = {
827
896
  x: horizontalValue,
828
- y: verticalValue
897
+ y: verticalValue,
829
898
  };
830
899
  // Apply the position to the host
831
900
  this.updateHostPosition();
@@ -868,12 +937,8 @@ export class OcsChat {
868
937
  const maxTop = windowHeight - buttonHeight - minPadding;
869
938
  const constrainedLeft = Math.max(minLeft, Math.min(candidateLeft, maxLeft));
870
939
  const constrainedTop = Math.max(minTop, Math.min(candidateTop, maxTop));
871
- const newHorizontalValue = this.buttonHorizontalSide === 'left'
872
- ? constrainedLeft
873
- : Math.max(minPadding, windowWidth - (constrainedLeft + buttonWidth));
874
- const newVerticalValue = this.buttonVerticalSide === 'top'
875
- ? constrainedTop
876
- : Math.max(minPadding, windowHeight - (constrainedTop + buttonHeight));
940
+ const newHorizontalValue = this.buttonHorizontalSide === 'left' ? constrainedLeft : Math.max(minPadding, windowWidth - (constrainedLeft + buttonWidth));
941
+ const newVerticalValue = this.buttonVerticalSide === 'top' ? constrainedTop : Math.max(minPadding, windowHeight - (constrainedTop + buttonHeight));
877
942
  if (newHorizontalValue !== this.buttonPosition.x || newVerticalValue !== this.buttonPosition.y) {
878
943
  this.buttonWasDragged = true;
879
944
  this.buttonPosition = { x: newHorizontalValue, y: newVerticalValue };
@@ -936,16 +1001,12 @@ export class OcsChat {
936
1001
  return fallback;
937
1002
  }
938
1003
  getWelcomeMessages() {
939
- const translated = this.translationManager.getArray("content.welcomeMessages");
940
- return translated && translated.length > 0
941
- ? translated
942
- : this.parsedWelcomeMessages;
1004
+ const translated = this.translationManager.getArray('content.welcomeMessages');
1005
+ return translated && translated.length > 0 ? translated : this.parsedWelcomeMessages;
943
1006
  }
944
1007
  getStarterQuestions() {
945
- const translated = this.translationManager.getArray("content.starterQuestions");
946
- return translated && translated.length > 0
947
- ? translated
948
- : this.parsedStarterQuestions;
1008
+ const translated = this.translationManager.getArray('content.starterQuestions');
1009
+ return translated && translated.length > 0 ? translated : this.parsedStarterQuestions;
949
1010
  }
950
1011
  getButtonClasses() {
951
1012
  const buttonText = this.translationManager.get('branding.buttonText', this.buttonText);
@@ -956,6 +1017,9 @@ export class OcsChat {
956
1017
  }
957
1018
  renderButton() {
958
1019
  var _a;
1020
+ if (!this.showButton || this.isKioskMode()) {
1021
+ return null;
1022
+ }
959
1023
  const buttonText = this.translationManager.get('branding.buttonText', this.buttonText);
960
1024
  const hasText = !!(buttonText && buttonText.trim());
961
1025
  const hasCustomIcon = this.iconUrl && this.iconUrl.trim();
@@ -965,21 +1029,24 @@ export class OcsChat {
965
1029
  const buttonAriaLabel = finalButtonText ? `${openLabel} - ${finalButtonText}` : openLabel;
966
1030
  // Only show drag cursor if button is draggable
967
1031
  const isDraggable = this.isButtonDraggable();
968
- const buttonStyle = isDraggable ? {
969
- cursor: this.isButtonDragging ? 'grabbing' : 'grab',
970
- } : {};
1032
+ const buttonStyle = isDraggable
1033
+ ? {
1034
+ cursor: this.isButtonDragging ? 'grabbing' : 'grab',
1035
+ }
1036
+ : {};
971
1037
  if (hasText) {
972
- return (h("button", { ref: (el) => this.buttonRef = el, class: buttonClasses, "aria-label": buttonAriaLabel, title: finalButtonText || openLabel, style: buttonStyle, onClick: () => this.handleButtonClick(), onMouseDown: (e) => this.handleButtonMouseDown(e), onTouchStart: (e) => this.handleButtonTouchStart(e), "aria-grabbed": this.isButtonDragging, "aria-describedby": isDraggable ? "chat-button-drag-hint" : undefined }, hasCustomIcon ? h("img", { src: this.iconUrl, alt: "" }) : h(OcsWidgetAvatar, null), h("span", null, finalButtonText), isDraggable && (h("span", { id: "chat-button-drag-hint", style: { display: 'none' } }, "Draggable. Use mouse or touch to reposition."))));
1038
+ return (h("button", { ref: el => (this.buttonRef = el), class: buttonClasses, "aria-label": buttonAriaLabel, title: finalButtonText || openLabel, style: buttonStyle, onClick: () => this.handleButtonClick(), onMouseDown: e => this.handleButtonMouseDown(e), onTouchStart: e => this.handleButtonTouchStart(e), "aria-grabbed": this.isButtonDragging, "aria-describedby": isDraggable ? 'chat-button-drag-hint' : undefined }, hasCustomIcon ? h("img", { src: this.iconUrl, alt: "" }) : h(OcsWidgetAvatar, null), h("span", null, finalButtonText), isDraggable && (h("span", { id: "chat-button-drag-hint", style: { display: 'none' } }, "Draggable. Use mouse or touch to reposition."))));
973
1039
  }
974
1040
  else {
975
- return (h("button", { ref: (el) => this.buttonRef = el, class: buttonClasses, "aria-label": openLabel, title: openLabel, style: buttonStyle, onClick: () => this.handleButtonClick(), onMouseDown: (e) => this.handleButtonMouseDown(e), onTouchStart: (e) => this.handleButtonTouchStart(e), "aria-grabbed": this.isButtonDragging, "aria-describedby": isDraggable ? "chat-button-drag-hint" : undefined }, hasCustomIcon ? h("img", { src: this.iconUrl, alt: "" }) : h(OcsWidgetAvatar, null), isDraggable && (h("span", { id: "chat-button-drag-hint", style: { display: 'none' } }, "Draggable. Use mouse or touch to reposition."))));
1041
+ return (h("button", { ref: el => (this.buttonRef = el), class: buttonClasses, "aria-label": openLabel, title: openLabel, style: buttonStyle, onClick: () => this.handleButtonClick(), onMouseDown: e => this.handleButtonMouseDown(e), onTouchStart: e => this.handleButtonTouchStart(e), "aria-grabbed": this.isButtonDragging, "aria-describedby": isDraggable ? 'chat-button-drag-hint' : undefined }, hasCustomIcon ? h("img", { src: this.iconUrl, alt: "" }) : h(OcsWidgetAvatar, null), isDraggable && (h("span", { id: "chat-button-drag-hint", style: { display: 'none' } }, "Draggable. Use mouse or touch to reposition."))));
976
1042
  }
977
1043
  }
978
1044
  getStorageKeys() {
979
1045
  return {
980
1046
  sessionId: `ocs-chat-session-${this.chatbotId}`,
981
1047
  messages: `ocs-chat-messages-${this.chatbotId}`,
982
- lastActivity: `ocs-chat-activity-${this.chatbotId}`
1048
+ lastActivity: `ocs-chat-activity-${this.chatbotId}`,
1049
+ visible: `ocs-chat-visible-${this.chatbotId}`,
983
1050
  };
984
1051
  }
985
1052
  saveSessionToStorage() {
@@ -1042,30 +1109,70 @@ export class OcsChat {
1042
1109
  return this.generatedUserId;
1043
1110
  }
1044
1111
  const storageKey = `ocs-user-id`;
1045
- const stored = localStorage.getItem(storageKey);
1112
+ let stored = null;
1113
+ try {
1114
+ stored = localStorage.getItem(storageKey);
1115
+ }
1116
+ catch (_a) {
1117
+ // localStorage blocked; fall through to in-memory id generation
1118
+ }
1046
1119
  if (stored) {
1047
1120
  this.generatedUserId = stored;
1048
1121
  return stored;
1049
1122
  }
1050
1123
  const array = new Uint8Array(9);
1051
1124
  window.crypto.getRandomValues(array);
1052
- const randomString = Array.from(array, byte => byte.toString(36)).join('').substr(0, 9);
1125
+ const randomString = Array.from(array, byte => byte.toString(36))
1126
+ .join('')
1127
+ .substr(0, 9);
1053
1128
  const newUserId = `ocs:${Date.now()}_${randomString}`;
1054
1129
  this.generatedUserId = newUserId;
1055
- localStorage.setItem(storageKey, newUserId);
1130
+ try {
1131
+ localStorage.setItem(storageKey, newUserId);
1132
+ }
1133
+ catch (_b) {
1134
+ // localStorage blocked; the generated id lives in component state for this page
1135
+ }
1056
1136
  return newUserId;
1057
1137
  }
1138
+ saveVisibleState(visible) {
1139
+ if (!this.persistentSession)
1140
+ return;
1141
+ try {
1142
+ const keys = this.getStorageKeys();
1143
+ localStorage.setItem(keys.visible, visible ? '1' : '0');
1144
+ }
1145
+ catch (_a) {
1146
+ // ignore
1147
+ }
1148
+ }
1149
+ restoreVisibleState() {
1150
+ try {
1151
+ const keys = this.getStorageKeys();
1152
+ const stored = localStorage.getItem(keys.visible);
1153
+ if (stored === '1') {
1154
+ this.visible = true;
1155
+ }
1156
+ }
1157
+ catch (_a) {
1158
+ // ignore
1159
+ }
1160
+ }
1058
1161
  clearSessionStorage() {
1059
1162
  const keys = this.getStorageKeys();
1060
1163
  try {
1061
1164
  localStorage.removeItem(keys.sessionId);
1062
1165
  localStorage.removeItem(keys.messages);
1063
1166
  localStorage.removeItem(keys.lastActivity);
1167
+ localStorage.removeItem(keys.visible);
1064
1168
  }
1065
1169
  catch (error) {
1066
1170
  console.warn('Failed to clear chat session from localStorage:', error);
1067
1171
  }
1068
1172
  }
1173
+ isKioskMode() {
1174
+ return this.mode === 'kiosk';
1175
+ }
1069
1176
  isLocalStorageAvailable() {
1070
1177
  try {
1071
1178
  localStorage.setItem(OcsChat.LOCALSTORAGE_TEST_KEY, 'test');
@@ -1091,6 +1198,7 @@ export class OcsChat {
1091
1198
  * will start when the user sends a message.
1092
1199
  */
1093
1200
  async clearSession() {
1201
+ this.sessionEpoch += 1;
1094
1202
  this.clearSessionStorage();
1095
1203
  this.sessionId = undefined;
1096
1204
  this.messages = [];
@@ -1111,18 +1219,12 @@ export class OcsChat {
1111
1219
  if (this.error && !this.sessionId) {
1112
1220
  return (h(Host, null, h("p", { class: "error-message" }, this.error)));
1113
1221
  }
1114
- return (h(Host, null, this.renderButton(), this.visible && (h("div", { ref: (el) => this.chatWindowRef = el, id: "ocs-chat-window", class: this.getPositionClasses(), style: this.getPositionStyles() }, h("div", { class: `chat-header ${this.isDragging ? 'chat-header-dragging' : 'chat-header-draggable'}`, onMouseDown: this.handleMouseDown, onTouchStart: this.handleTouchStart }, h("div", { class: "drag-indicator" }, h("div", { class: "drag-dots header-button" }, h(GripDotsVerticalIcon, null))), h("div", { class: "header-text" }, this.translationManager.get('branding.headerText', this.headerText)), h("div", { class: "header-buttons" }, this.messages.length > 0 && (h("button", { class: "header-button", onClick: () => this.showConfirmationDialog(), title: this.translationManager.get('window.newChat'), "aria-label": this.translationManager.get('window.newChat') }, h(PlusWithCircleIcon, null))), this.allowFullScreen && h("button", { class: "header-button fullscreen-button", onClick: () => this.toggleFullscreen(), title: this.isFullscreen ? this.translationManager.get('window.exitFullscreen') : this.translationManager.get('window.fullscreen'), "aria-label": this.isFullscreen ? this.translationManager.get('window.exitFullscreen') : this.translationManager.get('window.fullscreen') }, this.isFullscreen ? h(ArrowsPointingInIcon, null) : h(ArrowsPointingOutIcon, null)), h("button", { class: "header-button", onClick: () => this.visible = false, "aria-label": this.translationManager.get('window.close') }, h(XMarkIcon, null)))), this.showNewChatConfirmation && (h("div", { class: "confirmation-overlay" }, h("div", { class: "confirmation-dialog" }, h("div", { class: "confirmation-content" }, h("h3", { class: "confirmation-title" }, this.translationManager.get('modal.newChatTitle')), h("p", { class: "confirmation-message" }, this.translationManager.get('modal.newChatBody', this.newChatConfirmationMessage)), h("div", { class: "confirmation-buttons" }, h("button", { class: "confirmation-button confirmation-button-cancel", onClick: () => this.hideConfirmationDialog() }, this.translationManager.get('modal.cancel')), h("button", { class: "confirmation-button confirmation-button-confirm", onClick: () => this.confirmNewChat() }, this.translationManager.get('modal.confirm'))))))), h("div", { class: "chat-content" }, this.isLoading && !this.sessionId && (h("div", { class: "loading-container" }, h("div", { class: "loading-spinner" }), h("span", { class: "loading-text" }, this.translationManager.get('status.starting')))), (h("div", { ref: (el) => this.messageListRef = el, class: "messages-container" }, this.messages.length === 0 && this.getWelcomeMessages().length > 0 && (h("div", { class: "welcome-messages" }, this.getWelcomeMessages().map((message, index) => (h("div", { key: `welcome-${index}`, class: "message-row message-row-assistant" }, h("div", { class: "message-bubble message-bubble-assistant" }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownComplete(message) }))))))), this.messages.map((message, index) => (h("div", { key: index, class: `message-row ${message.role === 'user' ? 'message-row-user' : 'message-row-assistant'}` }, h("div", { class: `message-bubble ${message.role === 'user'
1115
- ? 'message-bubble-user'
1116
- : message.role === 'assistant'
1117
- ? 'message-bubble-assistant'
1118
- : 'message-bubble-system'}` }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownComplete(message.content) }), message.attachments && message.attachments.length > 0 && (h("div", { class: "message-attachments" }, message.attachments.map((attachment, attachmentIndex) => (h("div", { key: attachmentIndex, class: "flex items-center gap-[0.5em]" }, h("span", { class: "message-attachment-icon" }, h(PaperClipIcon, null)), h("span", { class: "message-attachment-name" }, attachment.name)))))), h("div", { class: "message-timestamp" }, this.formatTime(message.created_at)))))), this.isTyping && (h("div", null, h("div", { class: "typing-indicator" }, h("div", { class: "typing-progress" })), h("div", { class: "typing-text" }, h("span", null, this.translationManager.get('status.typing', this.typingIndicatorText)), h("span", { class: "typing-dots loading" })))))), this.messages.length === 0 && this.getStarterQuestions().length > 0 && (h("div", { class: "starter-questions" }, this.getStarterQuestions().map((question, index) => (h("div", { key: `starter-${index}`, class: "starter-question-row" }, h("button", { class: "starter-question", onClick: () => this.handleStarterQuestionClick(question) }, question)))))), this.allowAttachments && this.selectedFiles.length > 0 && (h("div", { class: "selected-files-container" }, h("div", { class: "space-y-[0.25em]" }, this.selectedFiles.map((selectedFile, index) => (h("div", { key: index, class: "selected-file-item" }, h("div", { class: "flex items-center gap-[0.5em]" }, h("span", { class: "selected-file-icon" }, h(PaperClipIcon, null)), h("span", null, selectedFile.file.name), h("span", { class: "selected-file-size" }, "(", this.formatFileSize(selectedFile.file.size), ")"), selectedFile.error && (h("span", { class: "selected-file-error" }, selectedFile.error)), selectedFile.uploaded && (h("span", { class: "selected-file-success-icon" }, h(CheckDocumentIcon, null)))), h("button", { onClick: () => this.removeSelectedFile(index), class: "selected-file-remove-button", "aria-label": this.translationManager.get('attach.remove') }, h(XIcon, null)))))))), h("div", { class: "input-area" }, h("div", { class: "input-container" }, h("textarea", { ref: (el) => this.textareaRef = el, class: "message-textarea", rows: 1, placeholder: this.translationManager.get('composer.placeholder'), value: this.messageInput, onInput: (e) => this.handleInputChange(e), onKeyPress: (e) => this.handleKeyPress(e), disabled: this.isTyping || this.isUploadingFiles || this.isLoading }), this.allowAttachments && (h("input", { ref: (el) => {
1222
+ return (h(Host, null, this.renderButton(), this.visible && (h("div", { ref: el => (this.chatWindowRef = el), id: "ocs-chat-window", class: this.getPositionClasses(), style: this.getPositionStyles() }, !this.isKioskMode() && (h("div", { class: `chat-header ${this.isDragging ? 'chat-header-dragging' : 'chat-header-draggable'}`, onMouseDown: this.handleMouseDown, onTouchStart: this.handleTouchStart }, h("div", { class: "drag-indicator" }, h("div", { class: "drag-dots header-button" }, h(GripDotsVerticalIcon, null))), h("div", { class: "header-text" }, this.translationManager.get('branding.headerText', this.headerText)), h("div", { class: "header-buttons" }, this.messages.length > 0 && (h("button", { class: "header-button", onClick: () => this.showConfirmationDialog(), title: this.translationManager.get('window.newChat'), "aria-label": this.translationManager.get('window.newChat') }, h(PlusWithCircleIcon, null))), this.allowFullScreen && (h("button", { class: "header-button fullscreen-button", onClick: () => this.toggleFullscreen(), title: this.isFullscreen ? this.translationManager.get('window.exitFullscreen') : this.translationManager.get('window.fullscreen'), "aria-label": this.isFullscreen ? this.translationManager.get('window.exitFullscreen') : this.translationManager.get('window.fullscreen') }, this.isFullscreen ? h(ArrowsPointingInIcon, null) : h(ArrowsPointingOutIcon, null))), h("button", { class: "header-button", onClick: () => (this.visible = false), "aria-label": this.translationManager.get('window.close') }, h(XMarkIcon, null))))), !this.isKioskMode() && this.showNewChatConfirmation && (h("div", { class: "confirmation-overlay" }, h("div", { class: "confirmation-dialog" }, h("div", { class: "confirmation-content" }, h("h3", { class: "confirmation-title" }, this.translationManager.get('modal.newChatTitle')), h("p", { class: "confirmation-message" }, this.translationManager.get('modal.newChatBody', this.newChatConfirmationMessage)), h("div", { class: "confirmation-buttons" }, h("button", { class: "confirmation-button confirmation-button-cancel", onClick: () => this.hideConfirmationDialog() }, this.translationManager.get('modal.cancel')), h("button", { class: "confirmation-button confirmation-button-confirm", onClick: () => this.confirmNewChat() }, this.translationManager.get('modal.confirm'))))))), h("div", { class: "chat-content" }, this.isLoading && !this.sessionId && (h("div", { class: "loading-container" }, h("div", { class: "loading-spinner" }), h("span", { class: "loading-text" }, this.translationManager.get('status.starting')))), h("div", { ref: el => (this.messageListRef = el), class: "messages-container" }, this.messages.length === 0 && this.getWelcomeMessages().length > 0 && (h("div", { class: "welcome-messages" }, this.getWelcomeMessages().map((message, index) => (h("div", { key: `welcome-${index}`, class: "message-row message-row-assistant" }, h("div", { class: "message-bubble message-bubble-assistant" }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownComplete(message) }))))))), this.messages.map((message, index) => (h("div", { key: index, class: `message-row ${message.role === 'user' ? 'message-row-user' : 'message-row-assistant'}` }, h("div", { class: `message-bubble ${message.role === 'user' ? 'message-bubble-user' : message.role === 'assistant' ? 'message-bubble-assistant' : 'message-bubble-system'}` }, h("div", { class: "chat-markdown", innerHTML: renderMarkdownComplete(message.content) }), message.attachments && message.attachments.length > 0 && (h("div", { class: "message-attachments" }, message.attachments.map((attachment, attachmentIndex) => (h("div", { key: attachmentIndex, class: "flex items-center gap-[0.5em]" }, h("span", { class: "message-attachment-icon" }, h(PaperClipIcon, null)), h("span", { class: "message-attachment-name" }, attachment.name)))))), h("div", { class: "message-timestamp" }, this.formatTime(message.created_at)))))), this.isTyping && (h("div", null, h("div", { class: "typing-indicator" }, h("div", { class: "typing-progress" })), h("div", { class: "typing-text" }, h("span", null, this.typingProgressMessage || this.translationManager.get('status.typing', this.typingIndicatorText)), h("span", { class: "typing-dots loading" }))))), this.messages.length === 0 && this.getStarterQuestions().length > 0 && (h("div", { class: "starter-questions" }, this.getStarterQuestions().map((question, index) => (h("div", { key: `starter-${index}`, class: "starter-question-row" }, h("button", { class: "starter-question", onClick: () => this.handleStarterQuestionClick(question) }, question)))))), this.allowAttachments && this.selectedFiles.length > 0 && (h("div", { class: "selected-files-container" }, h("div", { class: "space-y-[0.25em]" }, this.selectedFiles.map((selectedFile, index) => (h("div", { key: index, class: "selected-file-item" }, h("div", { class: "flex items-center gap-[0.5em]" }, h("span", { class: "selected-file-icon" }, h(PaperClipIcon, null)), h("span", null, selectedFile.file.name), h("span", { class: "selected-file-size" }, "(", this.formatFileSize(selectedFile.file.size), ")"), selectedFile.error && h("span", { class: "selected-file-error" }, selectedFile.error), selectedFile.uploaded && (h("span", { class: "selected-file-success-icon" }, h(CheckDocumentIcon, null)))), h("button", { onClick: () => this.removeSelectedFile(index), class: "selected-file-remove-button", "aria-label": this.translationManager.get('attach.remove') }, h(XIcon, null)))))))), h("div", { class: "input-area" }, h("div", { class: "input-container" }, h("textarea", { ref: el => (this.textareaRef = el), class: "message-textarea", rows: 1, placeholder: this.translationManager.get('composer.placeholder'), value: this.messageInput, onInput: e => this.handleInputChange(e), onKeyPress: e => this.handleKeyPress(e), disabled: this.isTyping || this.isUploadingFiles || this.isLoading }), this.allowAttachments && (h("input", { ref: el => {
1119
1223
  // Unclear why but after removing all attachments this is being set to `null`.
1120
1224
  if (el) {
1121
1225
  this.fileInputRef = el;
1122
1226
  }
1123
- }, id: "ocs-file-input", type: "file", multiple: true, accept: OcsChat.SUPPORTED_FILE_EXTENSIONS.join(',') + ',text/*', onChange: (e) => this.handleFileSelect(e), class: "hidden" })), this.allowAttachments && (h("button", { class: "file-attachment-button", onClick: () => { var _a; return (_a = this.fileInputRef) === null || _a === void 0 ? void 0 : _a.click(); }, disabled: this.isTyping || this.isUploadingFiles || this.isLoading, title: this.translationManager.get('attach.add'), "aria-label": this.translationManager.get('attach.add') }, h(PaperClipIcon, null))), h("button", { class: `send-button ${!this.isTyping && !this.isLoading && !!this.messageInput.trim()
1124
- ? 'send-button-enabled'
1125
- : 'send-button-disabled'}`, onClick: () => this.sendMessage(this.messageInput), disabled: this.isTyping || this.isUploadingFiles || this.isLoading || !this.messageInput.trim() }, this.isUploadingFiles ? `${this.translationManager.get('status.uploading')}...` : this.translationManager.get('composer.send')))), h("div", { class: "flex items-center justify-center text-[0.8em] font-light w-full text-slate-500 py-[2px]" }, h("p", null, this.translationManager.get('branding.poweredBy'), ' ', " ", h("a", { class: "underline", href: "https://www.dimagi.com", target: "_blank" }, "Dimagi"))))))));
1227
+ }, id: "ocs-file-input", type: "file", multiple: true, accept: OcsChat.SUPPORTED_FILE_EXTENSIONS.join(',') + ',text/*', onChange: e => this.handleFileSelect(e), class: "hidden" })), this.allowAttachments && (h("button", { class: "file-attachment-button", onClick: () => { var _a; return (_a = this.fileInputRef) === null || _a === void 0 ? void 0 : _a.click(); }, disabled: this.isTyping || this.isUploadingFiles || this.isLoading, title: this.translationManager.get('attach.add'), "aria-label": this.translationManager.get('attach.add') }, h(PaperClipIcon, null))), h("button", { class: `send-button ${!this.isTyping && !this.isLoading && !!this.messageInput.trim() ? 'send-button-enabled' : 'send-button-disabled'}`, onClick: () => this.sendMessage(this.messageInput), disabled: this.isTyping || this.isUploadingFiles || this.isLoading || !this.messageInput.trim() }, this.isUploadingFiles ? `${this.translationManager.get('status.uploading')}...` : this.translationManager.get('composer.send')))), h("div", { class: "flex items-center justify-center text-[0.8em] font-light w-full text-slate-500 py-[2px]" }, h("p", null, this.translationManager.get('branding.poweredBy'), ' ', h("a", { class: "underline", href: "https://www.dimagi.com", target: "_blank", rel: "noopener noreferrer" }, "Dimagi"))))))));
1126
1228
  }
1127
1229
  static get is() { return "open-chat-studio-widget"; }
1128
1230
  static get encapsulation() { return "shadow"; }
@@ -1175,7 +1277,7 @@ export class OcsChat {
1175
1277
  "getter": false,
1176
1278
  "setter": false,
1177
1279
  "reflect": false,
1178
- "defaultValue": "\"https://www.openchatstudio.com\""
1280
+ "defaultValue": "'https://www.openchatstudio.com'"
1179
1281
  },
1180
1282
  "buttonText": {
1181
1283
  "type": "string",
@@ -1254,6 +1356,46 @@ export class OcsChat {
1254
1356
  "reflect": false,
1255
1357
  "defaultValue": "'square'"
1256
1358
  },
1359
+ "showButton": {
1360
+ "type": "boolean",
1361
+ "attribute": "show-button",
1362
+ "mutable": false,
1363
+ "complexType": {
1364
+ "original": "boolean",
1365
+ "resolved": "boolean",
1366
+ "references": {}
1367
+ },
1368
+ "required": false,
1369
+ "optional": false,
1370
+ "docs": {
1371
+ "tags": [],
1372
+ "text": "Whether to show the launcher button. Set to false to hide the button\nand open the chat window programmatically via the `visible` property."
1373
+ },
1374
+ "getter": false,
1375
+ "setter": false,
1376
+ "reflect": false,
1377
+ "defaultValue": "true"
1378
+ },
1379
+ "mode": {
1380
+ "type": "string",
1381
+ "attribute": "mode",
1382
+ "mutable": false,
1383
+ "complexType": {
1384
+ "original": "'standard' | 'kiosk'",
1385
+ "resolved": "\"kiosk\" | \"standard\"",
1386
+ "references": {}
1387
+ },
1388
+ "required": false,
1389
+ "optional": false,
1390
+ "docs": {
1391
+ "tags": [],
1392
+ "text": "The operating mode of the widget.\n- 'standard': Default floating window with launcher button.\n- 'kiosk': Fills parent container, always visible, no header or launcher button.\n The parent element must establish a containing block (e.g. `position: relative`)."
1393
+ },
1394
+ "getter": false,
1395
+ "setter": false,
1396
+ "reflect": false,
1397
+ "defaultValue": "'standard'"
1398
+ },
1257
1399
  "headerText": {
1258
1400
  "type": "string",
1259
1401
  "attribute": "header-text",
@@ -1567,6 +1709,28 @@ export class OcsChat {
1567
1709
  },
1568
1710
  "getter": false,
1569
1711
  "setter": false
1712
+ },
1713
+ "versionNumber": {
1714
+ "type": "number",
1715
+ "attribute": "version-number",
1716
+ "mutable": false,
1717
+ "complexType": {
1718
+ "original": "number",
1719
+ "resolved": "number",
1720
+ "references": {}
1721
+ },
1722
+ "required": false,
1723
+ "optional": true,
1724
+ "docs": {
1725
+ "tags": [{
1726
+ "name": "internal",
1727
+ "text": "Optional version number of the chatbot to use. Requires authentication.\nThis is for internal use only and is not intended for public-facing widgets."
1728
+ }],
1729
+ "text": ""
1730
+ },
1731
+ "getter": false,
1732
+ "setter": false,
1733
+ "reflect": false
1570
1734
  }
1571
1735
  };
1572
1736
  }
@@ -1577,6 +1741,7 @@ export class OcsChat {
1577
1741
  "sessionId": {},
1578
1742
  "isLoading": {},
1579
1743
  "isTyping": {},
1744
+ "typingProgressMessage": {},
1580
1745
  "messageInput": {},
1581
1746
  "currentPollTaskId": {},
1582
1747
  "isDragging": {},
@@ -1599,6 +1764,12 @@ export class OcsChat {
1599
1764
  return [{
1600
1765
  "propName": "pageContext",
1601
1766
  "methodName": "pageContextHandler"
1767
+ }, {
1768
+ "propName": "chatbotId",
1769
+ "methodName": "chatbotConfigHandler"
1770
+ }, {
1771
+ "propName": "versionNumber",
1772
+ "methodName": "chatbotConfigHandler"
1602
1773
  }, {
1603
1774
  "propName": "visible",
1604
1775
  "methodName": "visibilityHandler"
@@ -1615,7 +1786,39 @@ OcsChat.WINDOW_MARGIN = 20;
1615
1786
  OcsChat.LOCALSTORAGE_TEST_KEY = '__ocs_test__';
1616
1787
  OcsChat.MAX_FILE_SIZE_MB = 50;
1617
1788
  OcsChat.MAX_TOTAL_SIZE_MB = 50;
1618
- OcsChat.SUPPORTED_FILE_EXTENSIONS = ['.txt', '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.csv', '.jpg',
1619
- '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg', '.mp4', '.mov', '.avi', '.mp3', '.wav', '.html', '.htm', '.css',
1620
- '.js', '.xml', '.md', '.ics', '.vcf', '.rtf', '.tsv', '.yaml', '.yml', '.py', '.c'];
1789
+ OcsChat.SUPPORTED_FILE_EXTENSIONS = [
1790
+ '.txt',
1791
+ '.pdf',
1792
+ '.doc',
1793
+ '.docx',
1794
+ '.xls',
1795
+ '.xlsx',
1796
+ '.csv',
1797
+ '.jpg',
1798
+ '.jpeg',
1799
+ '.png',
1800
+ '.gif',
1801
+ '.bmp',
1802
+ '.webp',
1803
+ '.svg',
1804
+ '.mp4',
1805
+ '.mov',
1806
+ '.avi',
1807
+ '.mp3',
1808
+ '.wav',
1809
+ '.html',
1810
+ '.htm',
1811
+ '.css',
1812
+ '.js',
1813
+ '.xml',
1814
+ '.md',
1815
+ '.ics',
1816
+ '.vcf',
1817
+ '.rtf',
1818
+ '.tsv',
1819
+ '.yaml',
1820
+ '.yml',
1821
+ '.py',
1822
+ '.c',
1823
+ ];
1621
1824
  //# sourceMappingURL=ocs-chat.js.map