@patternfly/chatbot 6.5.0 → 6.6.0-prerelease.1

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.
@@ -40,6 +40,8 @@ export interface MessageBarProps extends Omit<TextAreaProps, 'innerRef'> {
40
40
  placeholder?: string;
41
41
  /** Flag to disable/enable the Attach button */
42
42
  hasAttachButton?: boolean;
43
+ /** Whether the attach button is rendered before or after the message input. */
44
+ attachButtonPosition?: 'start' | 'end';
43
45
  /** Flag to enable the Microphone button */
44
46
  hasMicrophoneButton?: boolean;
45
47
  /** Placeholder text when listening */
@@ -111,6 +113,10 @@ export interface MessageBarProps extends Omit<TextAreaProps, 'innerRef'> {
111
113
  innerRef?: React.Ref<HTMLTextAreaElement>;
112
114
  /** Sets background color to primary */
113
115
  isPrimary?: boolean;
116
+ /** Additional actions to render for the message bar. This will force a multiline layout, and the actions will render at the start of the container. */
117
+ additionalActions?: React.ReactNode;
118
+ /** Flag indicating whether a multiline layout for the message input and actions should be forced. This can be used to always render actions below the message input. */
119
+ forceMultilineLayout?: boolean;
114
120
  /** @beta Flag indicating whether the message bar has an AI indicator border. */
115
121
  hasAiIndicator?: boolean;
116
122
  /** @beta Flag indicating whether the chatbot is thinking in response to a query, adding an animation to the message bar. */
@@ -27,18 +27,24 @@ const AttachMenu_1 = __importDefault(require("../AttachMenu"));
27
27
  const StopButton_1 = __importDefault(require("./StopButton"));
28
28
  const MessageBarBase = (_a) => {
29
29
  var _b;
30
- var { onSendMessage, className, alwayShowSendButton, placeholder = 'Send a message...', hasAttachButton = true, hasMicrophoneButton, listeningText = 'Listening', handleAttach, attachMenuProps, isSendButtonDisabled, handleStopButton, hasStopButton, buttonProps, onChange, displayMode, value, isCompact = false, allowedFileTypes, minSize, maxSize, maxFiles, isAttachmentDisabled, onAttach, onAttachRejected, validator, dropzoneProps, innerRef, isPrimary, hasAiIndicator, isThinking } = _a, props = __rest(_a, ["onSendMessage", "className", "alwayShowSendButton", "placeholder", "hasAttachButton", "hasMicrophoneButton", "listeningText", "handleAttach", "attachMenuProps", "isSendButtonDisabled", "handleStopButton", "hasStopButton", "buttonProps", "onChange", "displayMode", "value", "isCompact", "allowedFileTypes", "minSize", "maxSize", "maxFiles", "isAttachmentDisabled", "onAttach", "onAttachRejected", "validator", "dropzoneProps", "innerRef", "isPrimary", "hasAiIndicator", "isThinking"]);
30
+ var { onSendMessage, className, alwayShowSendButton, placeholder = 'Send a message...', hasAttachButton = true, attachButtonPosition = 'end', hasMicrophoneButton, listeningText = 'Listening', handleAttach, attachMenuProps, isSendButtonDisabled, handleStopButton, hasStopButton, buttonProps, onChange, displayMode, value, isCompact = false, allowedFileTypes, minSize, maxSize, maxFiles, isAttachmentDisabled, onAttach, onAttachRejected, validator, dropzoneProps, innerRef, isPrimary, additionalActions, forceMultilineLayout = false, hasAiIndicator, isThinking } = _a, props = __rest(_a, ["onSendMessage", "className", "alwayShowSendButton", "placeholder", "hasAttachButton", "attachButtonPosition", "hasMicrophoneButton", "listeningText", "handleAttach", "attachMenuProps", "isSendButtonDisabled", "handleStopButton", "hasStopButton", "buttonProps", "onChange", "displayMode", "value", "isCompact", "allowedFileTypes", "minSize", "maxSize", "maxFiles", "isAttachmentDisabled", "onAttach", "onAttachRejected", "validator", "dropzoneProps", "innerRef", "isPrimary", "additionalActions", "forceMultilineLayout", "hasAiIndicator", "isThinking"]);
31
31
  // Text Input
32
32
  // --------------------------------------------------------------------------
33
33
  const [message, setMessage] = (0, react_1.useState)(value !== null && value !== void 0 ? value : '');
34
34
  const [isListeningMessage, setIsListeningMessage] = (0, react_1.useState)(false);
35
35
  const [hasSentMessage, setHasSentMessage] = (0, react_1.useState)(false);
36
36
  const [isComposing, setIsComposing] = (0, react_1.useState)(false);
37
- const [isMultiline, setIsMultiline] = (0, react_1.useState)(false);
37
+ const shouldForceMultiline = forceMultilineLayout || additionalActions;
38
+ const [isMultiline, setIsMultiline] = (0, react_1.useState)(shouldForceMultiline);
38
39
  const inputRef = (0, react_1.useRef)(null);
39
40
  const textareaRef = (_b = innerRef) !== null && _b !== void 0 ? _b : inputRef;
40
41
  const attachButtonRef = (0, react_1.useRef)(null);
41
42
  const topMargin = '1rem';
43
+ (0, react_1.useEffect)(() => {
44
+ if (value !== undefined && value !== message) {
45
+ setMessage(value);
46
+ }
47
+ }, [value, message]);
42
48
  const setInitialLineHeight = (field) => {
43
49
  field.style.setProperty('line-height', '1rem');
44
50
  const parent = field.parentElement;
@@ -48,7 +54,7 @@ const MessageBarBase = (_a) => {
48
54
  parent.style.setProperty('height', 'inherit');
49
55
  const grandparent = parent.parentElement;
50
56
  if (grandparent) {
51
- grandparent.style.setProperty('flex-basis', 'auto');
57
+ grandparent.style.setProperty('flex-basis', shouldForceMultiline ? '100%' : 'auto');
52
58
  }
53
59
  }
54
60
  };
@@ -88,7 +94,7 @@ const MessageBarBase = (_a) => {
88
94
  const parent = field.parentElement;
89
95
  if (parent) {
90
96
  const grandparent = parent.parentElement;
91
- if (textIsLongerThan2Lines(field) && grandparent) {
97
+ if ((textIsLongerThan2Lines(field) || shouldForceMultiline) && grandparent) {
92
98
  grandparent.style.setProperty('flex-basis', `100%`);
93
99
  }
94
100
  }
@@ -136,15 +142,15 @@ const MessageBarBase = (_a) => {
136
142
  if (field) {
137
143
  if (field.value === '') {
138
144
  setInitialLineHeight(field);
139
- setIsMultiline(false);
145
+ !shouldForceMultiline && setIsMultiline(false);
140
146
  }
141
147
  else {
142
148
  setAutoHeight(field);
143
149
  setAutoWidth(field);
144
- checkIfMultiline(field);
150
+ !shouldForceMultiline && checkIfMultiline(field);
145
151
  }
146
152
  }
147
- }, [displayMode, message, setAutoWidth, checkIfMultiline]);
153
+ }, [displayMode, message, setAutoWidth, shouldForceMultiline, checkIfMultiline]);
148
154
  (0, react_1.useEffect)(() => {
149
155
  const field = textareaRef.current;
150
156
  if (field) {
@@ -157,11 +163,11 @@ const MessageBarBase = (_a) => {
157
163
  if (textareaRef.current) {
158
164
  if (event.target.value === '') {
159
165
  setInitialLineHeight(textareaRef.current);
160
- setIsMultiline(false);
166
+ !shouldForceMultiline && setIsMultiline(false);
161
167
  }
162
168
  else {
163
169
  setAutoHeight(textareaRef.current);
164
- checkIfMultiline(textareaRef.current);
170
+ !shouldForceMultiline && checkIfMultiline(textareaRef.current);
165
171
  }
166
172
  }
167
173
  setMessage(event.target.value);
@@ -207,14 +213,25 @@ const MessageBarBase = (_a) => {
207
213
  setMessage(message);
208
214
  onChange && onChange({}, message);
209
215
  };
216
+ const renderAttachButton = () => {
217
+ var _a, _b, _c, _d, _e, _f;
218
+ if (!attachMenuProps && hasAttachButton) {
219
+ return ((0, jsx_runtime_1.jsx)(AttachButton_1.AttachButton, Object.assign({ onAttachAccepted: handleAttach, isDisabled: isListeningMessage, tooltipContent: (_a = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _a === void 0 ? void 0 : _a.tooltipContent, inputTestId: (_b = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _b === void 0 ? void 0 : _b.inputTestId, isCompact: isCompact, tooltipProps: (_c = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _c === void 0 ? void 0 : _c.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach, (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _d === void 0 ? void 0 : _d.props)));
220
+ }
221
+ if (attachMenuProps) {
222
+ return ((0, jsx_runtime_1.jsx)(AttachButton_1.AttachButton, Object.assign({ ref: attachButtonRef, onClick: handleAttachMenuToggle, isDisabled: isListeningMessage, tooltipContent: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _e === void 0 ? void 0 : _e.tooltipContent, isCompact: isCompact, tooltipProps: (_f = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _f === void 0 ? void 0 : _f.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach)));
223
+ }
224
+ };
225
+ const isAttachButtonAtStart = attachButtonPosition === 'start';
210
226
  const renderButtons = () => {
211
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
227
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
212
228
  if (hasStopButton && handleStopButton) {
213
229
  return ((0, jsx_runtime_1.jsx)(StopButton_1.default, Object.assign({ onClick: handleStopButton, tooltipContent: (_a = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _a === void 0 ? void 0 : _a.tooltipContent, isCompact: isCompact, tooltipProps: (_b = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _b === void 0 ? void 0 : _b.tooltipProps }, (_c = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _c === void 0 ? void 0 : _c.props)));
214
230
  }
215
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [attachMenuProps && ((0, jsx_runtime_1.jsx)(AttachButton_1.AttachButton, Object.assign({ ref: attachButtonRef, onClick: handleAttachMenuToggle, isDisabled: isListeningMessage, tooltipContent: (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _d === void 0 ? void 0 : _d.tooltipContent, isCompact: isCompact, tooltipProps: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _e === void 0 ? void 0 : _e.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach))), !attachMenuProps && hasAttachButton && ((0, jsx_runtime_1.jsx)(AttachButton_1.AttachButton, Object.assign({ onAttachAccepted: handleAttach, isDisabled: isListeningMessage, tooltipContent: (_f = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _f === void 0 ? void 0 : _f.tooltipContent, inputTestId: (_g = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _g === void 0 ? void 0 : _g.inputTestId, isCompact: isCompact, tooltipProps: (_h = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _h === void 0 ? void 0 : _h.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach, (_j = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _j === void 0 ? void 0 : _j.props))), hasMicrophoneButton && ((0, jsx_runtime_1.jsx)(MicrophoneButton_1.default, Object.assign({ isListening: isListeningMessage, onIsListeningChange: setIsListeningMessage, onSpeechRecognition: handleSpeechRecognition, tooltipContent: (_k = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _k === void 0 ? void 0 : _k.tooltipContent, language: (_l = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _l === void 0 ? void 0 : _l.language, isCompact: isCompact, tooltipProps: (_m = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _m === void 0 ? void 0 : _m.tooltipProps }, (_o = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _o === void 0 ? void 0 : _o.props))), (alwayShowSendButton || message) && ((0, jsx_runtime_1.jsx)(SendButton_1.default, Object.assign({ value: message, onClick: () => handleSend(message), isDisabled: isSendButtonDisabled, tooltipContent: (_p = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _p === void 0 ? void 0 : _p.tooltipContent, isCompact: isCompact, tooltipProps: (_q = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _q === void 0 ? void 0 : _q.tooltipProps }, (_r = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _r === void 0 ? void 0 : _r.props)))] }));
231
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!isAttachButtonAtStart && renderAttachButton(), hasMicrophoneButton && ((0, jsx_runtime_1.jsx)(MicrophoneButton_1.default, Object.assign({ isListening: isListeningMessage, onIsListeningChange: setIsListeningMessage, onSpeechRecognition: handleSpeechRecognition, tooltipContent: (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _d === void 0 ? void 0 : _d.tooltipContent, language: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _e === void 0 ? void 0 : _e.language, isCompact: isCompact, tooltipProps: (_f = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _f === void 0 ? void 0 : _f.tooltipProps }, (_g = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _g === void 0 ? void 0 : _g.props))), (alwayShowSendButton || message) && ((0, jsx_runtime_1.jsx)(SendButton_1.default, Object.assign({ value: message, onClick: () => handleSend(message), isDisabled: isSendButtonDisabled, tooltipContent: (_h = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _h === void 0 ? void 0 : _h.tooltipContent, isCompact: isCompact, tooltipProps: (_j = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _j === void 0 ? void 0 : _j.tooltipProps }, (_k = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _k === void 0 ? void 0 : _k.props)))] }));
216
232
  };
217
- const messageBarContents = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `pf-chatbot__message-bar-input ${isCompact ? 'pf-m-compact' : ''}`, children: (0, jsx_runtime_1.jsx)(react_core_1.TextArea, Object.assign({ className: "pf-chatbot__message-textarea", value: message, onChange: handleChange, "aria-label": isListeningMessage ? listeningText : placeholder, placeholder: isListeningMessage ? listeningText : placeholder, ref: textareaRef, onKeyDown: handleKeyDown, onCompositionStart: handleCompositionStart, onCompositionEnd: handleCompositionEnd }, props)) }), (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-bar-actions", children: renderButtons() })] }));
233
+ const hasGroupedActions = additionalActions || (isAttachButtonAtStart && isMultiline);
234
+ const messageBarContents = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isAttachButtonAtStart && !isMultiline && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-bar-actions test", children: renderAttachButton() })), (0, jsx_runtime_1.jsx)("div", { className: `pf-chatbot__message-bar-input ${isCompact ? 'pf-m-compact' : ''}`, children: (0, jsx_runtime_1.jsx)(react_core_1.TextArea, Object.assign({ className: "pf-chatbot__message-textarea", value: message, onChange: handleChange, "aria-label": isListeningMessage ? listeningText : placeholder, placeholder: isListeningMessage ? listeningText : placeholder, ref: textareaRef, onKeyDown: handleKeyDown, onCompositionStart: handleCompositionStart, onCompositionEnd: handleCompositionEnd }, props)) }), (0, jsx_runtime_1.jsx)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-bar-actions', hasGroupedActions && 'pf-m-grouped'), children: hasGroupedActions ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-bar-actions-group'), children: [isAttachButtonAtStart && renderAttachButton(), additionalActions] }), (0, jsx_runtime_1.jsx)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-bar-actions-group'), children: renderButtons() })] })) : (renderButtons()) })] }));
218
235
  if (attachMenuProps) {
219
236
  return ((0, jsx_runtime_1.jsx)(AttachMenu_1.default, Object.assign({ toggle: (toggleRef) => ((0, jsx_runtime_1.jsx)("div", { ref: toggleRef, className: (0, react_styles_1.css)('pf-chatbot__message-bar', isMultiline && 'pf-m-multiline', className), children: messageBarContents })), filteredItems: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.attachMenuItems }, (attachMenuProps && { isOpen: attachMenuProps.isAttachMenuOpen }), { onOpenChange: (isAttachMenuOpen) => {
220
237
  var _a;
@@ -331,4 +331,16 @@ describe('Message bar', () => {
331
331
  (0, react_1.render)((0, jsx_runtime_1.jsx)(MessageBar_1.MessageBar, { onSendMessage: jest.fn, isThinking: true }));
332
332
  expect(react_1.screen.getByRole('textbox').closest('.pf-chatbot__message-bar')).toHaveClass('pf-v6-m-thinking');
333
333
  });
334
+ it('Renders with flex-basis of auto by default', () => {
335
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(MessageBar_1.MessageBar, { onSendMessage: jest.fn }));
336
+ expect(react_1.screen.getByRole('textbox').closest('.pf-chatbot__message-bar-input')).toHaveAttribute('style', 'flex-basis: auto;');
337
+ });
338
+ it('Renders with flex-basis of 100% when forceMultilineLayout is true', () => {
339
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(MessageBar_1.MessageBar, { forceMultilineLayout: true, onSendMessage: jest.fn }));
340
+ expect(react_1.screen.getByRole('textbox').closest('.pf-chatbot__message-bar-input')).toHaveAttribute('style', 'flex-basis: 100%;');
341
+ });
342
+ it('Renders with flex-basis of 100% when additionalActions is truthy', () => {
343
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(MessageBar_1.MessageBar, { additionalActions: "actions", onSendMessage: jest.fn }));
344
+ expect(react_1.screen.getByRole('textbox').closest('.pf-chatbot__message-bar-input')).toHaveAttribute('style', 'flex-basis: 100%;');
345
+ });
334
346
  });
package/dist/css/main.css CHANGED
@@ -2262,6 +2262,17 @@ li[id*=user-content-fn-]:has(> span > span > .pf-chatbot__message-text + .pf-cha
2262
2262
  padding-block-end: var(--pf-t--global--spacer--xs);
2263
2263
  gap: var(--pf-t--global--spacer--gap--action-to-action--plain);
2264
2264
  }
2265
+ .pf-chatbot__message-bar-actions.pf-m-grouped {
2266
+ flex-basis: 100%;
2267
+ justify-content: space-between;
2268
+ }
2269
+ .pf-chatbot__message-bar-actions-group {
2270
+ display: flex;
2271
+ padding-block-start: var(--pf-t--global--spacer--xs);
2272
+ padding-block-end: var(--pf-t--global--spacer--xs);
2273
+ gap: var(--pf-t--global--spacer--gap--action-to-action--plain);
2274
+ align-items: center;
2275
+ }
2265
2276
  .pf-chatbot__message-bar-input {
2266
2277
  flex: 1 1 auto;
2267
2278
  padding-block-start: var(--pf-t--global--spacer--sm);
@@ -2334,7 +2345,8 @@ li[id*=user-content-fn-]:has(> span > span > .pf-chatbot__message-text + .pf-cha
2334
2345
  font-size: var(--pf-t--global--font--size--sm) !important;
2335
2346
  }
2336
2347
 
2337
- .pf-m-compact .pf-chatbot__message-bar-actions {
2348
+ .pf-m-compact .pf-chatbot__message-bar-actions,
2349
+ .pf-m-compact .pf-chatbot__message-bar-actions-group {
2338
2350
  padding-block-start: var(--pf-t--global--spacer--sm);
2339
2351
  padding-block-end: var(--pf-t--global--spacer--sm);
2340
2352
  }
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../../src/AttachMenu/AttachMenu.scss","../../src/Chatbot/Chatbot.scss","../../src/ChatbotAlert/ChatbotAlert.scss","../../src/ChatbotContent/ChatbotContent.scss","../../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss","../../src/ChatbotFooter/ChatbotFootnote.scss","../../src/ChatbotFooter/ChatbotFooter.scss","../../src/ChatbotHeader/ChatbotHeader.scss","../../src/ChatbotModal/ChatbotModal.scss","../../src/ChatbotPopover/ChatbotPopover.scss","../../src/ChatbotToggle/ChatbotToggle.scss","../../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss","../../src/CodeModal/CodeModal.scss","../../src/Compare/Compare.scss","../../src/DeepThinking/DeepThinking.scss","../../src/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/FilePreview/FilePreview.scss","../../src/ImagePreview/ImagePreview.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/SuperscriptMessage/SuperscriptMessage.scss","../../src/Message/ImageMessage/ImageMessage.scss","../../src/Message/LinkMessage/LinkMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/Message/TableMessage/TableMessage.scss","../../src/Message/QuickStarts/QuickStartTile.scss","../../src/Message/QuickResponse/QuickResponse.scss","../../src/Message/UserFeedback/UserFeedback.scss","../../src/MessageBar/AttachButton.scss","../../src/MessageBar/MicrophoneButton.scss","../../src/MessageBar/SendButton.scss","../../src/MessageBar/StopButton.scss","../../src/MessageBar/MessageBar.scss","../../src/MessageBox/JumpButton.scss","../../src/MessageBox/MessageBox.scss","../../src/MessageDivider/MessageDivider.scss","../../src/Onboarding/Onboarding.scss","../../src/ResponseActions/ResponseActions.scss","../../src/Settings/Settings.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/TermsOfUse/TermsOfUse.scss","../../src/ToolResponse/ToolResponse.scss","../../src/ToolCall/ToolCall.scss","../../src/main.scss"],"names":[],"mappings":";AAAA;EACE;EACA;;;AAGF;AACE;AAsBA;AASA;;AA9BA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;AACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACxDJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAYF;;AAVA;EACE;EACA;EACA;;AAEF;EACE;EACA;;AAQF;EAjCF;IAkCI;IACA;;;AAIF;EAvCF;IAwCI;;;;AAOJ;EAEE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAfF;IAgBI;;;;AAOJ;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EAEE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAdF;IAgBI;;;;AAMF;EACE;;;AAOJ;EACE;;;ACjKF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;AAGF;EACE;;;AAOJ;EAII;AAAA;AAAA;IACE;IACA;;;ACzBJ;EACE;EACA;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAKA;EACE;EACA;;AAIJ;EACE;;AAKF;EACE;EACA;EAEA;EACA;EACA;;AAEF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AAIF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AAGF;EACE;;;AAMJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAKA;EACE;;;AASJ;EACE;;;AASF;AAAA;EACE;;AACA;AAAA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AAUF;AAAA;AAAA;AAAA;EACE;;;AAKN;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAKE;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;;ACvSN;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAGJ;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;IACA;;;AASJ;EACE;;;AAQF;EACE;;;AAIJ;EACE;EACA;;;AAQA;EAIM;AAAA;IACE;;;;AC5EV;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AAUJ;AAAA;EACE;;;AAOJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAOJ;EACE;;;AAOJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;AAOA;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;AAAA;EAEE;EACA;;;AAGF;EACE;;;AAQA;EAGI;AAAA;IACE;;;;AClLR;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;AAIF;EACE;;;AAOJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAGJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAOJ;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAQE;EACE;;;AAQN;EACE;;;AAOA;EACE;;AAGF;EACE;EACA;;;ACpGF;EACE;;AAMA;EACE;;AAEF;EACE;;AAEF;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACxBN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAIF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AC3BF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;;AAEA;EACE;;;AAOJ;EAIM;AAAA;IACE;IACA;;;ACpDN;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;AAAA;AAAA;EAGA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAGA;EACE;;;AAUF;EACE;EACA;;;AAKN;EACE;;;AAGF;EACE;;;AAIA;EACE;;;AC9FJ;EACE;EACA;EACA;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;;AAEA;EALF;IAMI;;;AAGF;EACE;;AAEA;EAHF;IAII;;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAIA;EADF;IAEI;;;;AAIN;EACE;;AAEA;EAHF;IAII;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;;ACrEJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;ACtBF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACjCF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;EAEE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;;;AAMF;AAAA;EACE;;;AC/DJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;AAGA;EANF;IAOI;;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AAME;EADF;IAEI;IACA;IACA;;EAEA;IACE;;;;ACnDR;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAEF;EACE;EACA;;;ACpBF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;ACvDJ;EACE;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;;AAGF;EAKE;;AAJA;EACE;EACA;;AAOJ;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAGA;EACE;EAQA;EACA;;AAIF;EACE;EACA;;AAIF;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIF;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;EACA;EACA;EACA;EACA;EACA;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAQE;;AAIJ;EACE;;;AAMJ;EACE;EACA;EACA;;;AAGF;EACE;;;AChJF;EACE;EACA;EACA;EACA;EAEA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;AAIJ;EACE;;;ACtDJ;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;;AAIJ;EACE;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;EACA;;;ACrGJ;EACE;;AAGE;EACE;;;AAMN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAIJ;EACE;;AAEF;EACE;EACA;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;;AAGF;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AC/IN;EACE;EACA;;AACA;EACE;EACA;;;AJ0JF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;;AAIA;EACE;EACA;;AAIJ;EACE;;;AEjLJ;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;;AAIJ;EACE;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;EACA;;;AGzGJ;EACE;EACA;EACA;EACA;EAGA;;;ACNA;EACE;;;AHEJ;EACE;;AAGE;EACE;;;AAMN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAIJ;EACE;;AAEF;EACE;EACA;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;;AAGF;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AI3IN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAMJ;AAAA;EAEE;EACA;EACA;;AAGA;AAAA;EACE;;AAMF;EACE;EACA;;AAIJ;EACE;;;AC/CJ;EACE;EACA;EACA;EAEA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;;APhCN;EACE;EACA;EACA;EACA;EAEA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;AAIJ;EACE;;;AQzDJ;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;AClBF;EACE;;AAGF;EALF;IAMI;;;AAGF;EATF;IAUI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC/BJ;EACE;EAEA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAKA;EACE;;;AAGJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;;;AAMJ;EACE;;AAGF;EACE;;AAIA;EACE;;;AC/FN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;;;ACxCF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AAOJ;EACE;EACA;EACA;;;ACpDF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;EACA;;AAEA;EACE;;;AAMJ;EACE;;AACA;EACE;;AAIJ;EACE;EACA;;AAGF;AAAA;EAEE;;;AAIJ;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AAOJ;EACE;EACA;EACA;;;ACzDF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;;;ACjCF;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,YACE;;AAKF;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;IACE;IACA;;;AAKF;EACE;IACE;IACA;;;;AAQN;EACE;EACA;;AAEA;EACE;;;AAKF;EACE;EACA;;;AAOJ;EACE;;;AAQE;EACE;;;ACvKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AC9CJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIA;EAVF;IAWI;;;AAGF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;EAII;AAAA;AAAA;IACE;IACA;;;AAMJ;EACE;;;ACnCJ;EACE;EACA;;AAEA;AAAA;EAEE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKF;EACE;EACA;EAEA;;AAGF;EACE;;AAKF;AAAA;EAEE;;;AFrCN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AGhDJ;EACE;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;;AAIF;EACE;IACE;IACA;;;;AASF;AAAA;AAAA;EACE;EACA;;;AAKN;AAAA;EAGE;;AAEA;AAAA;EACE;;;AAKF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AClGJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;;ACrCF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAIA;EACE;EACA;;;AAIJ;EACE;;;AC3CF;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAIA;EACE;EACA;EACA;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;AAON;EACE;EACA;;;ACpGJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AC9BA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAIF;EACE;IACE;IACA;;;;AAKN;AAAA;EAGE;;AAGE;AAAA;EACE;;AAIJ;AAAA;EACE;;;AAKF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;;ACnFJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAIA;EACE;;;AC3CJ;EACE;EACA;EAEA;EACA;;AAEA;EACE;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;;ACWJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA","file":"main.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../../src/AttachMenu/AttachMenu.scss","../../src/Chatbot/Chatbot.scss","../../src/ChatbotAlert/ChatbotAlert.scss","../../src/ChatbotContent/ChatbotContent.scss","../../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss","../../src/ChatbotFooter/ChatbotFootnote.scss","../../src/ChatbotFooter/ChatbotFooter.scss","../../src/ChatbotHeader/ChatbotHeader.scss","../../src/ChatbotModal/ChatbotModal.scss","../../src/ChatbotPopover/ChatbotPopover.scss","../../src/ChatbotToggle/ChatbotToggle.scss","../../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss","../../src/CodeModal/CodeModal.scss","../../src/Compare/Compare.scss","../../src/DeepThinking/DeepThinking.scss","../../src/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/FilePreview/FilePreview.scss","../../src/ImagePreview/ImagePreview.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/SuperscriptMessage/SuperscriptMessage.scss","../../src/Message/ImageMessage/ImageMessage.scss","../../src/Message/LinkMessage/LinkMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/Message/TableMessage/TableMessage.scss","../../src/Message/QuickStarts/QuickStartTile.scss","../../src/Message/QuickResponse/QuickResponse.scss","../../src/Message/UserFeedback/UserFeedback.scss","../../src/MessageBar/AttachButton.scss","../../src/MessageBar/MicrophoneButton.scss","../../src/MessageBar/SendButton.scss","../../src/MessageBar/StopButton.scss","../../src/MessageBar/MessageBar.scss","../../src/MessageBox/JumpButton.scss","../../src/MessageBox/MessageBox.scss","../../src/MessageDivider/MessageDivider.scss","../../src/Onboarding/Onboarding.scss","../../src/ResponseActions/ResponseActions.scss","../../src/Settings/Settings.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/TermsOfUse/TermsOfUse.scss","../../src/ToolResponse/ToolResponse.scss","../../src/ToolCall/ToolCall.scss","../../src/main.scss"],"names":[],"mappings":";AAAA;EACE;EACA;;;AAGF;AACE;AAsBA;AASA;;AA9BA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;AACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACxDJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAYF;;AAVA;EACE;EACA;EACA;;AAEF;EACE;EACA;;AAQF;EAjCF;IAkCI;IACA;;;AAIF;EAvCF;IAwCI;;;;AAOJ;EAEE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAfF;IAgBI;;;;AAOJ;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EAEE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAdF;IAgBI;;;;AAMF;EACE;;;AAOJ;EACE;;;ACjKF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;AAGF;EACE;;;AAOJ;EAII;AAAA;AAAA;IACE;IACA;;;ACzBJ;EACE;EACA;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAKA;EACE;EACA;;AAIJ;EACE;;AAKF;EACE;EACA;EAEA;EACA;EACA;;AAEF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AAIF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AAGF;EACE;;;AAMJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAKA;EACE;;;AASJ;EACE;;;AASF;AAAA;EACE;;AACA;AAAA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AAUF;AAAA;AAAA;AAAA;EACE;;;AAKN;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAKE;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;;ACvSN;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAGJ;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;IACA;;;AASJ;EACE;;;AAQF;EACE;;;AAIJ;EACE;EACA;;;AAQA;EAIM;AAAA;IACE;;;;AC5EV;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AAUJ;AAAA;EACE;;;AAOJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAOJ;EACE;;;AAOJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;AAOA;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;AAAA;EAEE;EACA;;;AAGF;EACE;;;AAQA;EAGI;AAAA;IACE;;;;AClLR;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;AAIF;EACE;;;AAOJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAGJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAOJ;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAQE;EACE;;;AAQN;EACE;;;AAOA;EACE;;AAGF;EACE;EACA;;;ACpGF;EACE;;AAMA;EACE;;AAEF;EACE;;AAEF;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACxBN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAIF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AC3BF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;;AAEA;EACE;;;AAOJ;EAIM;AAAA;IACE;IACA;;;ACpDN;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;AAAA;AAAA;EAGA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAGA;EACE;;;AAUF;EACE;EACA;;;AAKN;EACE;;;AAGF;EACE;;;AAIA;EACE;;;AC9FJ;EACE;EACA;EACA;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;;AAEA;EALF;IAMI;;;AAGF;EACE;;AAEA;EAHF;IAII;;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAIA;EADF;IAEI;;;;AAIN;EACE;;AAEA;EAHF;IAII;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;;ACrEJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;ACtBF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACjCF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;EAEE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;;;AAMF;AAAA;EACE;;;AC/DJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;AAGA;EANF;IAOI;;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AAME;EADF;IAEI;IACA;IACA;;EAEA;IACE;;;;ACnDR;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAEF;EACE;EACA;;;ACpBF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;ACvDJ;EACE;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;;AAGF;EAKE;;AAJA;EACE;EACA;;AAOJ;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAGA;EACE;EAQA;EACA;;AAIF;EACE;EACA;;AAIF;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIF;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;EACA;EACA;EACA;EACA;EACA;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAQE;;AAIJ;EACE;;;AAMJ;EACE;EACA;EACA;;;AAGF;EACE;;;AChJF;EACE;EACA;EACA;EACA;EAEA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;AAIJ;EACE;;;ACtDJ;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;;AAIJ;EACE;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;EACA;;;ACrGJ;EACE;;AAGE;EACE;;;AAMN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAIJ;EACE;;AAEF;EACE;EACA;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;;AAGF;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AC/IN;EACE;EACA;;AACA;EACE;EACA;;;AJ0JF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;;AAIA;EACE;EACA;;AAIJ;EACE;;;AEjLJ;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;;AAIJ;EACE;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;EACA;;;AGzGJ;EACE;EACA;EACA;EACA;EAGA;;;ACNA;EACE;;;AHEJ;EACE;;AAGE;EACE;;;AAMN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAIJ;EACE;;AAEF;EACE;EACA;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;;AAGF;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AI3IN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAMJ;AAAA;EAEE;EACA;EACA;;AAGA;AAAA;EACE;;AAMF;EACE;EACA;;AAIJ;EACE;;;AC/CJ;EACE;EACA;EACA;EAEA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;;APhCN;EACE;EACA;EACA;EACA;EAEA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;AAIJ;EACE;;;AQzDJ;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;AClBF;EACE;;AAGF;EALF;IAMI;;;AAGF;EATF;IAUI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC/BJ;EACE;EAEA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAKA;EACE;;;AAGJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;;;AAMJ;EACE;;AAGF;EACE;;AAIA;EACE;;;AC/FN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;;;ACxCF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AAOJ;EACE;EACA;EACA;;;ACpDF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;EACA;;AAEA;EACE;;;AAMJ;EACE;;AACA;EACE;;AAIJ;EACE;EACA;;AAGF;AAAA;EAEE;;;AAIJ;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AAOJ;EACE;EACA;EACA;;;ACzDF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;;;ACjCF;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,YACE;;AAKF;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;IACE;IACA;;;AAKF;EACE;IACE;IACA;;;;AAQN;EACE;EACA;;AAEA;EACE;;;AAKF;AAAA;EAEE;EACA;;;AAOJ;EACE;;;AAQE;EACE;;;ACrLN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AC9CJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIA;EAVF;IAWI;;;AAGF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;EAII;AAAA;AAAA;IACE;IACA;;;AAMJ;EACE;;;ACnCJ;EACE;EACA;;AAEA;AAAA;EAEE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKF;EACE;EACA;EAEA;;AAGF;EACE;;AAKF;AAAA;EAEE;;;AFrCN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AGhDJ;EACE;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;;AAIF;EACE;IACE;IACA;;;;AASF;AAAA;AAAA;EACE;EACA;;;AAKN;AAAA;EAGE;;AAEA;AAAA;EACE;;;AAKF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AClGJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;;ACrCF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAIA;EACE;EACA;;;AAIJ;EACE;;;AC3CF;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAIA;EACE;EACA;EACA;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;AAON;EACE;EACA;;;ACpGJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AC9BA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAIF;EACE;IACE;IACA;;;;AAKN;AAAA;EAGE;;AAGE;AAAA;EACE;;AAIJ;AAAA;EACE;;;AAKF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;;ACnFJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAIA;EACE;;;AC3CJ;EACE;EACA;EAEA;EACA;;AAEA;EACE;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;;ACWJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA","file":"main.css"}
@@ -40,6 +40,8 @@ export interface MessageBarProps extends Omit<TextAreaProps, 'innerRef'> {
40
40
  placeholder?: string;
41
41
  /** Flag to disable/enable the Attach button */
42
42
  hasAttachButton?: boolean;
43
+ /** Whether the attach button is rendered before or after the message input. */
44
+ attachButtonPosition?: 'start' | 'end';
43
45
  /** Flag to enable the Microphone button */
44
46
  hasMicrophoneButton?: boolean;
45
47
  /** Placeholder text when listening */
@@ -111,6 +113,10 @@ export interface MessageBarProps extends Omit<TextAreaProps, 'innerRef'> {
111
113
  innerRef?: React.Ref<HTMLTextAreaElement>;
112
114
  /** Sets background color to primary */
113
115
  isPrimary?: boolean;
116
+ /** Additional actions to render for the message bar. This will force a multiline layout, and the actions will render at the start of the container. */
117
+ additionalActions?: React.ReactNode;
118
+ /** Flag indicating whether a multiline layout for the message input and actions should be forced. This can be used to always render actions below the message input. */
119
+ forceMultilineLayout?: boolean;
114
120
  /** @beta Flag indicating whether the message bar has an AI indicator border. */
115
121
  hasAiIndicator?: boolean;
116
122
  /** @beta Flag indicating whether the chatbot is thinking in response to a query, adding an animation to the message bar. */
@@ -21,18 +21,24 @@ import AttachMenu from '../AttachMenu';
21
21
  import StopButton from './StopButton';
22
22
  export const MessageBarBase = (_a) => {
23
23
  var _b;
24
- var { onSendMessage, className, alwayShowSendButton, placeholder = 'Send a message...', hasAttachButton = true, hasMicrophoneButton, listeningText = 'Listening', handleAttach, attachMenuProps, isSendButtonDisabled, handleStopButton, hasStopButton, buttonProps, onChange, displayMode, value, isCompact = false, allowedFileTypes, minSize, maxSize, maxFiles, isAttachmentDisabled, onAttach, onAttachRejected, validator, dropzoneProps, innerRef, isPrimary, hasAiIndicator, isThinking } = _a, props = __rest(_a, ["onSendMessage", "className", "alwayShowSendButton", "placeholder", "hasAttachButton", "hasMicrophoneButton", "listeningText", "handleAttach", "attachMenuProps", "isSendButtonDisabled", "handleStopButton", "hasStopButton", "buttonProps", "onChange", "displayMode", "value", "isCompact", "allowedFileTypes", "minSize", "maxSize", "maxFiles", "isAttachmentDisabled", "onAttach", "onAttachRejected", "validator", "dropzoneProps", "innerRef", "isPrimary", "hasAiIndicator", "isThinking"]);
24
+ var { onSendMessage, className, alwayShowSendButton, placeholder = 'Send a message...', hasAttachButton = true, attachButtonPosition = 'end', hasMicrophoneButton, listeningText = 'Listening', handleAttach, attachMenuProps, isSendButtonDisabled, handleStopButton, hasStopButton, buttonProps, onChange, displayMode, value, isCompact = false, allowedFileTypes, minSize, maxSize, maxFiles, isAttachmentDisabled, onAttach, onAttachRejected, validator, dropzoneProps, innerRef, isPrimary, additionalActions, forceMultilineLayout = false, hasAiIndicator, isThinking } = _a, props = __rest(_a, ["onSendMessage", "className", "alwayShowSendButton", "placeholder", "hasAttachButton", "attachButtonPosition", "hasMicrophoneButton", "listeningText", "handleAttach", "attachMenuProps", "isSendButtonDisabled", "handleStopButton", "hasStopButton", "buttonProps", "onChange", "displayMode", "value", "isCompact", "allowedFileTypes", "minSize", "maxSize", "maxFiles", "isAttachmentDisabled", "onAttach", "onAttachRejected", "validator", "dropzoneProps", "innerRef", "isPrimary", "additionalActions", "forceMultilineLayout", "hasAiIndicator", "isThinking"]);
25
25
  // Text Input
26
26
  // --------------------------------------------------------------------------
27
27
  const [message, setMessage] = useState(value !== null && value !== void 0 ? value : '');
28
28
  const [isListeningMessage, setIsListeningMessage] = useState(false);
29
29
  const [hasSentMessage, setHasSentMessage] = useState(false);
30
30
  const [isComposing, setIsComposing] = useState(false);
31
- const [isMultiline, setIsMultiline] = useState(false);
31
+ const shouldForceMultiline = forceMultilineLayout || additionalActions;
32
+ const [isMultiline, setIsMultiline] = useState(shouldForceMultiline);
32
33
  const inputRef = useRef(null);
33
34
  const textareaRef = (_b = innerRef) !== null && _b !== void 0 ? _b : inputRef;
34
35
  const attachButtonRef = useRef(null);
35
36
  const topMargin = '1rem';
37
+ useEffect(() => {
38
+ if (value !== undefined && value !== message) {
39
+ setMessage(value);
40
+ }
41
+ }, [value, message]);
36
42
  const setInitialLineHeight = (field) => {
37
43
  field.style.setProperty('line-height', '1rem');
38
44
  const parent = field.parentElement;
@@ -42,7 +48,7 @@ export const MessageBarBase = (_a) => {
42
48
  parent.style.setProperty('height', 'inherit');
43
49
  const grandparent = parent.parentElement;
44
50
  if (grandparent) {
45
- grandparent.style.setProperty('flex-basis', 'auto');
51
+ grandparent.style.setProperty('flex-basis', shouldForceMultiline ? '100%' : 'auto');
46
52
  }
47
53
  }
48
54
  };
@@ -82,7 +88,7 @@ export const MessageBarBase = (_a) => {
82
88
  const parent = field.parentElement;
83
89
  if (parent) {
84
90
  const grandparent = parent.parentElement;
85
- if (textIsLongerThan2Lines(field) && grandparent) {
91
+ if ((textIsLongerThan2Lines(field) || shouldForceMultiline) && grandparent) {
86
92
  grandparent.style.setProperty('flex-basis', `100%`);
87
93
  }
88
94
  }
@@ -130,15 +136,15 @@ export const MessageBarBase = (_a) => {
130
136
  if (field) {
131
137
  if (field.value === '') {
132
138
  setInitialLineHeight(field);
133
- setIsMultiline(false);
139
+ !shouldForceMultiline && setIsMultiline(false);
134
140
  }
135
141
  else {
136
142
  setAutoHeight(field);
137
143
  setAutoWidth(field);
138
- checkIfMultiline(field);
144
+ !shouldForceMultiline && checkIfMultiline(field);
139
145
  }
140
146
  }
141
- }, [displayMode, message, setAutoWidth, checkIfMultiline]);
147
+ }, [displayMode, message, setAutoWidth, shouldForceMultiline, checkIfMultiline]);
142
148
  useEffect(() => {
143
149
  const field = textareaRef.current;
144
150
  if (field) {
@@ -151,11 +157,11 @@ export const MessageBarBase = (_a) => {
151
157
  if (textareaRef.current) {
152
158
  if (event.target.value === '') {
153
159
  setInitialLineHeight(textareaRef.current);
154
- setIsMultiline(false);
160
+ !shouldForceMultiline && setIsMultiline(false);
155
161
  }
156
162
  else {
157
163
  setAutoHeight(textareaRef.current);
158
- checkIfMultiline(textareaRef.current);
164
+ !shouldForceMultiline && checkIfMultiline(textareaRef.current);
159
165
  }
160
166
  }
161
167
  setMessage(event.target.value);
@@ -201,14 +207,25 @@ export const MessageBarBase = (_a) => {
201
207
  setMessage(message);
202
208
  onChange && onChange({}, message);
203
209
  };
210
+ const renderAttachButton = () => {
211
+ var _a, _b, _c, _d, _e, _f;
212
+ if (!attachMenuProps && hasAttachButton) {
213
+ return (_jsx(AttachButton, Object.assign({ onAttachAccepted: handleAttach, isDisabled: isListeningMessage, tooltipContent: (_a = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _a === void 0 ? void 0 : _a.tooltipContent, inputTestId: (_b = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _b === void 0 ? void 0 : _b.inputTestId, isCompact: isCompact, tooltipProps: (_c = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _c === void 0 ? void 0 : _c.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach, (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _d === void 0 ? void 0 : _d.props)));
214
+ }
215
+ if (attachMenuProps) {
216
+ return (_jsx(AttachButton, Object.assign({ ref: attachButtonRef, onClick: handleAttachMenuToggle, isDisabled: isListeningMessage, tooltipContent: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _e === void 0 ? void 0 : _e.tooltipContent, isCompact: isCompact, tooltipProps: (_f = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _f === void 0 ? void 0 : _f.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach)));
217
+ }
218
+ };
219
+ const isAttachButtonAtStart = attachButtonPosition === 'start';
204
220
  const renderButtons = () => {
205
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
221
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
206
222
  if (hasStopButton && handleStopButton) {
207
223
  return (_jsx(StopButton, Object.assign({ onClick: handleStopButton, tooltipContent: (_a = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _a === void 0 ? void 0 : _a.tooltipContent, isCompact: isCompact, tooltipProps: (_b = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _b === void 0 ? void 0 : _b.tooltipProps }, (_c = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _c === void 0 ? void 0 : _c.props)));
208
224
  }
209
- return (_jsxs(_Fragment, { children: [attachMenuProps && (_jsx(AttachButton, Object.assign({ ref: attachButtonRef, onClick: handleAttachMenuToggle, isDisabled: isListeningMessage, tooltipContent: (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _d === void 0 ? void 0 : _d.tooltipContent, isCompact: isCompact, tooltipProps: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _e === void 0 ? void 0 : _e.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach))), !attachMenuProps && hasAttachButton && (_jsx(AttachButton, Object.assign({ onAttachAccepted: handleAttach, isDisabled: isListeningMessage, tooltipContent: (_f = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _f === void 0 ? void 0 : _f.tooltipContent, inputTestId: (_g = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _g === void 0 ? void 0 : _g.inputTestId, isCompact: isCompact, tooltipProps: (_h = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _h === void 0 ? void 0 : _h.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach, (_j = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _j === void 0 ? void 0 : _j.props))), hasMicrophoneButton && (_jsx(MicrophoneButton, Object.assign({ isListening: isListeningMessage, onIsListeningChange: setIsListeningMessage, onSpeechRecognition: handleSpeechRecognition, tooltipContent: (_k = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _k === void 0 ? void 0 : _k.tooltipContent, language: (_l = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _l === void 0 ? void 0 : _l.language, isCompact: isCompact, tooltipProps: (_m = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _m === void 0 ? void 0 : _m.tooltipProps }, (_o = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _o === void 0 ? void 0 : _o.props))), (alwayShowSendButton || message) && (_jsx(SendButton, Object.assign({ value: message, onClick: () => handleSend(message), isDisabled: isSendButtonDisabled, tooltipContent: (_p = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _p === void 0 ? void 0 : _p.tooltipContent, isCompact: isCompact, tooltipProps: (_q = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _q === void 0 ? void 0 : _q.tooltipProps }, (_r = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _r === void 0 ? void 0 : _r.props)))] }));
225
+ return (_jsxs(_Fragment, { children: [!isAttachButtonAtStart && renderAttachButton(), hasMicrophoneButton && (_jsx(MicrophoneButton, Object.assign({ isListening: isListeningMessage, onIsListeningChange: setIsListeningMessage, onSpeechRecognition: handleSpeechRecognition, tooltipContent: (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _d === void 0 ? void 0 : _d.tooltipContent, language: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _e === void 0 ? void 0 : _e.language, isCompact: isCompact, tooltipProps: (_f = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _f === void 0 ? void 0 : _f.tooltipProps }, (_g = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _g === void 0 ? void 0 : _g.props))), (alwayShowSendButton || message) && (_jsx(SendButton, Object.assign({ value: message, onClick: () => handleSend(message), isDisabled: isSendButtonDisabled, tooltipContent: (_h = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _h === void 0 ? void 0 : _h.tooltipContent, isCompact: isCompact, tooltipProps: (_j = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _j === void 0 ? void 0 : _j.tooltipProps }, (_k = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _k === void 0 ? void 0 : _k.props)))] }));
210
226
  };
211
- const messageBarContents = (_jsxs(_Fragment, { children: [_jsx("div", { className: `pf-chatbot__message-bar-input ${isCompact ? 'pf-m-compact' : ''}`, children: _jsx(TextArea, Object.assign({ className: "pf-chatbot__message-textarea", value: message, onChange: handleChange, "aria-label": isListeningMessage ? listeningText : placeholder, placeholder: isListeningMessage ? listeningText : placeholder, ref: textareaRef, onKeyDown: handleKeyDown, onCompositionStart: handleCompositionStart, onCompositionEnd: handleCompositionEnd }, props)) }), _jsx("div", { className: "pf-chatbot__message-bar-actions", children: renderButtons() })] }));
227
+ const hasGroupedActions = additionalActions || (isAttachButtonAtStart && isMultiline);
228
+ const messageBarContents = (_jsxs(_Fragment, { children: [isAttachButtonAtStart && !isMultiline && (_jsx("div", { className: "pf-chatbot__message-bar-actions test", children: renderAttachButton() })), _jsx("div", { className: `pf-chatbot__message-bar-input ${isCompact ? 'pf-m-compact' : ''}`, children: _jsx(TextArea, Object.assign({ className: "pf-chatbot__message-textarea", value: message, onChange: handleChange, "aria-label": isListeningMessage ? listeningText : placeholder, placeholder: isListeningMessage ? listeningText : placeholder, ref: textareaRef, onKeyDown: handleKeyDown, onCompositionStart: handleCompositionStart, onCompositionEnd: handleCompositionEnd }, props)) }), _jsx("div", { className: css('pf-chatbot__message-bar-actions', hasGroupedActions && 'pf-m-grouped'), children: hasGroupedActions ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: css('pf-chatbot__message-bar-actions-group'), children: [isAttachButtonAtStart && renderAttachButton(), additionalActions] }), _jsx("div", { className: css('pf-chatbot__message-bar-actions-group'), children: renderButtons() })] })) : (renderButtons()) })] }));
212
229
  if (attachMenuProps) {
213
230
  return (_jsx(AttachMenu, Object.assign({ toggle: (toggleRef) => (_jsx("div", { ref: toggleRef, className: css('pf-chatbot__message-bar', isMultiline && 'pf-m-multiline', className), children: messageBarContents })), filteredItems: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.attachMenuItems }, (attachMenuProps && { isOpen: attachMenuProps.isAttachMenuOpen }), { onOpenChange: (isAttachMenuOpen) => {
214
231
  var _a;
@@ -326,4 +326,16 @@ describe('Message bar', () => {
326
326
  render(_jsx(MessageBar, { onSendMessage: jest.fn, isThinking: true }));
327
327
  expect(screen.getByRole('textbox').closest('.pf-chatbot__message-bar')).toHaveClass('pf-v6-m-thinking');
328
328
  });
329
+ it('Renders with flex-basis of auto by default', () => {
330
+ render(_jsx(MessageBar, { onSendMessage: jest.fn }));
331
+ expect(screen.getByRole('textbox').closest('.pf-chatbot__message-bar-input')).toHaveAttribute('style', 'flex-basis: auto;');
332
+ });
333
+ it('Renders with flex-basis of 100% when forceMultilineLayout is true', () => {
334
+ render(_jsx(MessageBar, { forceMultilineLayout: true, onSendMessage: jest.fn }));
335
+ expect(screen.getByRole('textbox').closest('.pf-chatbot__message-bar-input')).toHaveAttribute('style', 'flex-basis: 100%;');
336
+ });
337
+ it('Renders with flex-basis of 100% when additionalActions is truthy', () => {
338
+ render(_jsx(MessageBar, { additionalActions: "actions", onSendMessage: jest.fn }));
339
+ expect(screen.getByRole('textbox').closest('.pf-chatbot__message-bar-input')).toHaveAttribute('style', 'flex-basis: 100%;');
340
+ });
329
341
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "6.5.0",
3
+ "version": "6.6.0-prerelease.1",
4
4
  "description": "This library provides React components based on PatternFly 6 that can be used to build chatbots.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -0,0 +1,190 @@
1
+ import { useState, FunctionComponent, ReactNode } from 'react';
2
+ import { MessageBar } from '@patternfly/chatbot/dist/dynamic/MessageBar';
3
+ import {
4
+ Divider,
5
+ DropdownItem,
6
+ DropdownList,
7
+ Label,
8
+ MenuToggle,
9
+ Select,
10
+ SelectList,
11
+ SelectOption
12
+ } from '@patternfly/react-core';
13
+ import { PlusIcon, ClipboardIcon, CodeIcon, UploadIcon } from '@patternfly/react-icons';
14
+ import { useDropzone } from 'react-dropzone';
15
+
16
+ export const ChatbotMessageBarCustomActionsExample: FunctionComponent = () => {
17
+ const [isFirstMenuOpen, setIsFirstMenuOpen] = useState<boolean>(false);
18
+ const [isSecondMenuOpen, setIsSecondMenuOpen] = useState<boolean>(false);
19
+ const [isModelSelectOpen, setIsModelSelectOpen] = useState<boolean>(false);
20
+ const [selectedModel, setSelectedModel] = useState<string>('GPT-4');
21
+ const [showCanvasLabel, setShowCanvasLabel] = useState<boolean>(true);
22
+
23
+ const handleSend = (message: string | number) => alert(message);
24
+
25
+ const { open, getInputProps } = useDropzone({
26
+ multiple: true,
27
+ // eslint-disable-next-line no-console
28
+ onDropAccepted: () => console.log('fileUploaded')
29
+ });
30
+
31
+ const onFirstMenuToggle = () => {
32
+ setIsFirstMenuOpen(!isFirstMenuOpen);
33
+ };
34
+
35
+ const onSecondMenuToggle = () => {
36
+ setIsSecondMenuOpen(!isSecondMenuOpen);
37
+ };
38
+
39
+ const onModelSelect = (
40
+ _event: React.MouseEvent<Element, MouseEvent> | undefined,
41
+ value: string | number | undefined
42
+ ) => {
43
+ setSelectedModel(value as string);
44
+ setIsModelSelectOpen(false);
45
+ };
46
+
47
+ const firstMenuItems: ReactNode = (
48
+ <DropdownList>
49
+ <DropdownItem value="Logs" id="logs" icon={<ClipboardIcon />}>
50
+ Logs
51
+ </DropdownItem>
52
+ <DropdownItem value="YAML - Status" id="yaml-status" icon={<CodeIcon />}>
53
+ YAML - Status
54
+ </DropdownItem>
55
+ <DropdownItem value="YAML - All contents" id="yaml-all" icon={<CodeIcon />}>
56
+ YAML - All contents
57
+ </DropdownItem>
58
+ <Divider key="divider" />
59
+ <DropdownItem value="Upload from computer" id="upload" icon={<UploadIcon />} onClick={open}>
60
+ Upload from computer
61
+ </DropdownItem>
62
+ </DropdownList>
63
+ );
64
+
65
+ const secondMenuItems: ReactNode = (
66
+ <DropdownList>
67
+ <DropdownItem value="canvas" id="canvas">
68
+ {showCanvasLabel ? 'Disable' : 'Enable'} Canvas
69
+ </DropdownItem>
70
+ <Divider key="divider-1" />
71
+ <DropdownItem value="Logs" id="logs" icon={<ClipboardIcon />}>
72
+ Logs
73
+ </DropdownItem>
74
+ <DropdownItem value="YAML - Status" id="yaml-status" icon={<CodeIcon />}>
75
+ YAML - Status
76
+ </DropdownItem>
77
+ <DropdownItem value="YAML - All contents" id="yaml-all" icon={<CodeIcon />}>
78
+ YAML - All contents
79
+ </DropdownItem>
80
+ <Divider key="divider-2" />
81
+ <DropdownItem value="Upload from computer" id="upload" icon={<UploadIcon />} onClick={open}>
82
+ Upload from computer
83
+ </DropdownItem>
84
+ </DropdownList>
85
+ );
86
+
87
+ const modelOptions = ['GPT-4', 'GPT-3.5', 'Claude', 'Llama 2'];
88
+
89
+ return (
90
+ <>
91
+ {/* This is required for react-dropzone to work in Safari and Firefox */}
92
+ <input {...getInputProps()} hidden />
93
+ <div style={{ marginBottom: '1rem' }}>
94
+ <h4 style={{ marginBottom: '0.5rem' }}>Custom attach menu with a PlusIcon at the start</h4>
95
+ <MessageBar
96
+ onSendMessage={handleSend}
97
+ attachButtonPosition="start"
98
+ attachMenuProps={{
99
+ isAttachMenuOpen: isFirstMenuOpen,
100
+ setIsAttachMenuOpen: setIsFirstMenuOpen,
101
+ attachMenuItems: firstMenuItems,
102
+ onAttachMenuSelect: (_ev, value) => {
103
+ // eslint-disable-next-line no-console
104
+ console.log('selected', value);
105
+ setIsFirstMenuOpen(false);
106
+ },
107
+ attachMenuInputPlaceholder: 'Search options...',
108
+ onAttachMenuToggleClick: onFirstMenuToggle,
109
+ onAttachMenuOnOpenChangeKeys: ['Escape', 'Tab']
110
+ }}
111
+ buttonProps={{
112
+ attach: {
113
+ icon: <PlusIcon />,
114
+ tooltipContent: 'Message actions',
115
+ 'aria-label': 'Message actions'
116
+ }
117
+ }}
118
+ />
119
+ </div>
120
+
121
+ <div>
122
+ <h4 style={{ marginBottom: '0.5rem' }}>Custom attach menu with additional actions</h4>
123
+ <MessageBar
124
+ onSendMessage={handleSend}
125
+ attachButtonPosition="start"
126
+ attachMenuProps={{
127
+ isAttachMenuOpen: isSecondMenuOpen,
128
+ setIsAttachMenuOpen: setIsSecondMenuOpen,
129
+ attachMenuItems: secondMenuItems,
130
+ onAttachMenuOnOpenChangeKeys: ['Escape', 'Tab'],
131
+ onAttachMenuSelect: (_ev, value) => {
132
+ // eslint-disable-next-line no-console
133
+ console.log('selected', value);
134
+ if (value === 'canvas') {
135
+ setShowCanvasLabel(!showCanvasLabel);
136
+ }
137
+ setIsSecondMenuOpen(false);
138
+ },
139
+ onAttachMenuToggleClick: onSecondMenuToggle
140
+ }}
141
+ buttonProps={{
142
+ attach: {
143
+ icon: <PlusIcon />,
144
+ tooltipContent: 'Message actions',
145
+ 'aria-label': 'Message actions'
146
+ }
147
+ }}
148
+ additionalActions={
149
+ <>
150
+ <Select
151
+ isOpen={isModelSelectOpen}
152
+ selected={selectedModel}
153
+ shouldFocusToggleOnSelect
154
+ onSelect={onModelSelect}
155
+ onOpenChange={(isOpen) => setIsModelSelectOpen(isOpen)}
156
+ toggle={(toggleRef) => (
157
+ <MenuToggle
158
+ ref={toggleRef}
159
+ variant="plainText"
160
+ onClick={() => setIsModelSelectOpen(!isModelSelectOpen)}
161
+ isExpanded={isModelSelectOpen}
162
+ aria-label={`${selectedModel}, Select a model`}
163
+ style={{
164
+ minWidth: '120px'
165
+ }}
166
+ >
167
+ {selectedModel}
168
+ </MenuToggle>
169
+ )}
170
+ >
171
+ <SelectList>
172
+ {modelOptions.map((option) => (
173
+ <SelectOption key={option} value={option}>
174
+ {option}
175
+ </SelectOption>
176
+ ))}
177
+ </SelectList>
178
+ </Select>
179
+ {showCanvasLabel && (
180
+ <Label closeBtnAriaLabel="Remove Canvas mode" onClose={() => setShowCanvasLabel(false)}>
181
+ Canvas
182
+ </Label>
183
+ )}
184
+ </>
185
+ }
186
+ />
187
+ </div>
188
+ </>
189
+ );
190
+ };
@@ -70,11 +70,11 @@ import { MessageBar } from '@patternfly/chatbot/dist/dynamic/MessageBar';
70
70
  import SourceDetailsMenuItem from '@patternfly/chatbot/dist/dynamic/SourceDetailsMenuItem';
71
71
  import { ChatbotModal } from '@patternfly/chatbot/dist/dynamic/ChatbotModal';
72
72
  import SettingsForm from '@patternfly/chatbot/dist/dynamic/Settings';
73
- import { BellIcon, CalendarAltIcon, ClipboardIcon, CodeIcon, ThumbtackIcon, UploadIcon } from '@patternfly/react-icons';
73
+ import { BellIcon, CalendarAltIcon, ClipboardIcon, CodeIcon, PlusIcon, ThumbtackIcon, UploadIcon } from '@patternfly/react-icons';
74
74
  import { useDropzone } from 'react-dropzone';
75
75
 
76
76
  import ChatbotConversationHistoryNav from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';
77
- import { Button, DropdownItem, DropdownList, Checkbox, MenuToggle, Select, SelectList, SelectOption } from '@patternfly/react-core';
77
+ import { Button, Label, DropdownItem, DropdownList, Checkbox, MenuToggle, Select, SelectList, SelectOption } from '@patternfly/react-core';
78
78
 
79
79
  import OutlinedWindowRestoreIcon from '@patternfly/react-icons/dist/esm/icons/outlined-window-restore-icon';
80
80
  import ExpandIcon from '@patternfly/react-icons/dist/esm/icons/expand-icon';
@@ -291,6 +291,19 @@ Attachments can also be added to the ChatBot via [drag and drop.](/extensions/ch
291
291
 
292
292
  ```
293
293
 
294
+ ### Message bar with custom attach menu and additional actions
295
+
296
+ You can move the attach button to the start of the message bar and customize it with a different icon. To include additional actions in the message bar you can also use the `additionalActions` prop.
297
+
298
+ This example shows two message bar variations:
299
+
300
+ 1. A message bar with a custom attach menu where a `PlusIcon` is positioned at the start
301
+ 2. The same custom attach menu with additional actions, including a model selector menu and a dismissable "Canvas" label
302
+
303
+ ```js file="./ChatbotMessageBarCustomActions.tsx"
304
+
305
+ ```
306
+
294
307
  ### Footer with message bar and footnote
295
308
 
296
309
  A simple footer with a message bar and footnote would have this code structure:
@@ -66,6 +66,19 @@
66
66
  padding-block-start: var(--pf-t--global--spacer--xs);
67
67
  padding-block-end: var(--pf-t--global--spacer--xs);
68
68
  gap: var(--pf-t--global--spacer--gap--action-to-action--plain);
69
+
70
+ &.pf-m-grouped {
71
+ flex-basis: 100%;
72
+ justify-content: space-between;
73
+ }
74
+ }
75
+
76
+ &-actions-group {
77
+ display: flex;
78
+ padding-block-start: var(--pf-t--global--spacer--xs);
79
+ padding-block-end: var(--pf-t--global--spacer--xs);
80
+ gap: var(--pf-t--global--spacer--gap--action-to-action--plain);
81
+ align-items: center;
69
82
  }
70
83
 
71
84
  &-input {
@@ -150,7 +163,8 @@
150
163
  }
151
164
 
152
165
  .pf-m-compact {
153
- .pf-chatbot__message-bar-actions {
166
+ .pf-chatbot__message-bar-actions,
167
+ .pf-chatbot__message-bar-actions-group {
154
168
  padding-block-start: var(--pf-t--global--spacer--sm);
155
169
  padding-block-end: var(--pf-t--global--spacer--sm);
156
170
  }
@@ -488,4 +488,31 @@ describe('Message bar', () => {
488
488
 
489
489
  expect(screen.getByRole('textbox').closest('.pf-chatbot__message-bar')).toHaveClass('pf-v6-m-thinking');
490
490
  });
491
+
492
+ it('Renders with flex-basis of auto by default', () => {
493
+ render(<MessageBar onSendMessage={jest.fn} />);
494
+
495
+ expect(screen.getByRole('textbox').closest('.pf-chatbot__message-bar-input')).toHaveAttribute(
496
+ 'style',
497
+ 'flex-basis: auto;'
498
+ );
499
+ });
500
+
501
+ it('Renders with flex-basis of 100% when forceMultilineLayout is true', () => {
502
+ render(<MessageBar forceMultilineLayout onSendMessage={jest.fn} />);
503
+
504
+ expect(screen.getByRole('textbox').closest('.pf-chatbot__message-bar-input')).toHaveAttribute(
505
+ 'style',
506
+ 'flex-basis: 100%;'
507
+ );
508
+ });
509
+
510
+ it('Renders with flex-basis of 100% when additionalActions is truthy', () => {
511
+ render(<MessageBar additionalActions="actions" onSendMessage={jest.fn} />);
512
+
513
+ expect(screen.getByRole('textbox').closest('.pf-chatbot__message-bar-input')).toHaveAttribute(
514
+ 'style',
515
+ 'flex-basis: 100%;'
516
+ );
517
+ });
491
518
  });
@@ -58,6 +58,8 @@ export interface MessageBarProps extends Omit<TextAreaProps, 'innerRef'> {
58
58
  placeholder?: string;
59
59
  /** Flag to disable/enable the Attach button */
60
60
  hasAttachButton?: boolean;
61
+ /** Whether the attach button is rendered before or after the message input. */
62
+ attachButtonPosition?: 'start' | 'end';
61
63
  /** Flag to enable the Microphone button */
62
64
  hasMicrophoneButton?: boolean;
63
65
  /** Placeholder text when listening */
@@ -116,6 +118,10 @@ export interface MessageBarProps extends Omit<TextAreaProps, 'innerRef'> {
116
118
  innerRef?: React.Ref<HTMLTextAreaElement>;
117
119
  /** Sets background color to primary */
118
120
  isPrimary?: boolean;
121
+ /** Additional actions to render for the message bar. This will force a multiline layout, and the actions will render at the start of the container. */
122
+ additionalActions?: React.ReactNode;
123
+ /** Flag indicating whether a multiline layout for the message input and actions should be forced. This can be used to always render actions below the message input. */
124
+ forceMultilineLayout?: boolean;
119
125
  /** @beta Flag indicating whether the message bar has an AI indicator border. */
120
126
  hasAiIndicator?: boolean;
121
127
  /** @beta Flag indicating whether the chatbot is thinking in response to a query, adding an animation to the message bar. */
@@ -128,6 +134,7 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
128
134
  alwayShowSendButton,
129
135
  placeholder = 'Send a message...',
130
136
  hasAttachButton = true,
137
+ attachButtonPosition = 'end',
131
138
  hasMicrophoneButton,
132
139
  listeningText = 'Listening',
133
140
  handleAttach,
@@ -151,6 +158,8 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
151
158
  dropzoneProps,
152
159
  innerRef,
153
160
  isPrimary,
161
+ additionalActions,
162
+ forceMultilineLayout = false,
154
163
  hasAiIndicator,
155
164
  isThinking,
156
165
  ...props
@@ -161,13 +170,21 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
161
170
  const [isListeningMessage, setIsListeningMessage] = useState<boolean>(false);
162
171
  const [hasSentMessage, setHasSentMessage] = useState(false);
163
172
  const [isComposing, setIsComposing] = useState(false);
164
- const [isMultiline, setIsMultiline] = useState(false);
173
+
174
+ const shouldForceMultiline = forceMultilineLayout || additionalActions;
175
+ const [isMultiline, setIsMultiline] = useState(shouldForceMultiline);
165
176
  const inputRef = useRef<HTMLTextAreaElement>(null);
166
177
  const textareaRef = (innerRef as React.RefObject<HTMLTextAreaElement>) ?? inputRef;
167
178
  const attachButtonRef = useRef<HTMLButtonElement>(null);
168
179
 
169
180
  const topMargin = '1rem';
170
181
 
182
+ useEffect(() => {
183
+ if (value !== undefined && value !== message) {
184
+ setMessage(value);
185
+ }
186
+ }, [value, message]);
187
+
171
188
  const setInitialLineHeight = (field: HTMLTextAreaElement) => {
172
189
  field.style.setProperty('line-height', '1rem');
173
190
  const parent = field.parentElement;
@@ -178,7 +195,7 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
178
195
 
179
196
  const grandparent = parent.parentElement;
180
197
  if (grandparent) {
181
- grandparent.style.setProperty('flex-basis', 'auto');
198
+ grandparent.style.setProperty('flex-basis', shouldForceMultiline ? '100%' : 'auto');
182
199
  }
183
200
  }
184
201
  };
@@ -227,7 +244,7 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
227
244
  const parent = field.parentElement;
228
245
  if (parent) {
229
246
  const grandparent = parent.parentElement;
230
- if (textIsLongerThan2Lines(field) && grandparent) {
247
+ if ((textIsLongerThan2Lines(field) || shouldForceMultiline) && grandparent) {
231
248
  grandparent.style.setProperty('flex-basis', `100%`);
232
249
  }
233
250
  }
@@ -277,14 +294,14 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
277
294
  if (field) {
278
295
  if (field.value === '') {
279
296
  setInitialLineHeight(field);
280
- setIsMultiline(false);
297
+ !shouldForceMultiline && setIsMultiline(false);
281
298
  } else {
282
299
  setAutoHeight(field);
283
300
  setAutoWidth(field);
284
- checkIfMultiline(field);
301
+ !shouldForceMultiline && checkIfMultiline(field);
285
302
  }
286
303
  }
287
- }, [displayMode, message, setAutoWidth, checkIfMultiline]);
304
+ }, [displayMode, message, setAutoWidth, shouldForceMultiline, checkIfMultiline]);
288
305
 
289
306
  useEffect(() => {
290
307
  const field = textareaRef.current;
@@ -300,10 +317,10 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
300
317
  if (textareaRef.current) {
301
318
  if (event.target.value === '') {
302
319
  setInitialLineHeight(textareaRef.current);
303
- setIsMultiline(false);
320
+ !shouldForceMultiline && setIsMultiline(false);
304
321
  } else {
305
322
  setAutoHeight(textareaRef.current);
306
- checkIfMultiline(textareaRef.current);
323
+ !shouldForceMultiline && checkIfMultiline(textareaRef.current);
307
324
  }
308
325
  }
309
326
  setMessage(event.target.value);
@@ -365,6 +382,55 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
365
382
  onChange && onChange({} as ChangeEvent<HTMLTextAreaElement>, message);
366
383
  };
367
384
 
385
+ const renderAttachButton = () => {
386
+ if (!attachMenuProps && hasAttachButton) {
387
+ return (
388
+ <AttachButton
389
+ onAttachAccepted={handleAttach}
390
+ isDisabled={isListeningMessage}
391
+ tooltipContent={buttonProps?.attach?.tooltipContent}
392
+ inputTestId={buttonProps?.attach?.inputTestId}
393
+ isCompact={isCompact}
394
+ tooltipProps={buttonProps?.attach?.tooltipProps}
395
+ allowedFileTypes={allowedFileTypes}
396
+ minSize={minSize}
397
+ maxSize={maxSize}
398
+ maxFiles={maxFiles}
399
+ isAttachmentDisabled={isAttachmentDisabled}
400
+ onAttach={onAttach}
401
+ onAttachRejected={onAttachRejected}
402
+ validator={validator}
403
+ dropzoneProps={dropzoneProps}
404
+ {...buttonProps?.attach}
405
+ {...buttonProps?.attach?.props}
406
+ />
407
+ );
408
+ }
409
+ if (attachMenuProps) {
410
+ return (
411
+ <AttachButton
412
+ ref={attachButtonRef}
413
+ onClick={handleAttachMenuToggle}
414
+ isDisabled={isListeningMessage}
415
+ tooltipContent={buttonProps?.attach?.tooltipContent}
416
+ isCompact={isCompact}
417
+ tooltipProps={buttonProps?.attach?.tooltipProps}
418
+ allowedFileTypes={allowedFileTypes}
419
+ minSize={minSize}
420
+ maxSize={maxSize}
421
+ maxFiles={maxFiles}
422
+ isAttachmentDisabled={isAttachmentDisabled}
423
+ onAttach={onAttach}
424
+ onAttachRejected={onAttachRejected}
425
+ validator={validator}
426
+ dropzoneProps={dropzoneProps}
427
+ {...buttonProps?.attach}
428
+ />
429
+ );
430
+ }
431
+ };
432
+
433
+ const isAttachButtonAtStart = attachButtonPosition === 'start';
368
434
  const renderButtons = () => {
369
435
  if (hasStopButton && handleStopButton) {
370
436
  return (
@@ -379,47 +445,7 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
379
445
  }
380
446
  return (
381
447
  <>
382
- {attachMenuProps && (
383
- <AttachButton
384
- ref={attachButtonRef}
385
- onClick={handleAttachMenuToggle}
386
- isDisabled={isListeningMessage}
387
- tooltipContent={buttonProps?.attach?.tooltipContent}
388
- isCompact={isCompact}
389
- tooltipProps={buttonProps?.attach?.tooltipProps}
390
- allowedFileTypes={allowedFileTypes}
391
- minSize={minSize}
392
- maxSize={maxSize}
393
- maxFiles={maxFiles}
394
- isAttachmentDisabled={isAttachmentDisabled}
395
- onAttach={onAttach}
396
- onAttachRejected={onAttachRejected}
397
- validator={validator}
398
- dropzoneProps={dropzoneProps}
399
- {...buttonProps?.attach}
400
- />
401
- )}
402
- {!attachMenuProps && hasAttachButton && (
403
- <AttachButton
404
- onAttachAccepted={handleAttach}
405
- isDisabled={isListeningMessage}
406
- tooltipContent={buttonProps?.attach?.tooltipContent}
407
- inputTestId={buttonProps?.attach?.inputTestId}
408
- isCompact={isCompact}
409
- tooltipProps={buttonProps?.attach?.tooltipProps}
410
- allowedFileTypes={allowedFileTypes}
411
- minSize={minSize}
412
- maxSize={maxSize}
413
- maxFiles={maxFiles}
414
- isAttachmentDisabled={isAttachmentDisabled}
415
- onAttach={onAttach}
416
- onAttachRejected={onAttachRejected}
417
- validator={validator}
418
- dropzoneProps={dropzoneProps}
419
- {...buttonProps?.attach}
420
- {...buttonProps?.attach?.props}
421
- />
422
- )}
448
+ {!isAttachButtonAtStart && renderAttachButton()}
423
449
  {hasMicrophoneButton && (
424
450
  <MicrophoneButton
425
451
  isListening={isListeningMessage}
@@ -447,8 +473,12 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
447
473
  );
448
474
  };
449
475
 
476
+ const hasGroupedActions = additionalActions || (isAttachButtonAtStart && isMultiline);
450
477
  const messageBarContents = (
451
478
  <>
479
+ {isAttachButtonAtStart && !isMultiline && (
480
+ <div className="pf-chatbot__message-bar-actions test">{renderAttachButton()}</div>
481
+ )}
452
482
  <div className={`pf-chatbot__message-bar-input ${isCompact ? 'pf-m-compact' : ''}`}>
453
483
  <TextArea
454
484
  className="pf-chatbot__message-textarea"
@@ -463,7 +493,19 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
463
493
  {...props}
464
494
  />
465
495
  </div>
466
- <div className="pf-chatbot__message-bar-actions">{renderButtons()}</div>
496
+ <div className={css('pf-chatbot__message-bar-actions', hasGroupedActions && 'pf-m-grouped')}>
497
+ {hasGroupedActions ? (
498
+ <>
499
+ <div className={css('pf-chatbot__message-bar-actions-group')}>
500
+ {isAttachButtonAtStart && renderAttachButton()}
501
+ {additionalActions}
502
+ </div>
503
+ <div className={css('pf-chatbot__message-bar-actions-group')}>{renderButtons()}</div>
504
+ </>
505
+ ) : (
506
+ renderButtons()
507
+ )}
508
+ </div>
467
509
  </>
468
510
  );
469
511