@patternfly/chatbot 6.4.1 → 6.5.0-prerelease.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/cjs/ChatbotContent/ChatbotContent.d.ts +2 -0
  2. package/dist/cjs/ChatbotContent/ChatbotContent.js +2 -2
  3. package/dist/cjs/ChatbotContent/ChatbotContent.test.js +4 -0
  4. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.d.ts +3 -1
  5. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +3 -3
  6. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.js +4 -0
  7. package/dist/cjs/CodeModal/CodeModal.js +36 -4
  8. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.d.ts +3 -1
  9. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +2 -2
  10. package/dist/cjs/Message/Message.d.ts +3 -19
  11. package/dist/cjs/Message/Message.test.js +6 -0
  12. package/dist/css/main.css +17 -6
  13. package/dist/css/main.css.map +1 -1
  14. package/dist/esm/ChatbotContent/ChatbotContent.d.ts +2 -0
  15. package/dist/esm/ChatbotContent/ChatbotContent.js +2 -2
  16. package/dist/esm/ChatbotContent/ChatbotContent.test.js +4 -0
  17. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.d.ts +3 -1
  18. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +3 -3
  19. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.js +4 -0
  20. package/dist/esm/CodeModal/CodeModal.js +38 -6
  21. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.d.ts +3 -1
  22. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +2 -2
  23. package/dist/esm/Message/Message.d.ts +3 -19
  24. package/dist/esm/Message/Message.test.js +7 -1
  25. package/package.json +1 -1
  26. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithActions.tsx +14 -14
  27. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithSelection.tsx +14 -14
  28. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarAttach.tsx +2 -2
  29. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachmentMenu.tsx +2 -2
  30. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotTranscripts.tsx +1 -1
  31. package/src/ChatbotContent/ChatbotContent.scss +4 -0
  32. package/src/ChatbotContent/ChatbotContent.test.tsx +5 -0
  33. package/src/ChatbotContent/ChatbotContent.tsx +4 -1
  34. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.tsx +5 -0
  35. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx +7 -4
  36. package/src/CodeModal/CodeModal.tsx +54 -7
  37. package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +3 -2
  38. package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +5 -1
  39. package/src/Message/Message.test.tsx +19 -1
  40. package/src/Message/Message.tsx +2 -21
  41. package/src/Message/TextMessage/TextMessage.scss +6 -0
@@ -4,6 +4,8 @@ export interface ChatbotContentProps extends HTMLProps<HTMLDivElement> {
4
4
  children: React.ReactNode;
5
5
  /** Custom classname for the ChatbotContent component */
6
6
  className?: string;
7
+ /** Sets background color to primary */
8
+ isPrimary?: boolean;
7
9
  }
8
10
  export declare const ChatbotContent: FunctionComponent<ChatbotContentProps>;
9
11
  export default ChatbotContent;
@@ -14,8 +14,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.ChatbotContent = void 0;
15
15
  const jsx_runtime_1 = require("react/jsx-runtime");
16
16
  const ChatbotContent = (_a) => {
17
- var { children, className } = _a, props = __rest(_a, ["children", "className"]);
18
- return ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: `pf-chatbot__content ${className !== null && className !== void 0 ? className : ''}` }, props, { children: children })));
17
+ var { children, className, isPrimary } = _a, props = __rest(_a, ["children", "className", "isPrimary"]);
18
+ return ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: `pf-chatbot__content ${isPrimary ? 'pf-m-primary' : ''} ${className !== null && className !== void 0 ? className : ''}` }, props, { children: children })));
19
19
  };
20
20
  exports.ChatbotContent = ChatbotContent;
21
21
  exports.default = exports.ChatbotContent;
@@ -15,4 +15,8 @@ describe('ChatbotContent', () => {
15
15
  const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotContent_1.default, { className: "custom-class", children: "Chatbot Content" }));
16
16
  expect(container.querySelector('.custom-class')).toBeTruthy();
17
17
  });
18
+ it('should render ChatbotContent with primary class', () => {
19
+ const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotContent_1.default, { isPrimary: true, children: "Chatbot Content" }));
20
+ expect(container.querySelector('.pf-m-primary')).toBeTruthy();
21
+ });
18
22
  });
@@ -5,8 +5,10 @@ export interface ChatbotConversationHistoryDropdownProps extends Omit<DropdownPr
5
5
  menuItems: React.ReactNode;
6
6
  /** Optional classname applied to conversation settings dropdown */
7
7
  menuClassName?: string;
8
- /** Tooltip content and aria-label applied to conversation settings dropdown */
8
+ /** Tooltip content applied to conversation settings dropdown */
9
9
  label?: string;
10
+ /** Aria-label applied to conversation settings dropdown */
11
+ 'aria-label'?: string;
10
12
  /** Callback for when user selects item. */
11
13
  onSelect?: (event?: React.MouseEvent, value?: string | number) => void;
12
14
  /** Id applied to dropdown menu toggle */
@@ -9,11 +9,11 @@ const react_1 = require("react");
9
9
  // Import PatternFly components
10
10
  const react_core_1 = require("@patternfly/react-core");
11
11
  const ellipsis_v_icon_1 = __importDefault(require("@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon"));
12
- const ChatbotConversationHistoryDropdown = ({ menuItems, menuClassName, onSelect, label, id }) => {
12
+ const ChatbotConversationHistoryDropdown = ({ menuItems, menuClassName, onSelect, label = 'Conversation options', 'aria-label': ariaLabel, id }) => {
13
13
  const [isOpen, setIsOpen] = (0, react_1.useState)(false);
14
- const toggle = (toggleRef) => ((0, jsx_runtime_1.jsx)(react_core_1.Tooltip, { className: "pf-chatbot__tooltip", content: label !== null && label !== void 0 ? label : 'Conversation options', position: "bottom",
14
+ const toggle = (toggleRef) => ((0, jsx_runtime_1.jsx)(react_core_1.Tooltip, { className: "pf-chatbot__tooltip", content: label, position: "bottom",
15
15
  // prevents VO announcements of both aria label and tooltip
16
- aria: "none", children: (0, jsx_runtime_1.jsx)(react_core_1.MenuToggle, { className: "pf-chatbot__history-actions", variant: "plain", "aria-label": label !== null && label !== void 0 ? label : 'Conversation options', ref: toggleRef, isExpanded: isOpen, onClick: () => setIsOpen(!isOpen), id: id, role: "menuitem", children: (0, jsx_runtime_1.jsx)(ellipsis_v_icon_1.default, {}) }) }));
16
+ aria: "none", children: (0, jsx_runtime_1.jsx)(react_core_1.MenuToggle, { className: "pf-chatbot__history-actions", variant: "plain", "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : label, ref: toggleRef, isExpanded: isOpen, onClick: () => setIsOpen(!isOpen), id: id, role: "menuitem", children: (0, jsx_runtime_1.jsx)(ellipsis_v_icon_1.default, {}) }) }));
17
17
  return ((0, jsx_runtime_1.jsx)(react_core_1.Dropdown, { className: `pf-chatbot__selections ${menuClassName !== null && menuClassName !== void 0 ? menuClassName : ''}`, isOpen: isOpen, onSelect: (props) => {
18
18
  onSelect === null || onSelect === void 0 ? void 0 : onSelect(props);
19
19
  setIsOpen((prev) => !prev);
@@ -68,4 +68,8 @@ describe('ChatbotConversationHistoryDropdown', () => {
68
68
  expect(react_1.screen.queryByText('Actions dropdown')).toBeInTheDocument();
69
69
  });
70
70
  }));
71
+ it('should be able to set a custom aria-label', () => {
72
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryDropdown_1.default, { menuItems: menuItems, "aria-label": "Custom conversation options" }));
73
+ expect(react_1.screen.queryByRole('menuitem', { name: /Custom conversation options/i })).toBeInTheDocument();
74
+ });
71
75
  });
@@ -50,6 +50,31 @@ const ChatbotModal_1 = __importDefault(require("../ChatbotModal/ChatbotModal"));
50
50
  const CodeModal = (_a) => {
51
51
  var { fileName, code, codeEditorControlClassName: codeEditorClassName, handleModalToggle, isCopyEnabled, isLineNumbersVisible, isModalOpen, isReadOnly, onPrimaryAction, onSecondaryAction, primaryActionBtn, secondaryActionBtn, title, displayMode = Chatbot_1.ChatbotDisplayMode.default, isCompact, modalHeaderClassName, modalBodyClassName, modalFooterClassName } = _a, props = __rest(_a, ["fileName", "code", "codeEditorControlClassName", "handleModalToggle", "isCopyEnabled", "isLineNumbersVisible", "isModalOpen", "isReadOnly", "onPrimaryAction", "onSecondaryAction", "primaryActionBtn", "secondaryActionBtn", "title", "displayMode", "isCompact", "modalHeaderClassName", "modalBodyClassName", "modalFooterClassName"]);
52
52
  const [newCode, setNewCode] = (0, react_1.useState)(code);
53
+ const [editorInstance, setEditorInstance] = (0, react_1.useState)(null);
54
+ const [isEditorReady, setIsEditorReady] = (0, react_1.useState)(false);
55
+ const containerRef = (0, react_1.useRef)(null);
56
+ (0, react_1.useEffect)(() => {
57
+ if (!isModalOpen || !isEditorReady || !editorInstance || !containerRef.current) {
58
+ return;
59
+ }
60
+ const handleResize = () => {
61
+ if (editorInstance && isEditorReady && isModalOpen) {
62
+ try {
63
+ window.requestAnimationFrame(() => {
64
+ editorInstance.layout();
65
+ });
66
+ }
67
+ catch (error) {
68
+ // eslint-disable-next-line no-console
69
+ console.error('ChatBot code modal layout error:', error);
70
+ }
71
+ }
72
+ };
73
+ const observer = (0, react_core_1.getResizeObserver)(containerRef.current, handleResize);
74
+ return () => {
75
+ observer();
76
+ };
77
+ }, [editorInstance, isEditorReady, isModalOpen]);
53
78
  const handlePrimaryAction = (_event) => {
54
79
  handleModalToggle(_event);
55
80
  if (!isReadOnly) {
@@ -64,18 +89,25 @@ const CodeModal = (_a) => {
64
89
  onSecondaryAction(_event);
65
90
  };
66
91
  const onEditorDidMount = (editor, monaco) => {
67
- editor.layout();
68
- editor.focus();
92
+ setEditorInstance(editor);
69
93
  monaco.editor.getModels()[0].updateOptions({ tabSize: 5 });
94
+ if (containerRef.current) {
95
+ setIsEditorReady(true);
96
+ editor.layout();
97
+ editor.focus();
98
+ }
70
99
  };
71
100
  const onCodeChange = (value) => {
72
101
  if (!isReadOnly) {
73
102
  setNewCode(value);
74
103
  }
75
104
  };
76
- const modal = ((0, jsx_runtime_1.jsxs)(ChatbotModal_1.default, { isOpen: isModalOpen, onClose: handleModalToggle, ouiaId: "CodeModal", "aria-labelledby": "code-modal-title", "aria-describedby": "code-modal", className: `pf-chatbot__code-modal ${isCompact ? 'pf-m-compact' : ''} pf-chatbot__code-modal--${displayMode}`, displayMode: displayMode, isCompact: isCompact, children: [(0, jsx_runtime_1.jsx)(react_core_1.ModalHeader, { className: modalHeaderClassName, title: title, labelId: "code-modal-title" }), (0, jsx_runtime_1.jsx)(react_core_1.ModalBody, { className: modalBodyClassName, id: "code-modal-body", children: (0, jsx_runtime_1.jsxs)(react_core_1.Stack, { className: "pf-chatbot__code-modal-body", children: [(0, jsx_runtime_1.jsx)(react_core_1.StackItem, { className: "pf-chatbot__code-modal-file-details", children: (0, jsx_runtime_1.jsx)(FileDetails_1.default, { fileName: fileName }) }), (0, jsx_runtime_1.jsx)(react_core_1.StackItem, { className: "pf-chatbot__code-modal-editor", children: (0, jsx_runtime_1.jsx)(react_code_editor_1.CodeEditor, Object.assign({ isDarkTheme: true, isLineNumbersVisible: isLineNumbersVisible, isLanguageLabelVisible: true, isCopyEnabled: isCopyEnabled, isReadOnly: isReadOnly, code: newCode, language: FileDetails_1.extensionToLanguage[path_browserify_1.default.extname(fileName).slice(1)], onEditorDidMount: onEditorDidMount, onCodeChange: onCodeChange, className: codeEditorClassName, isFullHeight: true, options: {
105
+ const modal = ((0, jsx_runtime_1.jsxs)(ChatbotModal_1.default, { isOpen: isModalOpen, onClose: handleModalToggle, ouiaId: "CodeModal", "aria-labelledby": "code-modal-title", "aria-describedby": "code-modal", className: `pf-chatbot__code-modal ${isCompact ? 'pf-m-compact' : ''} pf-chatbot__code-modal--${displayMode}`, displayMode: displayMode, isCompact: isCompact, children: [(0, jsx_runtime_1.jsx)(react_core_1.ModalHeader, { className: modalHeaderClassName, title: title, labelId: "code-modal-title" }), (0, jsx_runtime_1.jsx)(react_core_1.ModalBody, { className: modalBodyClassName, id: "code-modal-body", children: (0, jsx_runtime_1.jsxs)(react_core_1.Stack, { className: "pf-chatbot__code-modal-body", children: [(0, jsx_runtime_1.jsx)(react_core_1.StackItem, { className: "pf-chatbot__code-modal-file-details", children: (0, jsx_runtime_1.jsx)(FileDetails_1.default, { fileName: fileName }) }), (0, jsx_runtime_1.jsx)("div", { className: "pf-v6-l-stack__item pf-chatbot__code-modal-editor", ref: containerRef, children: (0, jsx_runtime_1.jsx)(react_code_editor_1.CodeEditor, Object.assign({ isDarkTheme: true, isLineNumbersVisible: isLineNumbersVisible, isLanguageLabelVisible: true, isCopyEnabled: isCopyEnabled, isReadOnly: isReadOnly, code: newCode, language: FileDetails_1.extensionToLanguage[path_browserify_1.default.extname(fileName).slice(1)], onEditorDidMount: onEditorDidMount, onCodeChange: onCodeChange, className: codeEditorClassName, isFullHeight: true, options: {
77
106
  glyphMargin: false,
78
- folding: false
107
+ folding: false,
108
+ // prevents Monaco from handling resizing itself
109
+ // was causing ResizeObserver issues
110
+ automaticLayout: false
79
111
  } }, props)) })] }) }), (0, jsx_runtime_1.jsxs)(react_core_1.ModalFooter, { className: modalFooterClassName, children: [(0, jsx_runtime_1.jsx)(react_core_1.Button, { isBlock: true, variant: "primary", onClick: handlePrimaryAction, form: "code-modal-form", children: primaryActionBtn }, "code-modal-primary"), (0, jsx_runtime_1.jsx)(react_core_1.Button, { isBlock: true, variant: "link", onClick: handleSecondaryAction, children: secondaryActionBtn }, "code-modal-secondary")] })] }));
80
112
  return modal;
81
113
  };
@@ -16,6 +16,8 @@ export interface CodeBlockMessageProps {
16
16
  expandedText?: string;
17
17
  /** Link text applied to expandable toggle when collapsed */
18
18
  collapsedText?: string;
19
+ /** Custom actions added to header of code block, after any default actions such as the "copy" action. */
20
+ customActions?: React.ReactNode;
19
21
  }
20
- declare const CodeBlockMessage: ({ children, className, "aria-label": ariaLabel, isExpandable, expandableSectionProps, expandableSectionToggleProps, expandedText, collapsedText, ...props }: CodeBlockMessageProps) => import("react/jsx-runtime").JSX.Element;
22
+ declare const CodeBlockMessage: ({ children, className, "aria-label": ariaLabel, isExpandable, expandableSectionProps, expandableSectionToggleProps, expandedText, collapsedText, customActions, ...props }: CodeBlockMessageProps) => import("react/jsx-runtime").JSX.Element;
21
23
  export default CodeBlockMessage;
@@ -24,7 +24,7 @@ const DEFAULT_EXPANDED_TEXT = 'Show less';
24
24
  const DEFAULT_COLLAPSED_TEXT = 'Show more';
25
25
  const CodeBlockMessage = (_a) => {
26
26
  var _b;
27
- var { children, className, 'aria-label': ariaLabel, isExpandable = false, expandableSectionProps, expandableSectionToggleProps, expandedText = DEFAULT_EXPANDED_TEXT, collapsedText = DEFAULT_COLLAPSED_TEXT } = _a, props = __rest(_a, ["children", "className", 'aria-label', "isExpandable", "expandableSectionProps", "expandableSectionToggleProps", "expandedText", "collapsedText"]);
27
+ var { children, className, 'aria-label': ariaLabel, isExpandable = false, expandableSectionProps, expandableSectionToggleProps, expandedText = DEFAULT_EXPANDED_TEXT, collapsedText = DEFAULT_COLLAPSED_TEXT, customActions } = _a, props = __rest(_a, ["children", "className", 'aria-label', "isExpandable", "expandableSectionProps", "expandableSectionToggleProps", "expandedText", "collapsedText", "customActions"]);
28
28
  const [copied, setCopied] = (0, react_1.useState)(false);
29
29
  const [isExpanded, setIsExpanded] = (0, react_1.useState)(false);
30
30
  const buttonRef = (0, react_1.useRef)();
@@ -64,7 +64,7 @@ const CodeBlockMessage = (_a) => {
64
64
  return ((0, jsx_runtime_1.jsx)("code", Object.assign({}, props, { className: "pf-chatbot__message-inline-code", children: children })));
65
65
  }
66
66
  // Setup code block header
67
- const actions = ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)(react_core_1.CodeBlockAction, { children: [language && (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-code-block-language", children: language }), (0, jsx_runtime_1.jsx)(react_core_1.Button, { ref: buttonRef, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : 'Copy code', variant: "plain", className: "pf-chatbot__button--copy", onClick: (event) => handleCopy(event, children), children: copied ? (0, jsx_runtime_1.jsx)(check_icon_1.CheckIcon, {}) : (0, jsx_runtime_1.jsx)(copy_icon_1.CopyIcon, {}) }), (0, jsx_runtime_1.jsx)(react_core_1.Tooltip, { id: tooltipID, content: "Copy", position: "top", triggerRef: buttonRef })] }) }));
67
+ const actions = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_core_1.CodeBlockAction, { className: "pf-chatbot__message-code-block-default-action", children: [language && (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-code-block-language", children: language }), (0, jsx_runtime_1.jsx)(react_core_1.Button, { ref: buttonRef, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : 'Copy code', variant: "plain", className: "pf-chatbot__button--copy", onClick: (event) => handleCopy(event, children), children: copied ? (0, jsx_runtime_1.jsx)(check_icon_1.CheckIcon, {}) : (0, jsx_runtime_1.jsx)(copy_icon_1.CopyIcon, {}) }), (0, jsx_runtime_1.jsx)(react_core_1.Tooltip, { id: tooltipID, content: "Copy", position: "top", triggerRef: buttonRef })] }), customActions] }));
68
68
  return ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-code-block", ref: codeBlockRef, children: (0, jsx_runtime_1.jsxs)(react_core_1.CodeBlock, { actions: actions, children: [(0, jsx_runtime_1.jsx)(react_core_1.CodeBlockCode, { children: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: isExpandable ? ((0, jsx_runtime_1.jsx)(react_core_1.ExpandableSection, Object.assign({ variant: react_core_1.ExpandableSectionVariant.truncate, isExpanded: isExpanded, isDetached: true, toggleId: toggleId, contentId: contentId }, expandableSectionProps, { children: children }))) : (children) }) }), isExpandable && ((0, jsx_runtime_1.jsx)(react_core_1.ExpandableSectionToggle, Object.assign({ isExpanded: isExpanded, onToggle: onToggle, direction: "up", toggleId: toggleId, contentId: contentId, hasTruncatedContent: true, className: "pf-chatbot__message-code-toggle" }, expandableSectionToggleProps, { children: isExpanded ? finalExpandedText : finalCollapsedText })))] }) }));
69
69
  };
70
70
  exports.default = CodeBlockMessage;
@@ -1,7 +1,8 @@
1
1
  import { ReactNode } from 'react';
2
2
  import type { FunctionComponent, HTMLProps, MouseEvent as ReactMouseEvent, Ref } from 'react';
3
3
  import { Options } from 'react-markdown';
4
- import { AlertProps, AvatarProps, ButtonProps, ExpandableSectionProps, ExpandableSectionToggleProps, FormProps, LabelGroupProps } from '@patternfly/react-core';
4
+ import { AlertProps, AvatarProps, ButtonProps, FormProps, LabelGroupProps } from '@patternfly/react-core';
5
+ import { CodeBlockMessageProps } from './CodeBlockMessage/CodeBlockMessage';
5
6
  import { ActionProps } from '../ResponseActions/ResponseActions';
6
7
  import { SourcesCardProps } from '../SourcesCard';
7
8
  import { QuickStart, QuickstartAction } from './QuickStarts/types';
@@ -69,24 +70,7 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
69
70
  /** Label for the English "Loading message," displayed to screenreaders when loading a message */
70
71
  loadingWord?: string;
71
72
  /** Props for code blocks */
72
- codeBlockProps?: {
73
- /** Aria label applied to code blocks */
74
- 'aria-label'?: string;
75
- /** Class name applied to code blocks */
76
- className?: string;
77
- /** Whether code blocks are expandable */
78
- isExpandable?: boolean;
79
- /** Length of text initially shown in expandable code blocks; defaults to 10 characters */
80
- maxLength?: number;
81
- /** Additional props passed to expandable section if isExpandable is applied */
82
- expandableSectionProps?: Omit<ExpandableSectionProps, 'ref'>;
83
- /** Additional props passed to expandable toggle if isExpandable is applied */
84
- expandableSectionToggleProps?: ExpandableSectionToggleProps;
85
- /** Link text applied to expandable toggle when expanded */
86
- expandedText?: string;
87
- /** Link text applied to expandable toggle when collapsed */
88
- collapsedText?: string;
89
- };
73
+ codeBlockProps?: CodeBlockMessageProps;
90
74
  /** Props for quick responses */
91
75
  quickResponses?: QuickResponse[];
92
76
  /** Props for quick responses container */
@@ -493,6 +493,12 @@ describe('Message', () => {
493
493
  (0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "user", name: "User", content: CODE_MESSAGE, codeBlockProps: { 'aria-label': 'test' } }));
494
494
  expect(react_2.screen.getByRole('button', { name: 'test' })).toBeTruthy();
495
495
  });
496
+ it('should be able to add custom actions to CodeMessage', () => {
497
+ (0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "user", name: "User", content: CODE_MESSAGE, codeBlockProps: {
498
+ customActions: ((0, jsx_runtime_1.jsx)(react_core_1.CodeBlockAction, { children: (0, jsx_runtime_1.jsx)(react_core_1.Button, { children: "New custom action" }) }))
499
+ } }));
500
+ expect(react_2.screen.getByRole('button', { name: /New custom action/i })).toBeTruthy();
501
+ });
496
502
  it('should handle hasRoundAvatar correctly when it is true', () => {
497
503
  (0, react_2.render)((0, jsx_runtime_1.jsx)(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "Hi", hasRoundAvatar: true }));
498
504
  expect(react_2.screen.getByRole('img')).toBeTruthy();
package/dist/css/main.css CHANGED
@@ -189,6 +189,9 @@
189
189
  overflow: unset;
190
190
  }
191
191
  }
192
+ .pf-chatbot__content.pf-m-primary {
193
+ background-color: var(--pf-t--global--background--color--primary--default);
194
+ }
192
195
 
193
196
  @media screen and (min-width: 64rem) {
194
197
  .pf-chatbot--drawer .pf-chatbot__content,
@@ -1355,7 +1358,7 @@
1355
1358
  text-transform: uppercase;
1356
1359
  font-family: var(--pf-t--global--font--family--body);
1357
1360
  }
1358
- .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-v6-c-code-block__actions-item {
1361
+ .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-chatbot__message-code-block-default-action {
1359
1362
  display: flex;
1360
1363
  align-items: center;
1361
1364
  justify-content: space-between;
@@ -1363,10 +1366,10 @@
1363
1366
  font-size: var(--pf-t--global--font--size--sm);
1364
1367
  font-weight: var(--pf-t--global--font--weight--body--bold);
1365
1368
  }
1366
- .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-chatbot__button--copy.pf-v6-c-button {
1369
+ .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-v6-c-code-block__actions-item > .pf-v6-c-button.pf-m-plain {
1367
1370
  color: var(--pf-t--color--white);
1368
1371
  }
1369
- .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-chatbot__button--copy.pf-v6-c-button:hover, .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-chatbot__button--copy.pf-v6-c-button:focus {
1372
+ .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-v6-c-code-block__actions-item > .pf-v6-c-button.pf-m-plain:hover, .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-v6-c-code-block__actions-item > .pf-v6-c-button.pf-m-plain:focus {
1370
1373
  color: var(--pf-t--color--white);
1371
1374
  }
1372
1375
  .pf-chatbot__message-code-block .pf-v6-c-code-block__content {
@@ -1448,6 +1451,10 @@ li[id*=user-content-fn-]:has(> span > span > .pf-chatbot__message-text + .pf-cha
1448
1451
  margin-block-end: var(--pf-t--global--spacer--md);
1449
1452
  }
1450
1453
 
1454
+ .pf-chatbot__message-text.footnotes .data-footnote-backref {
1455
+ width: fit-content;
1456
+ }
1457
+
1451
1458
  .pf-chatbot__message--user .pf-chatbot__message-text {
1452
1459
  background-color: var(--pf-t--global--color--brand--default);
1453
1460
  color: var(--pf-t--global--text--color--on-brand--default);
@@ -1538,7 +1545,7 @@ li[id*=user-content-fn-]:has(> span > span > .pf-chatbot__message-text + .pf-cha
1538
1545
  text-transform: uppercase;
1539
1546
  font-family: var(--pf-t--global--font--family--body);
1540
1547
  }
1541
- .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-v6-c-code-block__actions-item {
1548
+ .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-chatbot__message-code-block-default-action {
1542
1549
  display: flex;
1543
1550
  align-items: center;
1544
1551
  justify-content: space-between;
@@ -1546,10 +1553,10 @@ li[id*=user-content-fn-]:has(> span > span > .pf-chatbot__message-text + .pf-cha
1546
1553
  font-size: var(--pf-t--global--font--size--sm);
1547
1554
  font-weight: var(--pf-t--global--font--weight--body--bold);
1548
1555
  }
1549
- .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-chatbot__button--copy.pf-v6-c-button {
1556
+ .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-v6-c-code-block__actions-item > .pf-v6-c-button.pf-m-plain {
1550
1557
  color: var(--pf-t--color--white);
1551
1558
  }
1552
- .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-chatbot__button--copy.pf-v6-c-button:hover, .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-chatbot__button--copy.pf-v6-c-button:focus {
1559
+ .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-v6-c-code-block__actions-item > .pf-v6-c-button.pf-m-plain:hover, .pf-chatbot__message-code-block .pf-v6-c-code-block__header .pf-v6-c-code-block__actions-item > .pf-v6-c-button.pf-m-plain:focus {
1553
1560
  color: var(--pf-t--color--white);
1554
1561
  }
1555
1562
  .pf-chatbot__message-code-block .pf-v6-c-code-block__content {
@@ -1639,6 +1646,10 @@ li[id*=user-content-fn-]:has(> span > span > .pf-chatbot__message-text + .pf-cha
1639
1646
  margin-block-end: var(--pf-t--global--spacer--md);
1640
1647
  }
1641
1648
 
1649
+ .pf-chatbot__message-text.footnotes .data-footnote-backref {
1650
+ width: fit-content;
1651
+ }
1652
+
1642
1653
  .pf-chatbot__message--user .pf-chatbot__message-text {
1643
1654
  background-color: var(--pf-t--global--color--brand--default);
1644
1655
  color: var(--pf-t--global--text--color--on-brand--default);
@@ -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/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/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;;AAEF;EACE;EACA;EACA;;AAEF;EACE;EACA;;AAKF;EA9BF;IA+BI;IACA;;;AAIF;EApCF;IAqCI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAXF;IAYI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;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;EACA;;AAEA;EACE;;;AAOJ;EACE;;;AC3IF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;;AAOJ;EAII;AAAA;AAAA;IACE;IACA;;;ACrBJ;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;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;;;AC5PN;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;IACA;;;AASJ;EACE;;;AAQF;EACE;;;AAIJ;EACE;EACA;;;AC3DF;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;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;;;AClKF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAEF;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;;;ACjGF;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;EACE;EACA;EACA;;AAKF;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;;;AC9IF;EACE;EACA;EACA;EACA;;AAEA;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;;;;AC9CN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;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;;;AAKN;EACE;EACA;EACA;;;AAIA;EACE;EACA;;;ACnFJ;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;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;ACvHN;EACE;EACA;;AACA;EACE;EACA;;;AJwJF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;AE7KJ;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;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;;;AAKN;EACE;EACA;EACA;;;AAIA;EACE;EACA;;;AGvFJ;EACE;EACA;EACA;EACA;EAGA;;;AFHF;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;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AGnHN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;AAGA;AAAA;EACE;;AAMF;EACE;EACA;;AAIJ;EACE;;;ACvCJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;ANjBJ;EACE;EACA;EACA;EACA;;AAEA;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;;;;AOjDN;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;ACnBJ;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC7BJ;EACE;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAKA;EACE;;;AAKF;EACE;;AAGF;EACE;;AAIA;EACE;;;ACnEN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;EACA;;;ACzCF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AAOJ;EACE;EACA;EACA;EACA;;;ACrDF;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;EACA;;;AC1DF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;EACA;;;AClCF;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;;AAEA;EACE;;AAGF;EACE;;AAGF;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;;AAGF;EACE;EACA;;;AC1HJ;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;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1BF;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;;;ACjCJ;EACE;EACA;EAEA;EACA;;AAEA;EACE;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;;ACSJ;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/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/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;;AAEF;EACE;EACA;EACA;;AAEF;EACE;EACA;;AAKF;EA9BF;IA+BI;IACA;;;AAIF;EApCF;IAqCI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAXF;IAYI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;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;EACA;;AAEA;EACE;;;AAOJ;EACE;;;AC3IF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;AAGF;EACE;;;AAOJ;EAII;AAAA;AAAA;IACE;IACA;;;ACzBJ;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;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;;;AC5PN;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;IACA;;;AASJ;EACE;;;AAQF;EACE;;;AAIJ;EACE;EACA;;;AC3DF;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;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;;;AClKF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAEF;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;;;ACjGF;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;EACE;EACA;EACA;;AAKF;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;;;AC9IF;EACE;EACA;EACA;EACA;;AAEA;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;;;;AC9CN;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;;;AAKN;EACE;EACA;EACA;;;AAIA;EACE;EACA;;;ACpFJ;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;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AC7HN;EACE;EACA;;AACA;EACE;EACA;;;AJwJF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;AE7KJ;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;;;AAKN;EACE;EACA;EACA;;;AAIA;EACE;EACA;;;AGxFJ;EACE;EACA;EACA;EACA;EAGA;;;AFHF;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;;;AAUJ;EAIE;;;AAIF;EAKE;;;AAIA;EACE;;;AAKF;EACE;EACA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAIJ;EACE;EACA;;;AASF;EACE;;AACA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AGzHN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;AAGA;AAAA;EACE;;AAMF;EACE;EACA;;AAIJ;EACE;;;ACvCJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;ANjBJ;EACE;EACA;EACA;EACA;;AAEA;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;;;;AOjDN;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;ACnBJ;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC7BJ;EACE;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAKA;EACE;;;AAKF;EACE;;AAGF;EACE;;AAIA;EACE;;;ACnEN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;EACA;;;ACzCF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AAOJ;EACE;EACA;EACA;EACA;;;ACrDF;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;EACA;;;AC1DF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;AASR;EACE;EACA;EACA;EACA;;;AClCF;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;;AAEA;EACE;;AAGF;EACE;;AAGF;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;;AAGF;EACE;EACA;;;AC1HJ;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;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1BF;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;;;ACjCJ;EACE;EACA;EAEA;EACA;;AAEA;EACE;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;;ACSJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA","file":"main.css"}
@@ -4,6 +4,8 @@ export interface ChatbotContentProps extends HTMLProps<HTMLDivElement> {
4
4
  children: React.ReactNode;
5
5
  /** Custom classname for the ChatbotContent component */
6
6
  className?: string;
7
+ /** Sets background color to primary */
8
+ isPrimary?: boolean;
7
9
  }
8
10
  export declare const ChatbotContent: FunctionComponent<ChatbotContentProps>;
9
11
  export default ChatbotContent;
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  };
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
13
  export const ChatbotContent = (_a) => {
14
- var { children, className } = _a, props = __rest(_a, ["children", "className"]);
15
- return (_jsx("div", Object.assign({ className: `pf-chatbot__content ${className !== null && className !== void 0 ? className : ''}` }, props, { children: children })));
14
+ var { children, className, isPrimary } = _a, props = __rest(_a, ["children", "className", "isPrimary"]);
15
+ return (_jsx("div", Object.assign({ className: `pf-chatbot__content ${isPrimary ? 'pf-m-primary' : ''} ${className !== null && className !== void 0 ? className : ''}` }, props, { children: children })));
16
16
  };
17
17
  export default ChatbotContent;
@@ -10,4 +10,8 @@ describe('ChatbotContent', () => {
10
10
  const { container } = render(_jsx(ChatbotContent, { className: "custom-class", children: "Chatbot Content" }));
11
11
  expect(container.querySelector('.custom-class')).toBeTruthy();
12
12
  });
13
+ it('should render ChatbotContent with primary class', () => {
14
+ const { container } = render(_jsx(ChatbotContent, { isPrimary: true, children: "Chatbot Content" }));
15
+ expect(container.querySelector('.pf-m-primary')).toBeTruthy();
16
+ });
13
17
  });
@@ -5,8 +5,10 @@ export interface ChatbotConversationHistoryDropdownProps extends Omit<DropdownPr
5
5
  menuItems: React.ReactNode;
6
6
  /** Optional classname applied to conversation settings dropdown */
7
7
  menuClassName?: string;
8
- /** Tooltip content and aria-label applied to conversation settings dropdown */
8
+ /** Tooltip content applied to conversation settings dropdown */
9
9
  label?: string;
10
+ /** Aria-label applied to conversation settings dropdown */
11
+ 'aria-label'?: string;
10
12
  /** Callback for when user selects item. */
11
13
  onSelect?: (event?: React.MouseEvent, value?: string | number) => void;
12
14
  /** Id applied to dropdown menu toggle */
@@ -3,11 +3,11 @@ import { useState } from 'react';
3
3
  // Import PatternFly components
4
4
  import { Tooltip, MenuToggle, Dropdown } from '@patternfly/react-core';
5
5
  import EllipsisIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
6
- export const ChatbotConversationHistoryDropdown = ({ menuItems, menuClassName, onSelect, label, id }) => {
6
+ export const ChatbotConversationHistoryDropdown = ({ menuItems, menuClassName, onSelect, label = 'Conversation options', 'aria-label': ariaLabel, id }) => {
7
7
  const [isOpen, setIsOpen] = useState(false);
8
- const toggle = (toggleRef) => (_jsx(Tooltip, { className: "pf-chatbot__tooltip", content: label !== null && label !== void 0 ? label : 'Conversation options', position: "bottom",
8
+ const toggle = (toggleRef) => (_jsx(Tooltip, { className: "pf-chatbot__tooltip", content: label, position: "bottom",
9
9
  // prevents VO announcements of both aria label and tooltip
10
- aria: "none", children: _jsx(MenuToggle, { className: "pf-chatbot__history-actions", variant: "plain", "aria-label": label !== null && label !== void 0 ? label : 'Conversation options', ref: toggleRef, isExpanded: isOpen, onClick: () => setIsOpen(!isOpen), id: id, role: "menuitem", children: _jsx(EllipsisIcon, {}) }) }));
10
+ aria: "none", children: _jsx(MenuToggle, { className: "pf-chatbot__history-actions", variant: "plain", "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : label, ref: toggleRef, isExpanded: isOpen, onClick: () => setIsOpen(!isOpen), id: id, role: "menuitem", children: _jsx(EllipsisIcon, {}) }) }));
11
11
  return (_jsx(Dropdown, { className: `pf-chatbot__selections ${menuClassName !== null && menuClassName !== void 0 ? menuClassName : ''}`, isOpen: isOpen, onSelect: (props) => {
12
12
  onSelect === null || onSelect === void 0 ? void 0 : onSelect(props);
13
13
  setIsOpen((prev) => !prev);
@@ -63,4 +63,8 @@ describe('ChatbotConversationHistoryDropdown', () => {
63
63
  expect(screen.queryByText('Actions dropdown')).toBeInTheDocument();
64
64
  });
65
65
  }));
66
+ it('should be able to set a custom aria-label', () => {
67
+ render(_jsx(ChatbotConversationHistoryDropdown, { menuItems: menuItems, "aria-label": "Custom conversation options" }));
68
+ expect(screen.queryByRole('menuitem', { name: /Custom conversation options/i })).toBeInTheDocument();
69
+ });
66
70
  });
@@ -10,17 +10,42 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
- import { useState } from 'react';
13
+ import { useState, useEffect, useRef } from 'react';
14
14
  import path from 'path-browserify';
15
15
  // Import PatternFly components
16
16
  import { CodeEditor } from '@patternfly/react-code-editor';
17
- import { Button, ModalBody, ModalFooter, ModalHeader, Stack, StackItem } from '@patternfly/react-core';
17
+ import { Button, getResizeObserver, ModalBody, ModalFooter, ModalHeader, Stack, StackItem } from '@patternfly/react-core';
18
18
  import FileDetails, { extensionToLanguage } from '../FileDetails';
19
19
  import { ChatbotDisplayMode } from '../Chatbot';
20
20
  import ChatbotModal from '../ChatbotModal/ChatbotModal';
21
21
  export const CodeModal = (_a) => {
22
22
  var { fileName, code, codeEditorControlClassName: codeEditorClassName, handleModalToggle, isCopyEnabled, isLineNumbersVisible, isModalOpen, isReadOnly, onPrimaryAction, onSecondaryAction, primaryActionBtn, secondaryActionBtn, title, displayMode = ChatbotDisplayMode.default, isCompact, modalHeaderClassName, modalBodyClassName, modalFooterClassName } = _a, props = __rest(_a, ["fileName", "code", "codeEditorControlClassName", "handleModalToggle", "isCopyEnabled", "isLineNumbersVisible", "isModalOpen", "isReadOnly", "onPrimaryAction", "onSecondaryAction", "primaryActionBtn", "secondaryActionBtn", "title", "displayMode", "isCompact", "modalHeaderClassName", "modalBodyClassName", "modalFooterClassName"]);
23
23
  const [newCode, setNewCode] = useState(code);
24
+ const [editorInstance, setEditorInstance] = useState(null);
25
+ const [isEditorReady, setIsEditorReady] = useState(false);
26
+ const containerRef = useRef(null);
27
+ useEffect(() => {
28
+ if (!isModalOpen || !isEditorReady || !editorInstance || !containerRef.current) {
29
+ return;
30
+ }
31
+ const handleResize = () => {
32
+ if (editorInstance && isEditorReady && isModalOpen) {
33
+ try {
34
+ window.requestAnimationFrame(() => {
35
+ editorInstance.layout();
36
+ });
37
+ }
38
+ catch (error) {
39
+ // eslint-disable-next-line no-console
40
+ console.error('ChatBot code modal layout error:', error);
41
+ }
42
+ }
43
+ };
44
+ const observer = getResizeObserver(containerRef.current, handleResize);
45
+ return () => {
46
+ observer();
47
+ };
48
+ }, [editorInstance, isEditorReady, isModalOpen]);
24
49
  const handlePrimaryAction = (_event) => {
25
50
  handleModalToggle(_event);
26
51
  if (!isReadOnly) {
@@ -35,18 +60,25 @@ export const CodeModal = (_a) => {
35
60
  onSecondaryAction(_event);
36
61
  };
37
62
  const onEditorDidMount = (editor, monaco) => {
38
- editor.layout();
39
- editor.focus();
63
+ setEditorInstance(editor);
40
64
  monaco.editor.getModels()[0].updateOptions({ tabSize: 5 });
65
+ if (containerRef.current) {
66
+ setIsEditorReady(true);
67
+ editor.layout();
68
+ editor.focus();
69
+ }
41
70
  };
42
71
  const onCodeChange = (value) => {
43
72
  if (!isReadOnly) {
44
73
  setNewCode(value);
45
74
  }
46
75
  };
47
- const modal = (_jsxs(ChatbotModal, { isOpen: isModalOpen, onClose: handleModalToggle, ouiaId: "CodeModal", "aria-labelledby": "code-modal-title", "aria-describedby": "code-modal", className: `pf-chatbot__code-modal ${isCompact ? 'pf-m-compact' : ''} pf-chatbot__code-modal--${displayMode}`, displayMode: displayMode, isCompact: isCompact, children: [_jsx(ModalHeader, { className: modalHeaderClassName, title: title, labelId: "code-modal-title" }), _jsx(ModalBody, { className: modalBodyClassName, id: "code-modal-body", children: _jsxs(Stack, { className: "pf-chatbot__code-modal-body", children: [_jsx(StackItem, { className: "pf-chatbot__code-modal-file-details", children: _jsx(FileDetails, { fileName: fileName }) }), _jsx(StackItem, { className: "pf-chatbot__code-modal-editor", children: _jsx(CodeEditor, Object.assign({ isDarkTheme: true, isLineNumbersVisible: isLineNumbersVisible, isLanguageLabelVisible: true, isCopyEnabled: isCopyEnabled, isReadOnly: isReadOnly, code: newCode, language: extensionToLanguage[path.extname(fileName).slice(1)], onEditorDidMount: onEditorDidMount, onCodeChange: onCodeChange, className: codeEditorClassName, isFullHeight: true, options: {
76
+ const modal = (_jsxs(ChatbotModal, { isOpen: isModalOpen, onClose: handleModalToggle, ouiaId: "CodeModal", "aria-labelledby": "code-modal-title", "aria-describedby": "code-modal", className: `pf-chatbot__code-modal ${isCompact ? 'pf-m-compact' : ''} pf-chatbot__code-modal--${displayMode}`, displayMode: displayMode, isCompact: isCompact, children: [_jsx(ModalHeader, { className: modalHeaderClassName, title: title, labelId: "code-modal-title" }), _jsx(ModalBody, { className: modalBodyClassName, id: "code-modal-body", children: _jsxs(Stack, { className: "pf-chatbot__code-modal-body", children: [_jsx(StackItem, { className: "pf-chatbot__code-modal-file-details", children: _jsx(FileDetails, { fileName: fileName }) }), _jsx("div", { className: "pf-v6-l-stack__item pf-chatbot__code-modal-editor", ref: containerRef, children: _jsx(CodeEditor, Object.assign({ isDarkTheme: true, isLineNumbersVisible: isLineNumbersVisible, isLanguageLabelVisible: true, isCopyEnabled: isCopyEnabled, isReadOnly: isReadOnly, code: newCode, language: extensionToLanguage[path.extname(fileName).slice(1)], onEditorDidMount: onEditorDidMount, onCodeChange: onCodeChange, className: codeEditorClassName, isFullHeight: true, options: {
48
77
  glyphMargin: false,
49
- folding: false
78
+ folding: false,
79
+ // prevents Monaco from handling resizing itself
80
+ // was causing ResizeObserver issues
81
+ automaticLayout: false
50
82
  } }, props)) })] }) }), _jsxs(ModalFooter, { className: modalFooterClassName, children: [_jsx(Button, { isBlock: true, variant: "primary", onClick: handlePrimaryAction, form: "code-modal-form", children: primaryActionBtn }, "code-modal-primary"), _jsx(Button, { isBlock: true, variant: "link", onClick: handleSecondaryAction, children: secondaryActionBtn }, "code-modal-secondary")] })] }));
51
83
  return modal;
52
84
  };
@@ -16,6 +16,8 @@ export interface CodeBlockMessageProps {
16
16
  expandedText?: string;
17
17
  /** Link text applied to expandable toggle when collapsed */
18
18
  collapsedText?: string;
19
+ /** Custom actions added to header of code block, after any default actions such as the "copy" action. */
20
+ customActions?: React.ReactNode;
19
21
  }
20
- declare const CodeBlockMessage: ({ children, className, "aria-label": ariaLabel, isExpandable, expandableSectionProps, expandableSectionToggleProps, expandedText, collapsedText, ...props }: CodeBlockMessageProps) => import("react/jsx-runtime").JSX.Element;
22
+ declare const CodeBlockMessage: ({ children, className, "aria-label": ariaLabel, isExpandable, expandableSectionProps, expandableSectionToggleProps, expandedText, collapsedText, customActions, ...props }: CodeBlockMessageProps) => import("react/jsx-runtime").JSX.Element;
21
23
  export default CodeBlockMessage;
@@ -22,7 +22,7 @@ const DEFAULT_EXPANDED_TEXT = 'Show less';
22
22
  const DEFAULT_COLLAPSED_TEXT = 'Show more';
23
23
  const CodeBlockMessage = (_a) => {
24
24
  var _b;
25
- var { children, className, 'aria-label': ariaLabel, isExpandable = false, expandableSectionProps, expandableSectionToggleProps, expandedText = DEFAULT_EXPANDED_TEXT, collapsedText = DEFAULT_COLLAPSED_TEXT } = _a, props = __rest(_a, ["children", "className", 'aria-label', "isExpandable", "expandableSectionProps", "expandableSectionToggleProps", "expandedText", "collapsedText"]);
25
+ var { children, className, 'aria-label': ariaLabel, isExpandable = false, expandableSectionProps, expandableSectionToggleProps, expandedText = DEFAULT_EXPANDED_TEXT, collapsedText = DEFAULT_COLLAPSED_TEXT, customActions } = _a, props = __rest(_a, ["children", "className", 'aria-label', "isExpandable", "expandableSectionProps", "expandableSectionToggleProps", "expandedText", "collapsedText", "customActions"]);
26
26
  const [copied, setCopied] = useState(false);
27
27
  const [isExpanded, setIsExpanded] = useState(false);
28
28
  const buttonRef = useRef();
@@ -62,7 +62,7 @@ const CodeBlockMessage = (_a) => {
62
62
  return (_jsx("code", Object.assign({}, props, { className: "pf-chatbot__message-inline-code", children: children })));
63
63
  }
64
64
  // Setup code block header
65
- const actions = (_jsx(_Fragment, { children: _jsxs(CodeBlockAction, { children: [language && _jsx("div", { className: "pf-chatbot__message-code-block-language", children: language }), _jsx(Button, { ref: buttonRef, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : 'Copy code', variant: "plain", className: "pf-chatbot__button--copy", onClick: (event) => handleCopy(event, children), children: copied ? _jsx(CheckIcon, {}) : _jsx(CopyIcon, {}) }), _jsx(Tooltip, { id: tooltipID, content: "Copy", position: "top", triggerRef: buttonRef })] }) }));
65
+ const actions = (_jsxs(_Fragment, { children: [_jsxs(CodeBlockAction, { className: "pf-chatbot__message-code-block-default-action", children: [language && _jsx("div", { className: "pf-chatbot__message-code-block-language", children: language }), _jsx(Button, { ref: buttonRef, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : 'Copy code', variant: "plain", className: "pf-chatbot__button--copy", onClick: (event) => handleCopy(event, children), children: copied ? _jsx(CheckIcon, {}) : _jsx(CopyIcon, {}) }), _jsx(Tooltip, { id: tooltipID, content: "Copy", position: "top", triggerRef: buttonRef })] }), customActions] }));
66
66
  return (_jsx("div", { className: "pf-chatbot__message-code-block", ref: codeBlockRef, children: _jsxs(CodeBlock, { actions: actions, children: [_jsx(CodeBlockCode, { children: _jsx(_Fragment, { children: isExpandable ? (_jsx(ExpandableSection, Object.assign({ variant: ExpandableSectionVariant.truncate, isExpanded: isExpanded, isDetached: true, toggleId: toggleId, contentId: contentId }, expandableSectionProps, { children: children }))) : (children) }) }), isExpandable && (_jsx(ExpandableSectionToggle, Object.assign({ isExpanded: isExpanded, onToggle: onToggle, direction: "up", toggleId: toggleId, contentId: contentId, hasTruncatedContent: true, className: "pf-chatbot__message-code-toggle" }, expandableSectionToggleProps, { children: isExpanded ? finalExpandedText : finalCollapsedText })))] }) }));
67
67
  };
68
68
  export default CodeBlockMessage;
@@ -1,7 +1,8 @@
1
1
  import { ReactNode } from 'react';
2
2
  import type { FunctionComponent, HTMLProps, MouseEvent as ReactMouseEvent, Ref } from 'react';
3
3
  import { Options } from 'react-markdown';
4
- import { AlertProps, AvatarProps, ButtonProps, ExpandableSectionProps, ExpandableSectionToggleProps, FormProps, LabelGroupProps } from '@patternfly/react-core';
4
+ import { AlertProps, AvatarProps, ButtonProps, FormProps, LabelGroupProps } from '@patternfly/react-core';
5
+ import { CodeBlockMessageProps } from './CodeBlockMessage/CodeBlockMessage';
5
6
  import { ActionProps } from '../ResponseActions/ResponseActions';
6
7
  import { SourcesCardProps } from '../SourcesCard';
7
8
  import { QuickStart, QuickstartAction } from './QuickStarts/types';
@@ -69,24 +70,7 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
69
70
  /** Label for the English "Loading message," displayed to screenreaders when loading a message */
70
71
  loadingWord?: string;
71
72
  /** Props for code blocks */
72
- codeBlockProps?: {
73
- /** Aria label applied to code blocks */
74
- 'aria-label'?: string;
75
- /** Class name applied to code blocks */
76
- className?: string;
77
- /** Whether code blocks are expandable */
78
- isExpandable?: boolean;
79
- /** Length of text initially shown in expandable code blocks; defaults to 10 characters */
80
- maxLength?: number;
81
- /** Additional props passed to expandable section if isExpandable is applied */
82
- expandableSectionProps?: Omit<ExpandableSectionProps, 'ref'>;
83
- /** Additional props passed to expandable toggle if isExpandable is applied */
84
- expandableSectionToggleProps?: ExpandableSectionToggleProps;
85
- /** Link text applied to expandable toggle when expanded */
86
- expandedText?: string;
87
- /** Link text applied to expandable toggle when collapsed */
88
- collapsedText?: string;
89
- };
73
+ codeBlockProps?: CodeBlockMessageProps;
90
74
  /** Props for quick responses */
91
75
  quickResponses?: QuickResponse[];
92
76
  /** Props for quick responses container */
@@ -16,7 +16,7 @@ import userEvent from '@testing-library/user-event';
16
16
  import { monitorSampleAppQuickStart } from './QuickStarts/monitor-sampleapp-quickstart';
17
17
  import { monitorSampleAppQuickStartWithImage } from './QuickStarts/monitor-sampleapp-quickstart-with-image';
18
18
  import rehypeExternalLinks from '../__mocks__/rehype-external-links';
19
- import { AlertActionLink } from '@patternfly/react-core';
19
+ import { AlertActionLink, Button, CodeBlockAction } from '@patternfly/react-core';
20
20
  const ALL_ACTIONS = [
21
21
  { label: /Good response/i },
22
22
  { label: /Bad response/i },
@@ -488,6 +488,12 @@ describe('Message', () => {
488
488
  render(_jsx(Message, { avatar: "./img", role: "user", name: "User", content: CODE_MESSAGE, codeBlockProps: { 'aria-label': 'test' } }));
489
489
  expect(screen.getByRole('button', { name: 'test' })).toBeTruthy();
490
490
  });
491
+ it('should be able to add custom actions to CodeMessage', () => {
492
+ render(_jsx(Message, { avatar: "./img", role: "user", name: "User", content: CODE_MESSAGE, codeBlockProps: {
493
+ customActions: (_jsx(CodeBlockAction, { children: _jsx(Button, { children: "New custom action" }) }))
494
+ } }));
495
+ expect(screen.getByRole('button', { name: /New custom action/i })).toBeTruthy();
496
+ });
491
497
  it('should handle hasRoundAvatar correctly when it is true', () => {
492
498
  render(_jsx(Message, { avatar: "./img", role: "user", name: "User", content: "Hi", hasRoundAvatar: true }));
493
499
  expect(screen.getByRole('img')).toBeTruthy();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "6.4.1",
3
+ "version": "6.5.0-prerelease.2",
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",
@@ -5,8 +5,8 @@ import ChatbotConversationHistoryNav, {
5
5
  } from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';
6
6
  import { Checkbox, DropdownItem, DropdownList } from '@patternfly/react-core';
7
7
 
8
- const menuItems = [
9
- <DropdownList key="list-1">
8
+ const generateMenuItems = (id: string) => [
9
+ <DropdownList key={`header-drawer-with-actions-example-conversation-${id}-dropdown`}>
10
10
  <DropdownItem value="Download" id="Download">
11
11
  Download
12
12
  </DropdownItem>
@@ -23,29 +23,29 @@ const menuItems = [
23
23
  ];
24
24
 
25
25
  const conversations: { [key: string]: Conversation[] } = {
26
- Today: [{ id: '1', text: 'Red Hat products and services', menuItems }],
26
+ Today: [{ id: '1', text: 'Red Hat products and services', menuItems: generateMenuItems('1') }],
27
27
  'This month': [
28
28
  {
29
29
  id: '2',
30
30
  text: 'Enterprise Linux installation and setup',
31
- menuItems
31
+ menuItems: generateMenuItems('2')
32
32
  },
33
- { id: '3', text: 'Troubleshoot system crash', menuItems }
33
+ { id: '3', text: 'Troubleshoot system crash', menuItems: generateMenuItems('3') }
34
34
  ],
35
35
  March: [
36
- { id: '4', text: 'Ansible security and updates', menuItems },
37
- { id: '5', text: 'Red Hat certification', menuItems },
38
- { id: '6', text: 'Lightspeed user documentation', menuItems }
36
+ { id: '4', text: 'Ansible security and updates', menuItems: generateMenuItems('4') },
37
+ { id: '5', text: 'Red Hat certification', menuItems: generateMenuItems('5') },
38
+ { id: '6', text: 'Lightspeed user documentation', menuItems: generateMenuItems('6') }
39
39
  ],
40
40
  February: [
41
- { id: '7', text: 'Crashing pod assistance', menuItems },
42
- { id: '8', text: 'OpenShift AI pipelines', menuItems },
43
- { id: '9', text: 'Updating subscription plan', menuItems },
44
- { id: '10', text: 'Red Hat licensing options', menuItems }
41
+ { id: '7', text: 'Crashing pod assistance', menuItems: generateMenuItems('7') },
42
+ { id: '8', text: 'OpenShift AI pipelines', menuItems: generateMenuItems('8') },
43
+ { id: '9', text: 'Updating subscription plan', menuItems: generateMenuItems('9') },
44
+ { id: '10', text: 'Red Hat licensing options', menuItems: generateMenuItems('10') }
45
45
  ],
46
46
  January: [
47
- { id: '11', text: 'RHEL system performance', menuItems },
48
- { id: '12', text: 'Manage user accounts', menuItems }
47
+ { id: '11', text: 'RHEL system performance', menuItems: generateMenuItems('11') },
48
+ { id: '12', text: 'Manage user accounts', menuItems: generateMenuItems('12') }
49
49
  ]
50
50
  };
51
51
 
@@ -5,8 +5,8 @@ import ChatbotConversationHistoryNav, {
5
5
  } from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';
6
6
  import { Checkbox, DropdownItem, DropdownList } from '@patternfly/react-core';
7
7
 
8
- const menuItems = [
9
- <DropdownList key="list-1">
8
+ const generateMenuItems = (id: string) => [
9
+ <DropdownList key={`header-drawer-with-selections-example-conversation-${id}-dropdown`}>
10
10
  <DropdownItem value="Download" id="Download">
11
11
  Download
12
12
  </DropdownItem>
@@ -29,29 +29,29 @@ export const ChatbotHeaderDrawerWithSelection: FunctionComponent = () => {
29
29
  const displayMode = ChatbotDisplayMode.embedded;
30
30
 
31
31
  const conversations: { [key: string]: Conversation[] } = {
32
- Today: [{ id: '1', text: 'Red Hat products and services', menuItems }],
32
+ Today: [{ id: '1', text: 'Red Hat products and services', menuItems: generateMenuItems('1') }],
33
33
  'This month': [
34
34
  {
35
35
  id: '2',
36
36
  text: 'Enterprise Linux installation and setup',
37
- menuItems
37
+ menuItems: generateMenuItems('2')
38
38
  },
39
- { id: '3', text: 'Troubleshoot system crash', menuItems }
39
+ { id: '3', text: 'Troubleshoot system crash', menuItems: generateMenuItems('3') }
40
40
  ],
41
41
  March: [
42
- { id: '4', text: 'Ansible security and updates', menuItems },
43
- { id: '5', text: 'Red Hat certification', menuItems },
44
- { id: '6', text: 'Lightspeed user documentation', menuItems }
42
+ { id: '4', text: 'Ansible security and updates', menuItems: generateMenuItems('4') },
43
+ { id: '5', text: 'Red Hat certification', menuItems: generateMenuItems('5') },
44
+ { id: '6', text: 'Lightspeed user documentation', menuItems: generateMenuItems('6') }
45
45
  ],
46
46
  February: [
47
- { id: '7', text: 'Crashing pod assistance', menuItems },
48
- { id: '8', text: 'OpenShift AI pipelines', menuItems },
49
- { id: '9', text: 'Updating subscription plan', menuItems },
50
- { id: '10', text: 'Red Hat licensing options', menuItems }
47
+ { id: '7', text: 'Crashing pod assistance', menuItems: generateMenuItems('7') },
48
+ { id: '8', text: 'OpenShift AI pipelines', menuItems: generateMenuItems('8') },
49
+ { id: '9', text: 'Updating subscription plan', menuItems: generateMenuItems('9') },
50
+ { id: '10', text: 'Red Hat licensing options', menuItems: generateMenuItems('10') }
51
51
  ],
52
52
  January: [
53
- { id: '11', text: 'RHEL system performance', menuItems },
54
- { id: '12', text: 'Manage user accounts', menuItems }
53
+ { id: '11', text: 'RHEL system performance', menuItems: generateMenuItems('11') },
54
+ { id: '12', text: 'Manage user accounts', menuItems: generateMenuItems('12') }
55
55
  ]
56
56
  };
57
57
 
@@ -66,7 +66,7 @@ export const ChatbotMessageBarDefaultAttachExample: FunctionComponent = () => {
66
66
  };
67
67
 
68
68
  const initialMenuItems = [
69
- <DropdownList key="list-1">
69
+ <DropdownList key="message-bar-attach-menu-items">
70
70
  <DropdownItem className="pf-chatbot-source-details-dropdown-item" value="auth-operator Pod" id="0">
71
71
  <SourceDetailsMenuItem
72
72
  icon={
@@ -93,7 +93,7 @@ export const ChatbotMessageBarDefaultAttachExample: FunctionComponent = () => {
93
93
  />
94
94
  </DropdownItem>
95
95
  </DropdownList>,
96
- <DropdownGroup key="group2">
96
+ <DropdownGroup key="message-bar-attach-dropdown-group">
97
97
  <DropdownList>
98
98
  <DropdownItem value="Alerts" id="1" icon={<BellIcon />}>
99
99
  Alerts
@@ -20,7 +20,7 @@ import '@patternfly/chatbot/dist/css/main.css';
20
20
  import { cloneElement, FunctionComponent, isValidElement, ReactNode, useState, Children } from 'react';
21
21
 
22
22
  const initialMenuItems = [
23
- <DropdownList key="list-1">
23
+ <DropdownList key="attachment-menu-example-initial-menu-items">
24
24
  <DropdownItem value="auth-operator Pod" id="0" className="pf-chatbot-source-details-dropdown-item">
25
25
  <SourceDetailsMenuItem
26
26
  icon={
@@ -47,7 +47,7 @@ const initialMenuItems = [
47
47
  />
48
48
  </DropdownItem>
49
49
  </DropdownList>,
50
- <DropdownGroup key="group2">
50
+ <DropdownGroup key="attachment-menu-example-initial-group">
51
51
  <DropdownList>
52
52
  <DropdownItem value="Alerts" id="1" icon={<BellIcon />}>
53
53
  Alerts
@@ -230,7 +230,7 @@ export const ChatbotDemo: FunctionComponent = () => {
230
230
  id: '1',
231
231
  text: 'Hello, can you give me an example of what you can do?',
232
232
  menuItems: (
233
- <DropdownList key={`list-1`}>
233
+ <DropdownList key="transcript-example-initial-menu-items">
234
234
  <DropdownItem
235
235
  value="Download"
236
236
  id={`Download-1`}
@@ -12,6 +12,10 @@
12
12
  @media screen and (max-height: 518px) {
13
13
  overflow: unset;
14
14
  }
15
+
16
+ &.pf-m-primary {
17
+ background-color: var(--pf-t--global--background--color--primary--default);
18
+ }
15
19
  }
16
20
 
17
21
  // ============================================================================
@@ -11,4 +11,9 @@ describe('ChatbotContent', () => {
11
11
  const { container } = render(<ChatbotContent className="custom-class">Chatbot Content</ChatbotContent>);
12
12
  expect(container.querySelector('.custom-class')).toBeTruthy();
13
13
  });
14
+
15
+ it('should render ChatbotContent with primary class', () => {
16
+ const { container } = render(<ChatbotContent isPrimary>Chatbot Content</ChatbotContent>);
17
+ expect(container.querySelector('.pf-m-primary')).toBeTruthy();
18
+ });
14
19
  });
@@ -8,14 +8,17 @@ export interface ChatbotContentProps extends HTMLProps<HTMLDivElement> {
8
8
  children: React.ReactNode;
9
9
  /** Custom classname for the ChatbotContent component */
10
10
  className?: string;
11
+ /** Sets background color to primary */
12
+ isPrimary?: boolean;
11
13
  }
12
14
 
13
15
  export const ChatbotContent: FunctionComponent<ChatbotContentProps> = ({
14
16
  children,
15
17
  className,
18
+ isPrimary,
16
19
  ...props
17
20
  }: ChatbotContentProps) => (
18
- <div className={`pf-chatbot__content ${className ?? ''}`} {...props}>
21
+ <div className={`pf-chatbot__content ${isPrimary ? 'pf-m-primary' : ''} ${className ?? ''}`} {...props}>
19
22
  {children}
20
23
  </div>
21
24
  );
@@ -78,4 +78,9 @@ describe('ChatbotConversationHistoryDropdown', () => {
78
78
  expect(screen.queryByText('Actions dropdown')).toBeInTheDocument();
79
79
  });
80
80
  });
81
+
82
+ it('should be able to set a custom aria-label', () => {
83
+ render(<ChatbotConversationHistoryDropdown menuItems={menuItems} aria-label="Custom conversation options" />);
84
+ expect(screen.queryByRole('menuitem', { name: /Custom conversation options/i })).toBeInTheDocument();
85
+ });
81
86
  });
@@ -15,8 +15,10 @@ export interface ChatbotConversationHistoryDropdownProps extends Omit<DropdownPr
15
15
  menuItems: React.ReactNode;
16
16
  /** Optional classname applied to conversation settings dropdown */
17
17
  menuClassName?: string;
18
- /** Tooltip content and aria-label applied to conversation settings dropdown */
18
+ /** Tooltip content applied to conversation settings dropdown */
19
19
  label?: string;
20
+ /** Aria-label applied to conversation settings dropdown */
21
+ 'aria-label'?: string;
20
22
  /** Callback for when user selects item. */
21
23
  onSelect?: (event?: React.MouseEvent, value?: string | number) => void;
22
24
  /** Id applied to dropdown menu toggle */
@@ -27,7 +29,8 @@ export const ChatbotConversationHistoryDropdown: FunctionComponent<ChatbotConver
27
29
  menuItems,
28
30
  menuClassName,
29
31
  onSelect,
30
- label,
32
+ label = 'Conversation options',
33
+ 'aria-label': ariaLabel,
31
34
  id
32
35
  }: ChatbotConversationHistoryDropdownProps) => {
33
36
  const [isOpen, setIsOpen] = useState(false);
@@ -35,7 +38,7 @@ export const ChatbotConversationHistoryDropdown: FunctionComponent<ChatbotConver
35
38
  const toggle = (toggleRef: Ref<MenuToggleElement>) => (
36
39
  <Tooltip
37
40
  className="pf-chatbot__tooltip"
38
- content={label ?? 'Conversation options'}
41
+ content={label}
39
42
  position="bottom"
40
43
  // prevents VO announcements of both aria label and tooltip
41
44
  aria="none"
@@ -43,7 +46,7 @@ export const ChatbotConversationHistoryDropdown: FunctionComponent<ChatbotConver
43
46
  <MenuToggle
44
47
  className="pf-chatbot__history-actions"
45
48
  variant="plain"
46
- aria-label={label ?? 'Conversation options'}
49
+ aria-label={ariaLabel ?? label}
47
50
  ref={toggleRef}
48
51
  isExpanded={isOpen}
49
52
  onClick={() => setIsOpen(!isOpen)}
@@ -1,13 +1,23 @@
1
1
  // ============================================================================
2
2
  // Code Modal - Chatbot Modal with Code Editor
3
3
  // ============================================================================
4
+
4
5
  import type { FunctionComponent, MouseEvent } from 'react';
5
- import { useState } from 'react';
6
+ import { useState, useEffect, useRef } from 'react';
6
7
  import path from 'path-browserify';
8
+ import type monaco from 'monaco-editor';
7
9
 
8
10
  // Import PatternFly components
9
11
  import { CodeEditor } from '@patternfly/react-code-editor';
10
- import { Button, ModalBody, ModalFooter, ModalHeader, Stack, StackItem } from '@patternfly/react-core';
12
+ import {
13
+ Button,
14
+ getResizeObserver,
15
+ ModalBody,
16
+ ModalFooter,
17
+ ModalHeader,
18
+ Stack,
19
+ StackItem
20
+ } from '@patternfly/react-core';
11
21
  import FileDetails, { extensionToLanguage } from '../FileDetails';
12
22
  import { ChatbotDisplayMode } from '../Chatbot';
13
23
  import ChatbotModal from '../ChatbotModal/ChatbotModal';
@@ -73,6 +83,34 @@ export const CodeModal: FunctionComponent<CodeModalProps> = ({
73
83
  ...props
74
84
  }: CodeModalProps) => {
75
85
  const [newCode, setNewCode] = useState(code);
86
+ const [editorInstance, setEditorInstance] = useState<monaco.editor.IStandaloneCodeEditor | null>(null);
87
+ const [isEditorReady, setIsEditorReady] = useState(false);
88
+ const containerRef = useRef<HTMLDivElement>(null);
89
+
90
+ useEffect(() => {
91
+ if (!isModalOpen || !isEditorReady || !editorInstance || !containerRef.current) {
92
+ return;
93
+ }
94
+
95
+ const handleResize = () => {
96
+ if (editorInstance && isEditorReady && isModalOpen) {
97
+ try {
98
+ window.requestAnimationFrame(() => {
99
+ editorInstance.layout();
100
+ });
101
+ } catch (error) {
102
+ // eslint-disable-next-line no-console
103
+ console.error('ChatBot code modal layout error:', error);
104
+ }
105
+ }
106
+ };
107
+
108
+ const observer = getResizeObserver(containerRef.current, handleResize);
109
+
110
+ return () => {
111
+ observer();
112
+ };
113
+ }, [editorInstance, isEditorReady, isModalOpen]);
76
114
 
77
115
  const handlePrimaryAction = (_event: MouseEvent | MouseEvent | KeyboardEvent) => {
78
116
  handleModalToggle(_event);
@@ -89,9 +127,15 @@ export const CodeModal: FunctionComponent<CodeModalProps> = ({
89
127
  };
90
128
 
91
129
  const onEditorDidMount = (editor, monaco) => {
92
- editor.layout();
93
- editor.focus();
130
+ setEditorInstance(editor);
131
+
94
132
  monaco.editor.getModels()[0].updateOptions({ tabSize: 5 });
133
+
134
+ if (containerRef.current) {
135
+ setIsEditorReady(true);
136
+ editor.layout();
137
+ editor.focus();
138
+ }
95
139
  };
96
140
 
97
141
  const onCodeChange = (value: string) => {
@@ -117,7 +161,7 @@ export const CodeModal: FunctionComponent<CodeModalProps> = ({
117
161
  <StackItem className="pf-chatbot__code-modal-file-details">
118
162
  <FileDetails fileName={fileName} />
119
163
  </StackItem>
120
- <StackItem className="pf-chatbot__code-modal-editor">
164
+ <div className="pf-v6-l-stack__item pf-chatbot__code-modal-editor" ref={containerRef}>
121
165
  <CodeEditor
122
166
  isDarkTheme
123
167
  isLineNumbersVisible={isLineNumbersVisible}
@@ -132,11 +176,14 @@ export const CodeModal: FunctionComponent<CodeModalProps> = ({
132
176
  isFullHeight
133
177
  options={{
134
178
  glyphMargin: false,
135
- folding: false
179
+ folding: false,
180
+ // prevents Monaco from handling resizing itself
181
+ // was causing ResizeObserver issues
182
+ automaticLayout: false
136
183
  }}
137
184
  {...props}
138
185
  />
139
- </StackItem>
186
+ </div>
140
187
  </Stack>
141
188
  </ModalBody>
142
189
  <ModalFooter className={modalFooterClassName}>
@@ -30,7 +30,8 @@
30
30
  font-family: var(--pf-t--global--font--family--body);
31
31
  }
32
32
 
33
- .pf-v6-c-code-block__actions-item {
33
+ // we are overriding some default PatternFly positioning here - it's only necessary for the first two items
34
+ .pf-chatbot__message-code-block-default-action {
34
35
  display: flex;
35
36
  align-items: center;
36
37
  justify-content: space-between;
@@ -39,7 +40,7 @@
39
40
  font-weight: var(--pf-t--global--font--weight--body--bold);
40
41
  }
41
42
 
42
- .pf-chatbot__button--copy.pf-v6-c-button {
43
+ .pf-v6-c-code-block__actions-item > .pf-v6-c-button.pf-m-plain {
43
44
  color: var(--pf-t--color--white); // same in light + dark theme
44
45
 
45
46
  &:hover,
@@ -37,6 +37,8 @@ export interface CodeBlockMessageProps {
37
37
  expandedText?: string;
38
38
  /** Link text applied to expandable toggle when collapsed */
39
39
  collapsedText?: string;
40
+ /** Custom actions added to header of code block, after any default actions such as the "copy" action. */
41
+ customActions?: React.ReactNode;
40
42
  }
41
43
 
42
44
  const DEFAULT_EXPANDED_TEXT = 'Show less';
@@ -51,6 +53,7 @@ const CodeBlockMessage = ({
51
53
  expandableSectionToggleProps,
52
54
  expandedText = DEFAULT_EXPANDED_TEXT,
53
55
  collapsedText = DEFAULT_COLLAPSED_TEXT,
56
+ customActions,
54
57
  ...props
55
58
  }: CodeBlockMessageProps) => {
56
59
  const [copied, setCopied] = useState(false);
@@ -114,7 +117,7 @@ const CodeBlockMessage = ({
114
117
  // Setup code block header
115
118
  const actions = (
116
119
  <>
117
- <CodeBlockAction>
120
+ <CodeBlockAction className="pf-chatbot__message-code-block-default-action">
118
121
  {language && <div className="pf-chatbot__message-code-block-language">{language}</div>}
119
122
  <Button
120
123
  ref={buttonRef}
@@ -127,6 +130,7 @@ const CodeBlockMessage = ({
127
130
  </Button>
128
131
  <Tooltip id={tooltipID} content="Copy" position="top" triggerRef={buttonRef} />
129
132
  </CodeBlockAction>
133
+ {customActions}
130
134
  </>
131
135
  );
132
136
 
@@ -6,7 +6,7 @@ import userEvent from '@testing-library/user-event';
6
6
  import { monitorSampleAppQuickStart } from './QuickStarts/monitor-sampleapp-quickstart';
7
7
  import { monitorSampleAppQuickStartWithImage } from './QuickStarts/monitor-sampleapp-quickstart-with-image';
8
8
  import rehypeExternalLinks from '../__mocks__/rehype-external-links';
9
- import { AlertActionLink } from '@patternfly/react-core';
9
+ import { AlertActionLink, Button, CodeBlockAction } from '@patternfly/react-core';
10
10
  import { DeepThinkingProps } from '../DeepThinking';
11
11
 
12
12
  const ALL_ACTIONS = [
@@ -612,6 +612,24 @@ describe('Message', () => {
612
612
  );
613
613
  expect(screen.getByRole('button', { name: 'test' })).toBeTruthy();
614
614
  });
615
+ it('should be able to add custom actions to CodeMessage', () => {
616
+ render(
617
+ <Message
618
+ avatar="./img"
619
+ role="user"
620
+ name="User"
621
+ content={CODE_MESSAGE}
622
+ codeBlockProps={{
623
+ customActions: (
624
+ <CodeBlockAction>
625
+ <Button>New custom action</Button>
626
+ </CodeBlockAction>
627
+ )
628
+ }}
629
+ />
630
+ );
631
+ expect(screen.getByRole('button', { name: /New custom action/i })).toBeTruthy();
632
+ });
615
633
  it('should handle hasRoundAvatar correctly when it is true', () => {
616
634
  render(<Message avatar="./img" role="user" name="User" content="Hi" hasRoundAvatar />);
617
635
  expect(screen.getByRole('img')).toBeTruthy();
@@ -11,8 +11,6 @@ import {
11
11
  AvatarProps,
12
12
  ButtonProps,
13
13
  ContentVariants,
14
- ExpandableSectionProps,
15
- ExpandableSectionToggleProps,
16
14
  FormProps,
17
15
  Label,
18
16
  LabelGroupProps,
@@ -20,7 +18,7 @@ import {
20
18
  Truncate
21
19
  } from '@patternfly/react-core';
22
20
  import MessageLoading from './MessageLoading';
23
- import CodeBlockMessage from './CodeBlockMessage/CodeBlockMessage';
21
+ import CodeBlockMessage, { CodeBlockMessageProps } from './CodeBlockMessage/CodeBlockMessage';
24
22
  import TextMessage from './TextMessage/TextMessage';
25
23
  import FileDetailsLabel from '../FileDetailsLabel/FileDetailsLabel';
26
24
  import ResponseActions, { ActionProps } from '../ResponseActions/ResponseActions';
@@ -114,24 +112,7 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
114
112
  /** Label for the English "Loading message," displayed to screenreaders when loading a message */
115
113
  loadingWord?: string;
116
114
  /** Props for code blocks */
117
- codeBlockProps?: {
118
- /** Aria label applied to code blocks */
119
- 'aria-label'?: string;
120
- /** Class name applied to code blocks */
121
- className?: string;
122
- /** Whether code blocks are expandable */
123
- isExpandable?: boolean;
124
- /** Length of text initially shown in expandable code blocks; defaults to 10 characters */
125
- maxLength?: number;
126
- /** Additional props passed to expandable section if isExpandable is applied */
127
- expandableSectionProps?: Omit<ExpandableSectionProps, 'ref'>;
128
- /** Additional props passed to expandable toggle if isExpandable is applied */
129
- expandableSectionToggleProps?: ExpandableSectionToggleProps;
130
- /** Link text applied to expandable toggle when expanded */
131
- expandedText?: string;
132
- /** Link text applied to expandable toggle when collapsed */
133
- collapsedText?: string;
134
- };
115
+ codeBlockProps?: CodeBlockMessageProps;
135
116
  /** Props for quick responses */
136
117
  quickResponses?: QuickResponse[];
137
118
  /** Props for quick responses container */
@@ -71,6 +71,12 @@ li[id*='user-content-fn-']:has(> span > span > .pf-chatbot__message-text + .pf-c
71
71
  margin-block-end: var(--pf-t--global--spacer--md);
72
72
  }
73
73
 
74
+ .pf-chatbot__message-text.footnotes {
75
+ .data-footnote-backref {
76
+ width: fit-content;
77
+ }
78
+ }
79
+
74
80
  .pf-chatbot__message--user {
75
81
  .pf-chatbot__message-text {
76
82
  background-color: var(--pf-t--global--color--brand--default);