@patternfly/chatbot 2.1.0-prerelease.17 → 2.1.0-prerelease.19

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 (48) hide show
  1. package/dist/cjs/ChatbotToggle/ChatbotToggle.d.ts +7 -1
  2. package/dist/cjs/ChatbotToggle/ChatbotToggle.js +4 -4
  3. package/dist/cjs/ChatbotToggle/ChatbotToggle.test.d.ts +1 -0
  4. package/dist/cjs/ChatbotToggle/ChatbotToggle.test.js +60 -0
  5. package/dist/cjs/Message/Message.d.ts +5 -1
  6. package/dist/cjs/Message/Message.js +8 -2
  7. package/dist/cjs/Message/Message.test.js +100 -4
  8. package/dist/cjs/ResponseActions/ResponseActions.test.js +38 -0
  9. package/dist/css/main.css +19 -12
  10. package/dist/css/main.css.map +1 -1
  11. package/dist/esm/ChatbotToggle/ChatbotToggle.d.ts +7 -1
  12. package/dist/esm/ChatbotToggle/ChatbotToggle.js +4 -4
  13. package/dist/esm/ChatbotToggle/ChatbotToggle.test.d.ts +1 -0
  14. package/dist/esm/ChatbotToggle/ChatbotToggle.test.js +55 -0
  15. package/dist/esm/Message/Message.d.ts +5 -1
  16. package/dist/esm/Message/Message.js +8 -2
  17. package/dist/esm/Message/Message.test.js +100 -4
  18. package/dist/esm/ResponseActions/ResponseActions.test.js +38 -0
  19. package/dist/tsconfig.tsbuildinfo +1 -1
  20. package/package.json +5 -1
  21. package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +8 -0
  22. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithAttachment.tsx +1 -1
  23. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +8 -2
  24. package/patternfly-docs/content/extensions/chatbot/examples/Messages/PF-social-color-square.svg +19 -0
  25. package/patternfly-docs/content/extensions/chatbot/examples/Messages/PF-social-dark-square.svg +19 -0
  26. package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +8 -1
  27. package/patternfly-docs/content/extensions/chatbot/examples/Messages/user_avatar.svg +18 -0
  28. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotToggleBasic.tsx +1 -1
  29. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotWelcomeInteraction.tsx +3 -2
  30. package/patternfly-docs/content/extensions/chatbot/examples/UI/CustomClosedIcon.tsx +1 -1
  31. package/patternfly-docs/content/extensions/chatbot/examples/UI/SkipToContent.tsx +1 -1
  32. package/patternfly-docs/content/extensions/chatbot/examples/UI/SquareChatbotToggle.tsx +14 -0
  33. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +9 -1
  34. package/patternfly-docs/content/extensions/chatbot/examples/demos/AttachmentDemos.md +1 -1
  35. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +1 -1
  36. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.tsx +6 -4
  37. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachment.tsx +3 -2
  38. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachmentMenu.tsx +4 -3
  39. package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedChatbot.tsx +5 -3
  40. package/src/ChatbotToggle/ChatbotToggle.scss +11 -5
  41. package/src/ChatbotToggle/ChatbotToggle.test.tsx +47 -0
  42. package/src/ChatbotToggle/ChatbotToggle.tsx +15 -6
  43. package/src/Message/Message.scss +15 -9
  44. package/src/Message/Message.test.tsx +141 -4
  45. package/src/Message/Message.tsx +28 -3
  46. package/src/MessageBox/MessageBox.scss +2 -2
  47. package/src/ResponseActions/ResponseActions.test.tsx +44 -0
  48. package/patternfly-docs/content/extensions/chatbot/examples/Messages/user_avatar.jpg +0 -0
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { ButtonProps, TooltipProps } from '@patternfly/react-core';
3
3
  export interface ChatbotToggleProps extends ButtonProps {
4
4
  /** Contents of the tooltip applied to the toggle button */
5
- toolTipLabel?: React.ReactNode;
5
+ tooltipLabel: React.ReactNode;
6
6
  /** Props spread to the PF Tooltip component */
7
7
  tooltipProps?: Omit<TooltipProps, 'content'>;
8
8
  /** Flag indicating visibility of the chatbot appended to the toggle */
@@ -15,6 +15,12 @@ export interface ChatbotToggleProps extends ButtonProps {
15
15
  closedToggleIcon?: () => JSX.Element;
16
16
  /** Ref applied to toggle */
17
17
  innerRef?: React.Ref<HTMLButtonElement>;
18
+ /** Whether toggle is a circle */
19
+ isRound?: boolean;
20
+ /** Class name applied to toggle */
21
+ className?: string;
22
+ /** Test id applied to default open icon */
23
+ openIconTestId?: string;
18
24
  }
19
25
  declare const ChatbotToggle: React.ForwardRefExoticComponent<ChatbotToggleProps & React.RefAttributes<any>>;
20
26
  export default ChatbotToggle;
@@ -24,12 +24,12 @@ const ChatIcon = () => (react_1.default.createElement("svg", { xmlns: "http://ww
24
24
  react_1.default.createElement("path", { fill: "var(--pf-t--global--icon--color--inverse)", stroke: "var(--pf-t--global--icon--color--inverse)", strokeLinejoin: "round", strokeWidth: ".75", d: "M3.577 14.382c0 .198.12.38.31.46l.19.04a.492.492 0 0 0 .349-.143l3.028-3.028h8.513a.489.489 0 0 0 .492-.492V2.491A.489.489 0 0 0 15.967 2H1.691a.489.489 0 0 0-.492.491v8.728c0 .135.056.262.143.349a.498.498 0 0 0 .349.143h1.878v2.663h.008v.008ZM2.19 10.72V2.983h13.278v7.729H7.24a.512.512 0 0 0-.35.143l-2.322 2.322v-1.974a.498.498 0 0 0-.142-.348.492.492 0 0 0-.35-.143H2.19v.008Z" }),
25
25
  react_1.default.createElement("path", { fill: "var(--pf-t--global--text--color--inverse)", stroke: "var(--pf-t--global--text--color--inverse)", strokeLinejoin: "round", strokeWidth: ".75", d: "M22.301 9.135h-3.963a.489.489 0 0 0-.492.491c0 .27.222.492.492.492h3.472v7.737h-1.88a.404.404 0 0 0-.348.134.492.492 0 0 0-.143.35v1.973l-2.322-2.323a.492.492 0 0 0-.349-.142H8.532v-4.265a.489.489 0 0 0-.492-.492.494.494 0 0 0-.491.492v4.756c0 .277.222.492.491.492h8.514l3.028 3.028a.492.492 0 0 0 .349.142l.19-.04a.502.502 0 0 0 .31-.459V18.83h1.878c.111-.008.262-.048.349-.135a.491.491 0 0 0 .142-.349v-8.72a.489.489 0 0 0-.491-.491h-.008Z" })));
26
26
  const ChatbotToggleBase = (_a) => {
27
- var { toolTipLabel, isChatbotVisible, onToggleChatbot, tooltipProps, toggleButtonLabel, closedToggleIcon: ClosedToggleIcon, innerRef } = _a, props = __rest(_a, ["toolTipLabel", "isChatbotVisible", "onToggleChatbot", "tooltipProps", "toggleButtonLabel", "closedToggleIcon", "innerRef"]);
27
+ var { tooltipLabel, isChatbotVisible, onToggleChatbot, tooltipProps, toggleButtonLabel, closedToggleIcon: ClosedToggleIcon, innerRef, isRound = true, className, openIconTestId } = _a, props = __rest(_a, ["tooltipLabel", "isChatbotVisible", "onToggleChatbot", "tooltipProps", "toggleButtonLabel", "closedToggleIcon", "innerRef", "isRound", "className", "openIconTestId"]);
28
28
  // Configure icon
29
29
  const closedIcon = ClosedToggleIcon ? react_1.default.createElement(ClosedToggleIcon, null) : react_1.default.createElement(ChatIcon, null);
30
- const icon = isChatbotVisible ? react_1.default.createElement(angle_down_icon_1.default, null) : closedIcon;
31
- return (react_1.default.createElement(react_core_1.Tooltip, Object.assign({ content: toolTipLabel }, tooltipProps),
32
- react_1.default.createElement(react_core_1.Button, Object.assign({ className: `pf-chatbot__button ${isChatbotVisible ? 'pf-chatbot__button--active' : ''}`, variant: "plain", "aria-label": toggleButtonLabel || `${toolTipLabel} toggle`, onClick: onToggleChatbot, "aria-expanded": isChatbotVisible, icon: react_1.default.createElement(react_core_1.Icon, { isInline: true }, icon), ref: innerRef }, props))));
30
+ const icon = isChatbotVisible ? react_1.default.createElement(angle_down_icon_1.default, { "data-testid": openIconTestId }) : closedIcon;
31
+ return (react_1.default.createElement(react_core_1.Tooltip, Object.assign({ content: tooltipLabel }, tooltipProps),
32
+ react_1.default.createElement(react_core_1.Button, Object.assign({ className: `pf-chatbot__button ${isChatbotVisible ? 'pf-chatbot__button--active' : ''} ${isRound ? 'pf-chatbot__button--round' : ''} ${className ? className : ''}`, variant: "plain", "aria-label": toggleButtonLabel || `${tooltipLabel} toggle`, onClick: onToggleChatbot, "aria-expanded": isChatbotVisible, icon: react_1.default.createElement(react_core_1.Icon, { isInline: true }, icon), ref: innerRef }, props))));
33
33
  };
34
34
  const ChatbotToggle = react_1.default.forwardRef((props, ref) => (react_1.default.createElement(ChatbotToggleBase, Object.assign({ innerRef: ref }, props))));
35
35
  exports.default = ChatbotToggle;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const react_1 = __importDefault(require("react"));
16
+ const react_2 = require("@testing-library/react");
17
+ require("@testing-library/jest-dom");
18
+ const user_event_1 = __importDefault(require("@testing-library/user-event"));
19
+ const ChatbotToggle_1 = __importDefault(require("./ChatbotToggle"));
20
+ describe('ChatbotToggle', () => {
21
+ it('should render tooltipLabel correctly', () => __awaiter(void 0, void 0, void 0, function* () {
22
+ (0, react_2.render)(react_1.default.createElement(ChatbotToggle_1.default, { tooltipLabel: "Tooltip" }));
23
+ yield user_event_1.default.click(react_2.screen.getByRole('button', { name: /Tooltip toggle/i }));
24
+ expect(react_2.screen.getByRole('tooltip', { name: /Tooltip/i })).toBeTruthy();
25
+ }));
26
+ it('should render toggleButtonLabel correctly', () => __awaiter(void 0, void 0, void 0, function* () {
27
+ (0, react_2.render)(react_1.default.createElement(ChatbotToggle_1.default, { tooltipLabel: "Chatbot", toggleButtonLabel: "Button" }));
28
+ expect(react_2.screen.getByRole('button', { name: /Button/i })).toBeTruthy();
29
+ }));
30
+ it('should call onToggleChatbot when clicked', () => __awaiter(void 0, void 0, void 0, function* () {
31
+ const spy = jest.fn();
32
+ (0, react_2.render)(react_1.default.createElement(ChatbotToggle_1.default, { tooltipLabel: "Chatbot", onToggleChatbot: spy }));
33
+ yield user_event_1.default.click(react_2.screen.getByRole('button'));
34
+ expect(spy).toHaveBeenCalledTimes(1);
35
+ }));
36
+ it('should handle isChatbotVisible correctly when true', () => {
37
+ (0, react_2.render)(react_1.default.createElement(ChatbotToggle_1.default, { tooltipLabel: "Chatbot", isChatbotVisible: true, openIconTestId: "Open" }));
38
+ expect(react_2.screen.getByRole('button')).toHaveClass('pf-chatbot__button');
39
+ expect(react_2.screen.getByRole('button')).toHaveClass('pf-chatbot__button--active');
40
+ expect(react_2.screen.getByRole('button')).toHaveAttribute('aria-expanded', 'true');
41
+ expect(react_2.screen.getByTestId('Open')).toBeTruthy();
42
+ });
43
+ it('should handle isChatbotVisible correctly when false', () => {
44
+ (0, react_2.render)(react_1.default.createElement(ChatbotToggle_1.default, { tooltipLabel: "Chatbot", isChatbotVisible: false, openIconTestId: "Open" }));
45
+ expect(react_2.screen.getByRole('button')).toHaveClass('pf-chatbot__button');
46
+ expect(react_2.screen.getByRole('button')).not.toHaveClass('pf-chatbot__button--active');
47
+ expect(react_2.screen.getByRole('button')).toHaveAttribute('aria-expanded', 'false');
48
+ expect(react_2.screen.queryByTestId('Open')).toBeFalsy();
49
+ });
50
+ it('should handle isRound correctly', () => {
51
+ (0, react_2.render)(react_1.default.createElement(ChatbotToggle_1.default, { tooltipLabel: "Chatbot", isRound: true }));
52
+ expect(react_2.screen.getByRole('button')).toHaveClass('pf-chatbot__button');
53
+ expect(react_2.screen.getByRole('button')).toHaveClass('pf-chatbot__button--round');
54
+ });
55
+ it('should handle className correctly', () => {
56
+ (0, react_2.render)(react_1.default.createElement(ChatbotToggle_1.default, { tooltipLabel: "Chatbot", className: "test" }));
57
+ expect(react_2.screen.getByRole('button')).toHaveClass('pf-chatbot__button');
58
+ expect(react_2.screen.getByRole('button')).toHaveClass('test');
59
+ });
60
+ });
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { LabelGroupProps, LabelProps } from '@patternfly/react-core';
2
+ import { AvatarProps, LabelGroupProps, LabelProps } from '@patternfly/react-core';
3
3
  import { ActionProps } from '../ResponseActions/ResponseActions';
4
4
  import { SourcesCardProps } from '../SourcesCard';
5
5
  export interface QuickResponse extends Omit<LabelProps, 'children'> {
@@ -60,6 +60,10 @@ export interface MessageProps extends Omit<React.HTMLProps<HTMLDivElement>, 'rol
60
60
  quickResponses?: QuickResponse[];
61
61
  /** Props for quick responses container */
62
62
  quickResponseContainerProps?: Omit<LabelGroupProps, 'ref'>;
63
+ /** Whether avatar is round */
64
+ hasRoundAvatar?: boolean;
65
+ /** Any additional props applied to the avatar, for additional customization */
66
+ avatarProps?: Omit<AvatarProps, 'alt'>;
63
67
  }
64
68
  export declare const Message: React.FunctionComponent<MessageProps>;
65
69
  export default Message;
@@ -32,12 +32,18 @@ const ListItemMessage_1 = __importDefault(require("./ListMessage/ListItemMessage
32
32
  const UnorderedListMessage_1 = __importDefault(require("./ListMessage/UnorderedListMessage"));
33
33
  const OrderedListMessage_1 = __importDefault(require("./ListMessage/OrderedListMessage"));
34
34
  const Message = (_a) => {
35
- var { role, content, name, avatar, timestamp, isLoading, actions, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments } = _a, props = __rest(_a, ["role", "content", "name", "avatar", "timestamp", "isLoading", "actions", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments"]);
35
+ var { role, content, name, avatar, timestamp, isLoading, actions, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps } = _a, props = __rest(_a, ["role", "content", "name", "avatar", "timestamp", "isLoading", "actions", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps"]);
36
+ let avatarClassName;
37
+ if (avatarProps && 'className' in avatarProps) {
38
+ const { className } = avatarProps, rest = __rest(avatarProps, ["className"]);
39
+ avatarClassName = className;
40
+ avatarProps = Object.assign({}, rest);
41
+ }
36
42
  // Keep timestamps consistent between Timestamp component and aria-label
37
43
  const date = new Date();
38
44
  const dateString = timestamp !== null && timestamp !== void 0 ? timestamp : `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
39
45
  return (react_1.default.createElement("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: `pf-chatbot__message pf-chatbot__message--${role}` }, props),
40
- react_1.default.createElement(react_core_1.Avatar, { src: avatar, alt: "" }),
46
+ react_1.default.createElement(react_core_1.Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps)),
41
47
  react_1.default.createElement("div", { className: "pf-chatbot__message-contents" },
42
48
  react_1.default.createElement("div", { className: "pf-chatbot__message-meta" },
43
49
  name && (react_1.default.createElement("span", { className: "pf-chatbot__message-name" },
@@ -74,7 +74,12 @@ describe('Message', () => {
74
74
  expect(react_2.screen.getByText('User')).toBeTruthy();
75
75
  expect(react_2.screen.getByText('Hi')).toBeTruthy();
76
76
  const date = new Date();
77
- expect(react_2.screen.getByText(`${date.toLocaleDateString()}, ${date.toLocaleTimeString()}`)).toBeTruthy();
77
+ const formattedDate = date.toLocaleDateString();
78
+ expect(react_2.screen.getByText((content, element) => {
79
+ const hasText = content.includes(formattedDate);
80
+ const isVisible = (element === null || element === void 0 ? void 0 : element.tagName.toLowerCase()) !== 'script' && (element === null || element === void 0 ? void 0 : element.tagName.toLowerCase()) !== 'style';
81
+ return hasText && isVisible;
82
+ })).toBeInTheDocument();
78
83
  expect(react_2.screen.queryByText('Loading message')).toBeFalsy();
79
84
  expect(react_2.screen.getByRole('img')).toHaveAttribute('src', './img');
80
85
  });
@@ -84,7 +89,12 @@ describe('Message', () => {
84
89
  expect(react_2.screen.getByText('AI')).toBeTruthy();
85
90
  expect(react_2.screen.getByText('Hi')).toBeTruthy();
86
91
  const date = new Date();
87
- expect(react_2.screen.getByText(`${date.toLocaleDateString()}, ${date.toLocaleTimeString()}`)).toBeTruthy();
92
+ const formattedDate = date.toLocaleDateString();
93
+ expect(react_2.screen.getByText((content, element) => {
94
+ const hasText = content.includes(formattedDate);
95
+ const isVisible = (element === null || element === void 0 ? void 0 : element.tagName.toLowerCase()) !== 'script' && (element === null || element === void 0 ? void 0 : element.tagName.toLowerCase()) !== 'style';
96
+ return hasText && isVisible;
97
+ })).toBeInTheDocument();
88
98
  });
89
99
  it('should render avatar correctly', () => {
90
100
  (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./testImg", role: "bot", name: "Bot", content: "Hi" }));
@@ -104,7 +114,12 @@ describe('Message', () => {
104
114
  expect(react_2.screen.getByText('Hi')).toBeTruthy();
105
115
  expect(react_2.screen.getByText('2 hours ago')).toBeTruthy();
106
116
  const date = new Date();
107
- expect(react_2.screen.queryByText(`${date.toLocaleDateString()}, ${date.toLocaleTimeString()}`)).toBeFalsy();
117
+ const formattedDate = date.toLocaleDateString();
118
+ expect(react_2.screen.queryByText((content, element) => {
119
+ const hasText = content.includes(formattedDate);
120
+ const isVisible = (element === null || element === void 0 ? void 0 : element.tagName.toLowerCase()) !== 'script' && (element === null || element === void 0 ? void 0 : element.tagName.toLowerCase()) !== 'style';
121
+ return hasText && isVisible;
122
+ })).not.toBeInTheDocument();
108
123
  });
109
124
  it('should render attachments', () => {
110
125
  (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "user", content: "Hi", attachments: [{ name: 'testAttachment' }] }));
@@ -134,7 +149,12 @@ describe('Message', () => {
134
149
  expect(react_2.screen.getByText('AI')).toBeTruthy();
135
150
  expect(react_2.screen.queryByText('Hi')).toBeFalsy();
136
151
  const date = new Date();
137
- expect(react_2.screen.getByText(`${date.toLocaleDateString()}, ${date.toLocaleTimeString()}`)).toBeTruthy();
152
+ const formattedDate = date.toLocaleDateString();
153
+ expect(react_2.screen.getByText((content, element) => {
154
+ const hasText = content.includes(formattedDate);
155
+ const isVisible = (element === null || element === void 0 ? void 0 : element.tagName.toLowerCase()) !== 'script' && (element === null || element === void 0 ? void 0 : element.tagName.toLowerCase()) !== 'style';
156
+ return hasText && isVisible;
157
+ })).toBeInTheDocument();
138
158
  expect(react_2.screen.getByText('Loading message')).toBeTruthy();
139
159
  });
140
160
  it('should be able to show sources', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -162,6 +182,59 @@ describe('Message', () => {
162
182
  expect(react_2.screen.getByText('Loading message')).toBeTruthy();
163
183
  expect(react_2.screen.queryByText('Getting started with Red Hat OpenShift')).toBeFalsy();
164
184
  });
185
+ it('should be able to show quick response', () => __awaiter(void 0, void 0, void 0, function* () {
186
+ const spy = jest.fn();
187
+ (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", quickResponses: [
188
+ {
189
+ id: '1',
190
+ content: 'Yes',
191
+ onClick: spy,
192
+ className: 'test'
193
+ }
194
+ ] }));
195
+ const quickResponse = react_2.screen.getByRole('button', { name: /Yes/i });
196
+ expect(quickResponse).toBeTruthy();
197
+ yield user_event_1.default.click(quickResponse);
198
+ expect(spy).toHaveBeenCalledTimes(1);
199
+ }));
200
+ it('should be able to show more than 1 quick response', () => __awaiter(void 0, void 0, void 0, function* () {
201
+ const spy = jest.fn();
202
+ (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", quickResponses: [
203
+ {
204
+ id: '1',
205
+ content: 'Yes',
206
+ onClick: spy
207
+ },
208
+ {
209
+ id: '2',
210
+ content: 'No',
211
+ onClick: spy
212
+ }
213
+ ] }));
214
+ expect(react_2.screen.getByRole('button', { name: /Yes/i })).toBeTruthy();
215
+ expect(react_2.screen.getByRole('button', { name: /No/i })).toBeTruthy();
216
+ }));
217
+ it('should be able to spread quickResponseContainerProps', () => __awaiter(void 0, void 0, void 0, function* () {
218
+ const spy = jest.fn();
219
+ (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", quickResponses: [
220
+ {
221
+ id: '1',
222
+ content: 'Yes',
223
+ onClick: spy
224
+ },
225
+ {
226
+ id: '2',
227
+ content: 'No',
228
+ onClick: spy
229
+ }
230
+ ],
231
+ // this is a LabelGroup prop that changes the default number shown
232
+ // to be different than what we use in ChatBot
233
+ quickResponseContainerProps: { numLabels: 1 } }));
234
+ expect(react_2.screen.getByRole('button', { name: /Yes/i })).toBeTruthy();
235
+ expect(react_2.screen.queryByRole('button', { name: /No/i })).toBeFalsy();
236
+ expect(react_2.screen.getByRole('button', { name: /1 more/i }));
237
+ }));
165
238
  it('should be able to show actions', () => __awaiter(void 0, void 0, void 0, function* () {
166
239
  (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "bot", name: "Bot", content: "Hi", actions: {
167
240
  // eslint-disable-next-line no-console
@@ -236,4 +309,27 @@ describe('Message', () => {
236
309
  (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "user", name: "User", content: CODE_MESSAGE, codeBlockProps: { 'aria-label': 'test' } }));
237
310
  expect(react_2.screen.getByRole('button', { name: 'test' })).toBeTruthy();
238
311
  });
312
+ it('should handle hasRoundAvatar correctly when it is true', () => {
313
+ (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "Hi", hasRoundAvatar: true }));
314
+ expect(react_2.screen.getByRole('img')).toBeTruthy();
315
+ expect(react_2.screen.getByRole('img')).toHaveClass('pf-chatbot__message-avatar');
316
+ expect(react_2.screen.getByRole('img')).toHaveClass('pf-chatbot__message-avatar--round');
317
+ });
318
+ it('should handle hasRoundAvatar correctly when it is false', () => {
319
+ (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "Hi", hasRoundAvatar: false }));
320
+ expect(react_2.screen.getByRole('img')).toBeTruthy();
321
+ expect(react_2.screen.getByRole('img')).toHaveClass('pf-chatbot__message-avatar');
322
+ expect(react_2.screen.getByRole('img')).not.toHaveClass('pf-chatbot__message-avatar--round');
323
+ });
324
+ it('should handle avatarProps correctly by spreading it onto the Message Avatar', () => {
325
+ (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "Hi", avatarProps: { className: 'test' } }));
326
+ expect(react_2.screen.getByRole('img')).toBeTruthy();
327
+ expect(react_2.screen.getByRole('img')).toHaveClass('test');
328
+ });
329
+ it('should handle avatarProps and hasRoundAvatar correctly', () => {
330
+ (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "Hi", avatarProps: { className: 'test' }, hasRoundAvatar: false }));
331
+ expect(react_2.screen.getByRole('img')).toBeTruthy();
332
+ expect(react_2.screen.getByRole('img')).toHaveClass('test');
333
+ expect(react_2.screen.getByRole('img')).toHaveClass('pf-chatbot__message-avatar');
334
+ });
239
335
  });
@@ -17,6 +17,7 @@ const react_2 = require("@testing-library/react");
17
17
  require("@testing-library/jest-dom");
18
18
  const ResponseActions_1 = __importDefault(require("./ResponseActions"));
19
19
  const user_event_1 = __importDefault(require("@testing-library/user-event"));
20
+ const react_icons_1 = require("@patternfly/react-icons");
20
21
  const ALL_ACTIONS = [
21
22
  { type: 'positive', label: 'Good response' },
22
23
  { type: 'negative', label: 'Bad response' },
@@ -24,6 +25,28 @@ const ALL_ACTIONS = [
24
25
  { type: 'share', label: 'Share' },
25
26
  { type: 'listen', label: 'Listen' }
26
27
  ];
28
+ const CUSTOM_ACTIONS = [
29
+ {
30
+ regenerate: {
31
+ ariaLabel: 'Regenerate',
32
+ onClick: jest.fn(),
33
+ tooltipContent: 'Regenerate',
34
+ icon: react_1.default.createElement(react_icons_1.RedoIcon, null)
35
+ },
36
+ download: {
37
+ ariaLabel: 'Download',
38
+ onClick: jest.fn(),
39
+ tooltipContent: 'Download',
40
+ icon: react_1.default.createElement(react_icons_1.DownloadIcon, null)
41
+ },
42
+ info: {
43
+ ariaLabel: 'Info',
44
+ onClick: jest.fn(),
45
+ tooltipContent: 'Info',
46
+ icon: react_1.default.createElement(react_icons_1.InfoCircleIcon, null)
47
+ }
48
+ }
49
+ ];
27
50
  describe('ResponseActions', () => {
28
51
  it('should render buttons correctly', () => {
29
52
  ALL_ACTIONS.forEach(({ type, label }) => {
@@ -64,4 +87,19 @@ describe('ResponseActions', () => {
64
87
  expect(react_2.screen.getByRole('button', { name: label })).toHaveClass('test');
65
88
  });
66
89
  });
90
+ it('should be able to add custom actions', () => {
91
+ CUSTOM_ACTIONS.forEach((action) => {
92
+ const key = Object.keys(action)[0];
93
+ (0, react_2.render)(react_1.default.createElement(ResponseActions_1.default, { actions: {
94
+ [key]: {
95
+ tooltipContent: action[key].tooltipContent,
96
+ onClick: action[key].onClick,
97
+ // doing this just because it's easier to test without a regex for the button name
98
+ ariaLabel: action[key].ariaLabel.toLowerCase(),
99
+ icon: action[key].icon
100
+ }
101
+ } }));
102
+ expect(react_2.screen.getByRole('button', { name: key })).toBeTruthy();
103
+ });
104
+ });
67
105
  });
package/dist/css/main.css CHANGED
@@ -532,11 +532,8 @@ html.pf-chatbot-allow--docked {
532
532
  inset-block-end: var(--pf-t--global--spacer--md);
533
533
  inset-inline-end: var(--pf-t--global--spacer--md);
534
534
  background-color: var(--pf-t--global--background--color--inverse--default);
535
- border-radius: var(--pf-t--global--border--radius--pill);
536
535
  --pf-v6-c-button__icon--Color: var(--pf-t--chatbot-toggle--color);
537
536
  padding: var(--pf-t--global--spacer--md);
538
- width: 3rem;
539
- height: 3rem;
540
537
  }
541
538
  .pf-v6-c-button.pf-chatbot__button:hover, .pf-v6-c-button.pf-chatbot__button:focus {
542
539
  background-color: var(--pf-t--chatbot-toggle--background--hover);
@@ -549,6 +546,12 @@ html.pf-chatbot-allow--docked {
549
546
  height: var(--pf-t--global--spacer--lg);
550
547
  }
551
548
 
549
+ .pf-chatbot__button--round {
550
+ border-radius: var(--pf-t--global--border--radius--pill);
551
+ width: 3rem;
552
+ height: 3rem;
553
+ }
554
+
552
555
  .pf-chatbot--layout--welcome {
553
556
  padding-block-end: var(--pf-t--global--spacer--lg);
554
557
  flex-direction: column;
@@ -781,18 +784,22 @@ html.pf-chatbot-allow--docked {
781
784
  gap: var(--pf-t--global--spacer--lg);
782
785
  padding-bottom: var(--pf-t--global--spacer--2xl);
783
786
  }
784
- .pf-chatbot__message .pf-v6-c-truncate {
785
- --pf-v6-c-truncate--MinWidth: 0ch;
786
- --pf-v6-c-truncate__start--MinWidth: 0ch;
787
- }
788
- .pf-chatbot__message .pf-v6-c-avatar {
789
- --pf-v6-c-avatar--Width: 3rem;
790
- --pf-v6-c-avatar--Height: 3rem;
787
+ .pf-chatbot__message-avatar.pf-v6-c-avatar {
788
+ --pf-v6-c-avatar--BorderRadius: 0;
791
789
  position: sticky;
792
790
  top: var(--pf-t--global--spacer--md);
793
791
  object-fit: cover;
794
792
  pointer-events: none;
795
793
  }
794
+ .pf-chatbot__message-avatar.pf-chatbot__message-avatar--round.pf-v6-c-avatar {
795
+ --pf-v6-c-avatar--Width: 3rem;
796
+ --pf-v6-c-avatar--Height: 3rem;
797
+ --pf-v6-c-avatar--BorderRadius: var(--pf-t--global--border--radius--pill);
798
+ }
799
+ .pf-chatbot__message .pf-v6-c-truncate {
800
+ --pf-v6-c-truncate--MinWidth: 0ch;
801
+ --pf-v6-c-truncate__start--MinWidth: 0ch;
802
+ }
796
803
  .pf-chatbot__message-contents {
797
804
  display: flex;
798
805
  flex-direction: column;
@@ -1363,8 +1370,8 @@ html.pf-chatbot-allow--docked {
1363
1370
  padding: var(--pf-t--global--spacer--lg);
1364
1371
  }
1365
1372
 
1366
- .pf-chatbot__messagebox--bottom {
1367
- justify-content: flex-end;
1373
+ .pf-chatbot__messagebox--bottom > :first-child {
1374
+ margin-top: auto !important;
1368
1375
  }
1369
1376
 
1370
1377
  .pf-chatbot__messagebox-announcement {
@@ -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/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/ListMessage/ListMessage.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/ResponseActions/ResponseActions.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.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;;AAGA;EACE;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;ACvFF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;IACA;;;ACfJ;EACE;EACA;;AAIF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;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;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;;AAQF;EACE;;;AAQF;EACE;;AACA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AASF;AAAA;AAAA;EACE;;;AC9JN;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;;;AAUF;EACE;;AAGJ;EACE;;;AChDJ;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;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AASJ;EACE;;AAEF;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;;;AC1IF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;AAAA;EAEE;;AAEF;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;;;ACvFA;EAA0B;;AAMxB;EAAM;;AACN;EAAuB;;AACvB;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACnBN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAIF;EAAM;EAAwC;;;ACpBhD;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;;AAOJ;EAIM;AAAA;IACE;IACA;;;AC1CN;EACE;EACA;EACA;EACA;;AAEF;EACE;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;;AASA;EACE;EACA;;;ACxEN;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACvBF;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;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AC/BF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIA;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;;AAQR;EACE;EACA;EACA;;;AC7GF;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;;;AC1EE;EACE;;;AAMN;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;;;AD5CN;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;;;AC1EE;EACE;;;AAMN;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;;;AC3CN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;;AHnBJ;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;;;;AI9CN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;;ACbN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AC1CJ;EACE;EACA;EACA;EACA;;AAEA;EAEE;;AAEA;EACE;;;AAKN;EACE;IACE;IACA;;EAEF;IACE;IACA;;;ACvBJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;;;ACTJ;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACvEF;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;;;ACzCJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAGI;AAAA;IACE;IACA;;;AD5BN;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;;;AE3CJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;;ACrBR;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;ACrER;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;ACJF;EAKE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASA;EACA;EAEA;EAEA;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAMA;EAKA;EAEA;EACA;EACA;EAEA;EACA;EACA;EAEA;;;AAMF;EACE;EACA;EAEA;EAEA;EACA;;;AAGF;EACE;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/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/ListMessage/ListMessage.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/ResponseActions/ResponseActions.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.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;;AAGA;EACE;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;ACvFF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;IACA;;;ACfJ;EACE;EACA;;AAIF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;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;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;;AAQF;EACE;;;AAQF;EACE;;AACA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AASF;AAAA;AAAA;EACE;;;AC9JN;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;;;AAUF;EACE;;AAGJ;EACE;;;AChDJ;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;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AASJ;EACE;;AAEF;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;;;AC1IF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;AAAA;EAEE;;AAEF;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;;;ACvFA;EAA0B;;AAMxB;EAAM;;AACN;EAAuB;;AACvB;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACnBN;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;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;;AAOJ;EAIM;AAAA;IACE;IACA;;;AC1CN;EACE;EACA;EACA;EACA;;AAEF;EACE;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;;AASA;EACE;EACA;;;ACxEN;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACvBF;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;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AC/BF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;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;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIA;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;;AAQR;EACE;EACA;EACA;;;ACnHF;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;;;AC1EE;EACE;;;AAMN;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;;;AD5CN;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;;;AC1EE;EACE;;;AAMN;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;;;AC3CN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;;AHnBJ;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;;;;AI9CN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;;ACbN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AC1CJ;EACE;EACA;EACA;EACA;;AAEA;EAEE;;AAEA;EACE;;;AAKN;EACE;IACE;IACA;;EAEF;IACE;IACA;;;ACvBJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;;;ACTJ;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACvEF;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;;;ACzCJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAGI;AAAA;IACE;IACA;;;AD5BN;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;;;AE3CJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;;ACrBR;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;ACrER;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;ACJF;EAKE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASA;EACA;EAEA;EAEA;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAMA;EAKA;EAEA;EACA;EACA;EAEA;EACA;EACA;EAEA;;;AAMF;EACE;EACA;EAEA;EAEA;EACA;;;AAGF;EACE;EACA","file":"main.css"}
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { ButtonProps, TooltipProps } from '@patternfly/react-core';
3
3
  export interface ChatbotToggleProps extends ButtonProps {
4
4
  /** Contents of the tooltip applied to the toggle button */
5
- toolTipLabel?: React.ReactNode;
5
+ tooltipLabel: React.ReactNode;
6
6
  /** Props spread to the PF Tooltip component */
7
7
  tooltipProps?: Omit<TooltipProps, 'content'>;
8
8
  /** Flag indicating visibility of the chatbot appended to the toggle */
@@ -15,6 +15,12 @@ export interface ChatbotToggleProps extends ButtonProps {
15
15
  closedToggleIcon?: () => JSX.Element;
16
16
  /** Ref applied to toggle */
17
17
  innerRef?: React.Ref<HTMLButtonElement>;
18
+ /** Whether toggle is a circle */
19
+ isRound?: boolean;
20
+ /** Class name applied to toggle */
21
+ className?: string;
22
+ /** Test id applied to default open icon */
23
+ openIconTestId?: string;
18
24
  }
19
25
  declare const ChatbotToggle: React.ForwardRefExoticComponent<ChatbotToggleProps & React.RefAttributes<any>>;
20
26
  export default ChatbotToggle;
@@ -19,12 +19,12 @@ const ChatIcon = () => (React.createElement("svg", { xmlns: "http://www.w3.org/2
19
19
  React.createElement("path", { fill: "var(--pf-t--global--icon--color--inverse)", stroke: "var(--pf-t--global--icon--color--inverse)", strokeLinejoin: "round", strokeWidth: ".75", d: "M3.577 14.382c0 .198.12.38.31.46l.19.04a.492.492 0 0 0 .349-.143l3.028-3.028h8.513a.489.489 0 0 0 .492-.492V2.491A.489.489 0 0 0 15.967 2H1.691a.489.489 0 0 0-.492.491v8.728c0 .135.056.262.143.349a.498.498 0 0 0 .349.143h1.878v2.663h.008v.008ZM2.19 10.72V2.983h13.278v7.729H7.24a.512.512 0 0 0-.35.143l-2.322 2.322v-1.974a.498.498 0 0 0-.142-.348.492.492 0 0 0-.35-.143H2.19v.008Z" }),
20
20
  React.createElement("path", { fill: "var(--pf-t--global--text--color--inverse)", stroke: "var(--pf-t--global--text--color--inverse)", strokeLinejoin: "round", strokeWidth: ".75", d: "M22.301 9.135h-3.963a.489.489 0 0 0-.492.491c0 .27.222.492.492.492h3.472v7.737h-1.88a.404.404 0 0 0-.348.134.492.492 0 0 0-.143.35v1.973l-2.322-2.323a.492.492 0 0 0-.349-.142H8.532v-4.265a.489.489 0 0 0-.492-.492.494.494 0 0 0-.491.492v4.756c0 .277.222.492.491.492h8.514l3.028 3.028a.492.492 0 0 0 .349.142l.19-.04a.502.502 0 0 0 .31-.459V18.83h1.878c.111-.008.262-.048.349-.135a.491.491 0 0 0 .142-.349v-8.72a.489.489 0 0 0-.491-.491h-.008Z" })));
21
21
  const ChatbotToggleBase = (_a) => {
22
- var { toolTipLabel, isChatbotVisible, onToggleChatbot, tooltipProps, toggleButtonLabel, closedToggleIcon: ClosedToggleIcon, innerRef } = _a, props = __rest(_a, ["toolTipLabel", "isChatbotVisible", "onToggleChatbot", "tooltipProps", "toggleButtonLabel", "closedToggleIcon", "innerRef"]);
22
+ var { tooltipLabel, isChatbotVisible, onToggleChatbot, tooltipProps, toggleButtonLabel, closedToggleIcon: ClosedToggleIcon, innerRef, isRound = true, className, openIconTestId } = _a, props = __rest(_a, ["tooltipLabel", "isChatbotVisible", "onToggleChatbot", "tooltipProps", "toggleButtonLabel", "closedToggleIcon", "innerRef", "isRound", "className", "openIconTestId"]);
23
23
  // Configure icon
24
24
  const closedIcon = ClosedToggleIcon ? React.createElement(ClosedToggleIcon, null) : React.createElement(ChatIcon, null);
25
- const icon = isChatbotVisible ? React.createElement(AngleDownIcon, null) : closedIcon;
26
- return (React.createElement(Tooltip, Object.assign({ content: toolTipLabel }, tooltipProps),
27
- React.createElement(Button, Object.assign({ className: `pf-chatbot__button ${isChatbotVisible ? 'pf-chatbot__button--active' : ''}`, variant: "plain", "aria-label": toggleButtonLabel || `${toolTipLabel} toggle`, onClick: onToggleChatbot, "aria-expanded": isChatbotVisible, icon: React.createElement(Icon, { isInline: true }, icon), ref: innerRef }, props))));
25
+ const icon = isChatbotVisible ? React.createElement(AngleDownIcon, { "data-testid": openIconTestId }) : closedIcon;
26
+ return (React.createElement(Tooltip, Object.assign({ content: tooltipLabel }, tooltipProps),
27
+ React.createElement(Button, Object.assign({ className: `pf-chatbot__button ${isChatbotVisible ? 'pf-chatbot__button--active' : ''} ${isRound ? 'pf-chatbot__button--round' : ''} ${className ? className : ''}`, variant: "plain", "aria-label": toggleButtonLabel || `${tooltipLabel} toggle`, onClick: onToggleChatbot, "aria-expanded": isChatbotVisible, icon: React.createElement(Icon, { isInline: true }, icon), ref: innerRef }, props))));
28
28
  };
29
29
  const ChatbotToggle = React.forwardRef((props, ref) => (React.createElement(ChatbotToggleBase, Object.assign({ innerRef: ref }, props))));
30
30
  export default ChatbotToggle;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,55 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import React from 'react';
11
+ import { render, screen } from '@testing-library/react';
12
+ import '@testing-library/jest-dom';
13
+ import userEvent from '@testing-library/user-event';
14
+ import ChatbotToggle from './ChatbotToggle';
15
+ describe('ChatbotToggle', () => {
16
+ it('should render tooltipLabel correctly', () => __awaiter(void 0, void 0, void 0, function* () {
17
+ render(React.createElement(ChatbotToggle, { tooltipLabel: "Tooltip" }));
18
+ yield userEvent.click(screen.getByRole('button', { name: /Tooltip toggle/i }));
19
+ expect(screen.getByRole('tooltip', { name: /Tooltip/i })).toBeTruthy();
20
+ }));
21
+ it('should render toggleButtonLabel correctly', () => __awaiter(void 0, void 0, void 0, function* () {
22
+ render(React.createElement(ChatbotToggle, { tooltipLabel: "Chatbot", toggleButtonLabel: "Button" }));
23
+ expect(screen.getByRole('button', { name: /Button/i })).toBeTruthy();
24
+ }));
25
+ it('should call onToggleChatbot when clicked', () => __awaiter(void 0, void 0, void 0, function* () {
26
+ const spy = jest.fn();
27
+ render(React.createElement(ChatbotToggle, { tooltipLabel: "Chatbot", onToggleChatbot: spy }));
28
+ yield userEvent.click(screen.getByRole('button'));
29
+ expect(spy).toHaveBeenCalledTimes(1);
30
+ }));
31
+ it('should handle isChatbotVisible correctly when true', () => {
32
+ render(React.createElement(ChatbotToggle, { tooltipLabel: "Chatbot", isChatbotVisible: true, openIconTestId: "Open" }));
33
+ expect(screen.getByRole('button')).toHaveClass('pf-chatbot__button');
34
+ expect(screen.getByRole('button')).toHaveClass('pf-chatbot__button--active');
35
+ expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'true');
36
+ expect(screen.getByTestId('Open')).toBeTruthy();
37
+ });
38
+ it('should handle isChatbotVisible correctly when false', () => {
39
+ render(React.createElement(ChatbotToggle, { tooltipLabel: "Chatbot", isChatbotVisible: false, openIconTestId: "Open" }));
40
+ expect(screen.getByRole('button')).toHaveClass('pf-chatbot__button');
41
+ expect(screen.getByRole('button')).not.toHaveClass('pf-chatbot__button--active');
42
+ expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'false');
43
+ expect(screen.queryByTestId('Open')).toBeFalsy();
44
+ });
45
+ it('should handle isRound correctly', () => {
46
+ render(React.createElement(ChatbotToggle, { tooltipLabel: "Chatbot", isRound: true }));
47
+ expect(screen.getByRole('button')).toHaveClass('pf-chatbot__button');
48
+ expect(screen.getByRole('button')).toHaveClass('pf-chatbot__button--round');
49
+ });
50
+ it('should handle className correctly', () => {
51
+ render(React.createElement(ChatbotToggle, { tooltipLabel: "Chatbot", className: "test" }));
52
+ expect(screen.getByRole('button')).toHaveClass('pf-chatbot__button');
53
+ expect(screen.getByRole('button')).toHaveClass('test');
54
+ });
55
+ });
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { LabelGroupProps, LabelProps } from '@patternfly/react-core';
2
+ import { AvatarProps, LabelGroupProps, LabelProps } from '@patternfly/react-core';
3
3
  import { ActionProps } from '../ResponseActions/ResponseActions';
4
4
  import { SourcesCardProps } from '../SourcesCard';
5
5
  export interface QuickResponse extends Omit<LabelProps, 'children'> {
@@ -60,6 +60,10 @@ export interface MessageProps extends Omit<React.HTMLProps<HTMLDivElement>, 'rol
60
60
  quickResponses?: QuickResponse[];
61
61
  /** Props for quick responses container */
62
62
  quickResponseContainerProps?: Omit<LabelGroupProps, 'ref'>;
63
+ /** Whether avatar is round */
64
+ hasRoundAvatar?: boolean;
65
+ /** Any additional props applied to the avatar, for additional customization */
66
+ avatarProps?: Omit<AvatarProps, 'alt'>;
63
67
  }
64
68
  export declare const Message: React.FunctionComponent<MessageProps>;
65
69
  export default Message;
@@ -26,12 +26,18 @@ import ListItemMessage from './ListMessage/ListItemMessage';
26
26
  import UnorderedListMessage from './ListMessage/UnorderedListMessage';
27
27
  import OrderedListMessage from './ListMessage/OrderedListMessage';
28
28
  export const Message = (_a) => {
29
- var { role, content, name, avatar, timestamp, isLoading, actions, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments } = _a, props = __rest(_a, ["role", "content", "name", "avatar", "timestamp", "isLoading", "actions", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments"]);
29
+ var { role, content, name, avatar, timestamp, isLoading, actions, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps } = _a, props = __rest(_a, ["role", "content", "name", "avatar", "timestamp", "isLoading", "actions", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps"]);
30
+ let avatarClassName;
31
+ if (avatarProps && 'className' in avatarProps) {
32
+ const { className } = avatarProps, rest = __rest(avatarProps, ["className"]);
33
+ avatarClassName = className;
34
+ avatarProps = Object.assign({}, rest);
35
+ }
30
36
  // Keep timestamps consistent between Timestamp component and aria-label
31
37
  const date = new Date();
32
38
  const dateString = timestamp !== null && timestamp !== void 0 ? timestamp : `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
33
39
  return (React.createElement("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: `pf-chatbot__message pf-chatbot__message--${role}` }, props),
34
- React.createElement(Avatar, { src: avatar, alt: "" }),
40
+ React.createElement(Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps)),
35
41
  React.createElement("div", { className: "pf-chatbot__message-contents" },
36
42
  React.createElement("div", { className: "pf-chatbot__message-meta" },
37
43
  name && (React.createElement("span", { className: "pf-chatbot__message-name" },