@carbon/ai-chat 1.15.0-rc.1 → 1.16.0-rc.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.
@@ -92,6 +92,8 @@ import "lodash-es/throttle.js";
92
92
 
93
93
  import "@carbon/icons/es/down-to-bottom/16.js";
94
94
 
95
+ import "@carbon/ai-chat-components/es/globals/settings.js";
96
+
95
97
  import "@carbon/icons/es/screen--off/16.js";
96
98
 
97
99
  import "@carbon/icons/es/user--avatar/32.js";
@@ -128,8 +130,6 @@ import "@carbon/ai-chat-components/es/react/feedback-buttons.js";
128
130
 
129
131
  import "@carbon/ai-chat-components/es/react/feedback.js";
130
132
 
131
- import "@carbon/ai-chat-components/es/globals/settings.js";
132
-
133
133
  import "@carbon/icons/es/checkmark/16.js";
134
134
 
135
135
  import "@carbon/icons/es/headset/16.js";
@@ -218,12 +218,12 @@ import "lit/decorators.js";
218
218
 
219
219
  import "@carbon/ai-chat-components/es/react/panel.js";
220
220
 
221
- import "@carbon/icons/es/chevron--down/20.js";
222
-
223
- import "@carbon/icons/es/close--large/20.js";
221
+ import "@carbon/icons/es/chevron--left/16.js";
224
222
 
225
223
  import "@carbon/ai-chat-components/es/react/toolbar.js";
226
224
 
225
+ import "@carbon/web-components/es/components/icon-button/icon-button.js";
226
+
227
227
  import "@carbon/web-components/es/components/chat-button/chat-button.js";
228
228
 
229
229
  function readCarbonChatSession(namespace) {
@@ -76,6 +76,8 @@ import throttle from "lodash-es/throttle.js";
76
76
 
77
77
  import DownToBottom16 from "@carbon/icons/es/down-to-bottom/16.js";
78
78
 
79
+ import prefix from "@carbon/ai-chat-components/es/globals/settings.js";
80
+
79
81
  import ScreenOff16 from "@carbon/icons/es/screen--off/16.js";
80
82
 
81
83
  import UserAvatar32 from "@carbon/icons/es/user--avatar/32.js";
@@ -112,8 +114,6 @@ import FeedbackButtons from "@carbon/ai-chat-components/es/react/feedback-button
112
114
 
113
115
  import Feedback from "@carbon/ai-chat-components/es/react/feedback.js";
114
116
 
115
- import prefix from "@carbon/ai-chat-components/es/globals/settings.js";
116
-
117
117
  import Checkmark16 from "@carbon/icons/es/checkmark/16.js";
118
118
 
119
119
  import Headset16 from "@carbon/icons/es/headset/16.js";
@@ -208,12 +208,12 @@ import { property } from "lit/decorators.js";
208
208
 
209
209
  import ChatPanel from "@carbon/ai-chat-components/es/react/panel.js";
210
210
 
211
- import ChevronDown20 from "@carbon/icons/es/chevron--down/20.js";
212
-
213
- import CloseLarge20 from "@carbon/icons/es/close--large/20.js";
211
+ import ChevronLeft16 from "@carbon/icons/es/chevron--left/16.js";
214
212
 
215
213
  import Toolbar from "@carbon/ai-chat-components/es/react/toolbar.js";
216
214
 
215
+ import CarbonIconButtonElement from "@carbon/web-components/es/components/icon-button/icon-button.js";
216
+
217
217
  import CarbonChatButtonElement, { CHAT_BUTTON_SIZE as CHAT_BUTTON_SIZE$1, CHAT_BUTTON_KIND as CHAT_BUTTON_KIND$1 } from "@carbon/web-components/es/components/chat-button/chat-button.js";
218
218
 
219
219
  const VERSION = "1.15.0";
@@ -2017,7 +2017,9 @@ const DEFAULT_CUSTOM_PANEL_CONFIG_OPTIONS = {
2017
2017
  hideBackButton: false,
2018
2018
  disableAnimation: false,
2019
2019
  fullWidth: false,
2020
- backButtonType: "minimize"
2020
+ backButtonType: "minimize",
2021
+ showChatHeader: false,
2022
+ openFromSide: false
2021
2023
  };
2022
2024
 
2023
2025
  deepFreeze(DEFAULT_CUSTOM_PANEL_CONFIG_OPTIONS);
@@ -9348,6 +9350,7 @@ function MessagesTypingIndicator({carbonTheme, index, isTypingMessage, isVisible
9348
9350
  }, React.createElement(Processing, {
9349
9351
  className: "cds-aichat--processing-component",
9350
9352
  loop: true,
9353
+ quickLoad: true,
9351
9354
  carbonTheme,
9352
9355
  "aria-label": processingLabel
9353
9356
  }), " ", React.createElement("div", {
@@ -11144,7 +11147,7 @@ const OperationalTag = createComponent({
11144
11147
  react: React
11145
11148
  });
11146
11149
 
11147
- const ChevronDown = carbonIconToReact(ChevronDown16);
11150
+ const ChevronDown$1 = carbonIconToReact(ChevronDown16);
11148
11151
 
11149
11152
  const ChevronUp = carbonIconToReact(ChevronUp16);
11150
11153
 
@@ -11190,7 +11193,7 @@ function ConversationalSearchText(props) {
11190
11193
  "aria-label": languagePack.conversationalSearch_toggleCitations
11191
11194
  }, React.createElement("span", {
11192
11195
  slot: "icon"
11193
- }, citationsOpen ? React.createElement(ChevronUp, null) : React.createElement(ChevronDown, null))))));
11196
+ }, citationsOpen ? React.createElement(ChevronUp, null) : React.createElement(ChevronDown$1, null))))));
11194
11197
  }
11195
11198
 
11196
11199
  function insertHighlightMarkdown(text, highlightCitation) {
@@ -13294,14 +13297,16 @@ class MessagesComponent extends PureComponent {
13294
13297
  });
13295
13298
  this.scheduleAutoScroll = (options = {}, includePublicSpacerReconciliation = false) => {
13296
13299
  requestAnimationFrame(() => {
13297
- const scrollElement = this.messagesContainerWithScrollingRef.current;
13298
- if (!scrollElement) {
13299
- return;
13300
- }
13301
- this.executeResolvedAutoScrollAction(options, scrollElement);
13302
- if (includePublicSpacerReconciliation) {
13303
- this.reconcileSpacerAfterPublicDoAutoScroll(scrollElement);
13304
- }
13300
+ void (async () => {
13301
+ const scrollElement = this.messagesContainerWithScrollingRef.current;
13302
+ if (!scrollElement) {
13303
+ return;
13304
+ }
13305
+ await this.executeResolvedAutoScrollAction(options, scrollElement);
13306
+ if (includePublicSpacerReconciliation) {
13307
+ this.reconcileSpacerAfterPublicDoAutoScroll(scrollElement);
13308
+ }
13309
+ })();
13305
13310
  });
13306
13311
  };
13307
13312
  this.doAutoScrollInternal = (options = {}) => {
@@ -13399,7 +13404,10 @@ class MessagesComponent extends PureComponent {
13399
13404
  if (scrollElement && spacerElem && this.pinnedMessageComponent) {
13400
13405
  const maxScrollTop = scrollElement.scrollHeight - scrollElement.clientHeight;
13401
13406
  const wasBrowserCapped = scrollElement.scrollTop >= maxScrollTop - 2 && scrollElement.scrollTop < this.pinnedScrollTop;
13402
- this.domSpacerHeight = Math.max(0, this.domSpacerHeight - delta);
13407
+ const deltaCompensated = Math.max(0, this.domSpacerHeight - delta);
13408
+ const contentHeightWithoutSpacer = scrollElement.scrollHeight - this.domSpacerHeight;
13409
+ const minSpacerForPin = Math.max(0, this.pinnedScrollTop + scrollElement.clientHeight - contentHeightWithoutSpacer);
13410
+ this.domSpacerHeight = Math.min(deltaCompensated, Math.max(this.domSpacerHeight, minSpacerForPin));
13403
13411
  applySpacerDeficit(spacerElem, this.domSpacerHeight);
13404
13412
  const scrollDelta = Math.abs(scrollElement.scrollTop - this.pinnedScrollTop);
13405
13413
  const hasScrolledAway = scrollDelta > 50;
@@ -13493,6 +13501,20 @@ class MessagesComponent extends PureComponent {
13493
13501
  this.pinnedScrollTop = result.scrollTop;
13494
13502
  debugAutoScroll(`[autoScroll] Pinned message, scrollTop=${result.scrollTop}, spacer=${result.currentSpacerHeight}px`);
13495
13503
  }
13504
+ async waitForMessageComponentLayout(messageComponent) {
13505
+ const targetElem = messageComponent?.ref?.current;
13506
+ if (!targetElem) {
13507
+ return;
13508
+ }
13509
+ const markdownElement = targetElem.querySelector(`${prefix}-markdown`);
13510
+ if (!markdownElement) {
13511
+ return;
13512
+ }
13513
+ await (markdownElement.updateComplete?.catch(() => undefined));
13514
+ await new Promise(resolve => {
13515
+ requestAnimationFrame(() => resolve());
13516
+ });
13517
+ }
13496
13518
  executeRecalculateSpacer(scrollElement) {
13497
13519
  const result = recalculatePinnedMessageSpacer({
13498
13520
  pinnedMessageComponent: this.pinnedMessageComponent,
@@ -13504,7 +13526,7 @@ class MessagesComponent extends PureComponent {
13504
13526
  }
13505
13527
  this.domSpacerHeight = result.deficit;
13506
13528
  }
13507
- executeResolvedAutoScrollAction(options, scrollElement) {
13529
+ async executeResolvedAutoScrollAction(options, scrollElement) {
13508
13530
  const action = resolveAutoScrollAction({
13509
13531
  allMessagesByID: this.props.allMessagesByID,
13510
13532
  localMessageItems: this.props.localMessageItems,
@@ -13531,6 +13553,10 @@ class MessagesComponent extends PureComponent {
13531
13553
  return;
13532
13554
 
13533
13555
  case "pin_message":
13556
+ await this.waitForMessageComponentLayout(action.messageComponent);
13557
+ if (!scrollElement.isConnected) {
13558
+ return;
13559
+ }
13534
13560
  this.executePinAndScroll(action.messageComponent, scrollElement);
13535
13561
  return;
13536
13562
 
@@ -14727,20 +14753,76 @@ function RequestScreenShareModal() {
14727
14753
  });
14728
14754
  }
14729
14755
 
14730
- function PanelHeader({title, showBackButton = true, labelBackButton, backButtonType = "minimize", onClickBack}) {
14731
- const toolbarActions = useMemo(() => showBackButton ? [ {
14732
- text: labelBackButton ?? "",
14733
- icon: backButtonType === "close" ? CloseLarge20 : ChevronDown20,
14734
- size: "md",
14735
- onClick: () => onClickBack?.()
14736
- } ] : [], [ backButtonType, labelBackButton, onClickBack, showBackButton ]);
14756
+ const IconButton = createComponent({
14757
+ tagName: "cds-icon-button",
14758
+ elementClass: CarbonIconButtonElement,
14759
+ react: React
14760
+ });
14761
+
14762
+ const ChevronDown = carbonIconToReact(ChevronDown16);
14763
+
14764
+ const ChevronLeft = carbonIconToReact(ChevronLeft16);
14765
+
14766
+ const CloseLarge = carbonIconToReact(CloseLarge16);
14767
+
14768
+ function PanelHeader({title, openFromSide, showBackButton = true, labelBackButton, backButtonType = "minimize", backButtonPosition = "end", onClickBack}) {
14769
+ const {backButtonIcon, BackButtonIcon} = useMemo(() => {
14770
+ const icons = {
14771
+ close: {
14772
+ iconDescriptor: CloseLarge16,
14773
+ IconComponent: CloseLarge
14774
+ },
14775
+ side: {
14776
+ iconDescriptor: ChevronLeft16,
14777
+ IconComponent: ChevronLeft
14778
+ },
14779
+ down: {
14780
+ iconDescriptor: ChevronDown16,
14781
+ IconComponent: ChevronDown
14782
+ }
14783
+ };
14784
+ const iconKey = backButtonType === "close" ? "close" : openFromSide ? "side" : "down";
14785
+ const selected = icons[iconKey];
14786
+ return {
14787
+ backButtonIcon: selected.iconDescriptor,
14788
+ BackButtonIcon: selected.IconComponent
14789
+ };
14790
+ }, [ backButtonType, openFromSide ]);
14791
+ const toolbarActions = useMemo(() => {
14792
+ if (!showBackButton || backButtonPosition === "start") {
14793
+ return [];
14794
+ }
14795
+ return [ {
14796
+ text: labelBackButton ?? "",
14797
+ icon: backButtonIcon,
14798
+ size: "md",
14799
+ onClick: () => onClickBack?.()
14800
+ } ];
14801
+ }, [ labelBackButton, onClickBack, showBackButton, backButtonPosition, backButtonIcon ]);
14802
+ const tooltipAlign = isDirectionRTL() ? "bottom-end" : "bottom-start";
14737
14803
  return React.createElement("div", {
14738
14804
  "data-floating-menu-container": true
14739
14805
  }, React.createElement(Toolbar, {
14740
14806
  actions: toolbarActions
14741
14807
  }, React.createElement("div", {
14742
14808
  slot: "title"
14743
- }, title)));
14809
+ }, title && React.createElement(MarkdownWithDefaultsExport, {
14810
+ text: title
14811
+ })), showBackButton && backButtonPosition === "start" && React.createElement("div", {
14812
+ slot: "navigation"
14813
+ }, React.createElement(IconButton, {
14814
+ "data-rounded": "top-left",
14815
+ size: "md",
14816
+ kind: BUTTON_KIND.GHOST,
14817
+ align: tooltipAlign,
14818
+ enterDelayMs: 0,
14819
+ leaveDelayMs: 0,
14820
+ onClick: () => onClickBack?.()
14821
+ }, React.createElement(BackButtonIcon, {
14822
+ slot: "icon"
14823
+ }), labelBackButton && React.createElement("span", {
14824
+ slot: "tooltip-content"
14825
+ }, labelBackButton)))));
14744
14826
  }
14745
14827
 
14746
14828
  const HydrationPanel = ({isHydrated, languagePack}) => React.createElement("div", {
@@ -15521,9 +15603,10 @@ const AppShellPanels = React.memo(function AppShellPanels({serviceManager, langu
15521
15603
  fullWidth: "fullWidth" in customPanelState.options && customPanelState.options.fullWidth ? true : false,
15522
15604
  showFrame: "showFrame" in customPanelState.options && customPanelState.options.showFrame ? true : false,
15523
15605
  aiEnabled: "aiEnabled" in customPanelState.options && customPanelState.options.aiEnabled ? true : false,
15524
- showChatHeader: !isLegacyCustomPanel,
15525
- animationOnOpen: customPanelState.options.disableAnimation ? "none" : "slide-in-from-bottom",
15526
- animationOnClose: customPanelState.options.disableAnimation ? "none" : "slide-out-to-bottom",
15606
+ showChatHeader: !isLegacyCustomPanel && "showChatHeader" in customPanelState.options && customPanelState.options.showChatHeader ? true : false,
15607
+ animationOnOpen: customPanelState.options.disableAnimation ? "none" : "openFromSide" in customPanelState.options && customPanelState.options.openFromSide ? "slide-in-from-start" : "slide-in-from-bottom",
15608
+ animationOnClose: customPanelState.options.disableAnimation ? "none" : "openFromSide" in customPanelState.options && customPanelState.options.openFromSide ? "slide-out-to-start" : "slide-out-to-bottom",
15609
+ openFromSide: "openFromSide" in customPanelState.options && customPanelState.options.openFromSide ? true : false,
15527
15610
  onOpenStart: () => {
15528
15611
  serviceManager.eventBus.fire({
15529
15612
  type: BusEventType.CUSTOM_PANEL_PRE_OPEN
@@ -15575,6 +15658,8 @@ const AppShellPanels = React.memo(function AppShellPanels({serviceManager, langu
15575
15658
  title: panelTitle,
15576
15659
  labelBackButton: languagePack.general_returnToAssistant,
15577
15660
  backButtonType: "backButtonType" in customPanelState.options ? customPanelState.options.backButtonType : undefined,
15661
+ backButtonPosition: "backButtonPosition" in customPanelState.options ? customPanelState.options.backButtonPosition : undefined,
15662
+ openFromSide: "openFromSide" in customPanelState.options && customPanelState.options.openFromSide,
15578
15663
  onClickBack: () => {
15579
15664
  serviceManager.store.dispatch(actions.setCustomPanelOpen(false));
15580
15665
  "onClickBack" in customPanelState.options && customPanelState.options.onClickBack?.();