@patternfly/chatbot 6.7.1 → 6.8.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 (43) hide show
  1. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +1 -1
  2. package/dist/cjs/Message/Message.test.js +31 -14
  3. package/dist/cjs/Message/TableMessage/TableCellContent.d.ts +8 -0
  4. package/dist/cjs/Message/TableMessage/TableCellContent.js +9 -0
  5. package/dist/cjs/Message/TableMessage/TdMessage.js +5 -1
  6. package/dist/cjs/Message/TableMessage/ThMessage.js +5 -1
  7. package/dist/cjs/ResponseActions/ResponseActions.js +21 -5
  8. package/dist/cjs/ResponseActions/ResponseActions.test.js +33 -29
  9. package/dist/cjs/SourcesCardBase/SourcesCardBase.js +1 -1
  10. package/dist/cjs/SourcesCardBase/SourcesCardBase.test.js +4 -4
  11. package/dist/css/main.css +7 -14
  12. package/dist/css/main.css.map +1 -1
  13. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +1 -1
  14. package/dist/esm/Message/Message.test.js +31 -14
  15. package/dist/esm/Message/TableMessage/TableCellContent.d.ts +8 -0
  16. package/dist/esm/Message/TableMessage/TableCellContent.js +7 -0
  17. package/dist/esm/Message/TableMessage/TdMessage.js +2 -1
  18. package/dist/esm/Message/TableMessage/ThMessage.js +2 -1
  19. package/dist/esm/ResponseActions/ResponseActions.js +22 -6
  20. package/dist/esm/ResponseActions/ResponseActions.test.js +33 -29
  21. package/dist/esm/SourcesCardBase/SourcesCardBase.js +1 -1
  22. package/dist/esm/SourcesCardBase/SourcesCardBase.test.js +4 -4
  23. package/dist/tsconfig.tsbuildinfo +1 -1
  24. package/package.json +1 -1
  25. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarAttach.tsx +11 -7
  26. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarCustomActions.tsx +46 -35
  27. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +7 -1
  28. package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedComparisonChatbot.tsx +4 -2
  29. package/src/AttachMenu/AttachMenu.scss +0 -9
  30. package/src/Chatbot/Chatbot.scss +0 -7
  31. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +1 -1
  32. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +7 -1
  33. package/src/ChatbotHeader/ChatbotHeader.scss +1 -0
  34. package/src/ChatbotToggle/ChatbotToggle.scss +1 -1
  35. package/src/Message/Message.test.tsx +42 -14
  36. package/src/Message/TableMessage/TableCellContent.tsx +9 -0
  37. package/src/Message/TableMessage/TdMessage.tsx +6 -1
  38. package/src/Message/TableMessage/ThMessage.tsx +6 -1
  39. package/src/ResponseActions/ResponseActions.test.tsx +33 -29
  40. package/src/ResponseActions/ResponseActions.tsx +37 -18
  41. package/src/SourcesCard/SourcesCard.scss +5 -0
  42. package/src/SourcesCardBase/SourcesCardBase.test.tsx +4 -4
  43. package/src/SourcesCardBase/SourcesCardBase.tsx +12 -3
@@ -10,7 +10,10 @@ import {
10
10
  SelectList,
11
11
  SelectOption
12
12
  } from '@patternfly/react-core';
13
- import { PlusIcon, ClipboardIcon, CodeIcon, UploadIcon } from '@patternfly/react-icons';
13
+ import RhUiAddIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-icon';
14
+ import RhUiClipboardIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-clipboard-icon';
15
+ import RhUiCodeIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-code-icon';
16
+ import RhUiUploadIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-upload-icon';
14
17
  import { useDropzone } from 'react-dropzone';
15
18
 
16
19
  export const ChatbotMessageBarCustomActionsExample: FunctionComponent = () => {
@@ -45,43 +48,51 @@ export const ChatbotMessageBarCustomActionsExample: FunctionComponent = () => {
45
48
  };
46
49
 
47
50
  const firstMenuItems: ReactNode = (
48
- <DropdownList>
49
- <DropdownItem value="Logs" id="logs" icon={<ClipboardIcon />}>
50
- Logs
51
- </DropdownItem>
52
- <DropdownItem value="YAML - Status" id="yaml-status" icon={<CodeIcon />}>
53
- YAML - Status
54
- </DropdownItem>
55
- <DropdownItem value="YAML - All contents" id="yaml-all" icon={<CodeIcon />}>
56
- YAML - All contents
57
- </DropdownItem>
51
+ <>
52
+ <DropdownList>
53
+ <DropdownItem value="Logs" id="logs" icon={<RhUiClipboardIcon />}>
54
+ Logs
55
+ </DropdownItem>
56
+ <DropdownItem value="YAML - Status" id="yaml-status" icon={<RhUiCodeIcon />}>
57
+ YAML - Status
58
+ </DropdownItem>
59
+ <DropdownItem value="YAML - All contents" id="yaml-all" icon={<RhUiCodeIcon />}>
60
+ YAML - All contents
61
+ </DropdownItem>
62
+ </DropdownList>
58
63
  <Divider key="divider" />
59
- <DropdownItem value="Upload from computer" id="upload" icon={<UploadIcon />} onClick={open}>
60
- Upload from computer
61
- </DropdownItem>
62
- </DropdownList>
64
+ <DropdownList>
65
+ <DropdownItem value="Upload from computer" id="upload" icon={<RhUiUploadIcon />} onClick={open}>
66
+ Upload from computer
67
+ </DropdownItem>
68
+ </DropdownList>
69
+ </>
63
70
  );
64
71
 
65
72
  const secondMenuItems: ReactNode = (
66
- <DropdownList>
67
- <DropdownItem value="canvas" id="canvas">
68
- {showCanvasLabel ? 'Disable' : 'Enable'} Canvas
69
- </DropdownItem>
70
- <Divider key="divider-1" />
71
- <DropdownItem value="Logs" id="logs" icon={<ClipboardIcon />}>
72
- Logs
73
- </DropdownItem>
74
- <DropdownItem value="YAML - Status" id="yaml-status" icon={<CodeIcon />}>
75
- YAML - Status
76
- </DropdownItem>
77
- <DropdownItem value="YAML - All contents" id="yaml-all" icon={<CodeIcon />}>
78
- YAML - All contents
79
- </DropdownItem>
73
+ <>
74
+ <DropdownList>
75
+ <DropdownItem value="canvas" id="canvas">
76
+ {showCanvasLabel ? 'Disable' : 'Enable'} Canvas
77
+ </DropdownItem>
78
+ <Divider key="divider-1" />
79
+ <DropdownItem value="Logs" id="logs" icon={<RhUiClipboardIcon />}>
80
+ Logs
81
+ </DropdownItem>
82
+ <DropdownItem value="YAML - Status" id="yaml-status" icon={<RhUiCodeIcon />}>
83
+ YAML - Status
84
+ </DropdownItem>
85
+ <DropdownItem value="YAML - All contents" id="yaml-all" icon={<RhUiCodeIcon />}>
86
+ YAML - All contents
87
+ </DropdownItem>
88
+ </DropdownList>
80
89
  <Divider key="divider-2" />
81
- <DropdownItem value="Upload from computer" id="upload" icon={<UploadIcon />} onClick={open}>
82
- Upload from computer
83
- </DropdownItem>
84
- </DropdownList>
90
+ <DropdownList>
91
+ <DropdownItem value="Upload from computer" id="upload" icon={<RhUiUploadIcon />} onClick={open}>
92
+ Upload from computer
93
+ </DropdownItem>
94
+ </DropdownList>
95
+ </>
85
96
  );
86
97
 
87
98
  const modelOptions = ['GPT-4', 'GPT-3.5', 'Claude', 'Llama 2'];
@@ -110,7 +121,7 @@ export const ChatbotMessageBarCustomActionsExample: FunctionComponent = () => {
110
121
  }}
111
122
  buttonProps={{
112
123
  attach: {
113
- icon: <PlusIcon />,
124
+ icon: <RhUiAddIcon />,
114
125
  tooltipContent: 'Message actions',
115
126
  'aria-label': 'Message actions'
116
127
  }
@@ -140,7 +151,7 @@ export const ChatbotMessageBarCustomActionsExample: FunctionComponent = () => {
140
151
  }}
141
152
  buttonProps={{
142
153
  attach: {
143
- icon: <PlusIcon />,
154
+ icon: <RhUiAddIcon />,
144
155
  tooltipContent: 'Message actions',
145
156
  'aria-label': 'Message actions'
146
157
  }
@@ -70,7 +70,13 @@ import { MessageBar } from '@patternfly/chatbot/dist/dynamic/MessageBar';
70
70
  import SourceDetailsMenuItem from '@patternfly/chatbot/dist/dynamic/SourceDetailsMenuItem';
71
71
  import { ChatbotModal } from '@patternfly/chatbot/dist/dynamic/ChatbotModal';
72
72
  import SettingsForm from '@patternfly/chatbot/dist/dynamic/Settings';
73
- import { BellIcon, CalendarAltIcon, ClipboardIcon, CodeIcon, PlusIcon, ThumbtackIcon, UploadIcon } from '@patternfly/react-icons';
73
+ import RhUiAttentionBellIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-attention-bell-icon';
74
+ import RhUiCalendarIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-calendar-icon';
75
+ import RhUiClipboardIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-clipboard-icon';
76
+ import RhUiCodeIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-code-icon';
77
+ import RhUiAddIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-icon';
78
+ import { ThumbtackIcon } from '@patternfly/react-icons';
79
+ import RhUiUploadIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-upload-icon';
74
80
  import { useDropzone } from 'react-dropzone';
75
81
 
76
82
  import ChatbotConversationHistoryNav from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';
@@ -18,7 +18,7 @@ import ChatbotFooter from '@patternfly/chatbot/dist/dynamic/ChatbotFooter';
18
18
  import MessageBar from '@patternfly/chatbot/dist/dynamic/MessageBar';
19
19
  import MessageBox from '@patternfly/chatbot/dist/dynamic/MessageBox';
20
20
  import Message, { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message';
21
- import ChatbotHeader, { ChatbotHeaderMain } from '@patternfly/chatbot/dist/dynamic/ChatbotHeader';
21
+ import ChatbotHeader, { ChatbotHeaderMain, ChatbotHeaderTitle } from '@patternfly/chatbot/dist/dynamic/ChatbotHeader';
22
22
  import Compare from '@patternfly/chatbot/dist/dynamic/Compare';
23
23
  import { BarsIcon } from '@patternfly/react-icons';
24
24
  import userAvatar from '../Messages/user_avatar.svg';
@@ -115,7 +115,9 @@ export const CompareChild = ({ name, input, hasNewInput, setIsSendButtonDisabled
115
115
  return (
116
116
  <Chatbot displayMode={displayMode}>
117
117
  <ChatbotHeader>
118
- <ChatbotHeaderMain>{name}</ChatbotHeaderMain>
118
+ <ChatbotHeaderMain>
119
+ <ChatbotHeaderTitle>{name}</ChatbotHeaderTitle>
120
+ </ChatbotHeaderMain>
119
121
  </ChatbotHeader>
120
122
  <ChatbotContent>
121
123
  <MessageBox ariaLabel={`Scrollable message log for ${name}`} announcement={announcement}>
@@ -1,5 +1,4 @@
1
1
  .pf-chatbot__menu.pf-v6-c-menu {
2
- --pf-v6-c-menu--BorderRadius: var(--pf-t--global--border--radius--large);
3
2
  --pf-v6-c-menu__list-item--hover--BackgroundColor: var(--pf-t--global--background--color--secondary--default);
4
3
  }
5
4
 
@@ -31,10 +30,6 @@
31
30
  --pf-v6-c-menu__item-main--ColumnGap: var(--pf-t--global--spacer--md);
32
31
  }
33
32
 
34
- .pf-v6-c-menu__list {
35
- padding: 0rem var(--pf-t--global--spacer--md) 0rem var(--pf-t--global--spacer--md);
36
- }
37
-
38
33
  /* handles hover state, which uses a background */
39
34
  .pf-v6-c-menu__list-item {
40
35
  border-radius: var(--pf-t--global--border--radius--small);
@@ -55,8 +50,4 @@
55
50
  .pf-v6-c-menu__item-description {
56
51
  font-weight: var(--pf-t--global--font--weight--body--bold);
57
52
  }
58
-
59
- .pf-v6-c-divider {
60
- padding: 0 var(--pf-t--global--spacer--md) 0 var(--pf-t--global--spacer--md);
61
- }
62
53
  }
@@ -12,7 +12,6 @@
12
12
  background-color: var(--pf-t--global--background--color--floating--secondary--default);
13
13
  border-radius: var(--pf-t--global--border--radius--medium);
14
14
  box-shadow: var(--pf-t--global--box-shadow--lg);
15
- font-size: var(--pf-t--global--font--size--md);
16
15
  z-index: var(--pf-t--global--z-index--md);
17
16
  -webkit-font-smoothing: antialiased;
18
17
  -moz-osx-font-smoothing: grayscale;
@@ -178,9 +177,3 @@
178
177
  }
179
178
  }
180
179
 
181
- // ============================================================================
182
- // Information density styles
183
- // ============================================================================
184
- .pf-chatbot.pf-m-compact {
185
- font-size: var(--pf-t--global--font--size--sm);
186
- }
@@ -48,7 +48,7 @@
48
48
 
49
49
  // Drawer menu
50
50
  // ----------------------------------------------------------------------------
51
- .pf-v6-c-menu {
51
+ .pf-v6-c-menu.pf-chatbot__history-menu {
52
52
  --pf-v6-c-menu--PaddingBlockStart: 0;
53
53
  --pf-v6-c-menu--BackgroundColor: var(--pf-t--global--background--color--floating--default);
54
54
  // override high contrast style
@@ -290,7 +290,13 @@ export const ChatbotConversationHistoryNav: FunctionComponent<ChatbotConversatio
290
290
  return <HistoryEmptyState {...noResultsState} />;
291
291
  }
292
292
  return (
293
- <Menu isPlain onSelect={onSelectActiveItem} activeItemId={activeItemId} {...menuProps}>
293
+ <Menu
294
+ className="pf-chatbot__history-menu"
295
+ isPlain
296
+ onSelect={onSelectActiveItem}
297
+ activeItemId={activeItemId}
298
+ {...menuProps}
299
+ >
294
300
  <MenuContent {...menuContentProps}>{buildConversations()}</MenuContent>
295
301
  </Menu>
296
302
  );
@@ -24,6 +24,7 @@
24
24
 
25
25
  // Title -or- Brand
26
26
  .pf-chatbot__title {
27
+ font-size: var(--pf-t--global--font--size--body--lg);
27
28
  display: flex;
28
29
  align-items: center;
29
30
  flex: 1;
@@ -32,7 +32,7 @@
32
32
  }
33
33
 
34
34
  &--secondary {
35
- --pf-v6-c-button--m-plain--BackgroundColor: var(--pf-t--global--background--color--secondary--default);
35
+ --pf-v6-c-button--m-plain--BackgroundColor: var(--pf-t--global--background--color--floating--secondary--default);
36
36
  --pf-v6-c-button--m-plain--hover--BackgroundColor: var(--pf-t--global--background--color--secondary--hover);
37
37
  --pf-v6-c-button--m-plain--m-clicked--BackgroundColor: var(--pf-t--global--background--color--secondary--clicked);
38
38
 
@@ -11,15 +11,18 @@ import { DeepThinkingProps } from '../DeepThinking';
11
11
 
12
12
  // Mock the icon components
13
13
  jest.mock('@patternfly/react-icons', () => ({
14
- OutlinedThumbsUpIcon: () => <div>OutlinedThumbsUpIcon</div>,
15
- ThumbsUpIcon: () => <div>ThumbsUpIcon</div>,
16
- OutlinedThumbsDownIcon: () => <div>OutlinedThumbsDownIcon</div>,
17
- ThumbsDownIcon: () => <div>ThumbsDownIcon</div>,
18
- OutlinedCopyIcon: () => <div>OutlinedCopyIcon</div>,
19
- DownloadIcon: () => <div>DownloadIcon</div>,
20
- ExternalLinkAltIcon: () => <div>ExternalLinkAltIcon</div>,
21
- VolumeUpIcon: () => <div>VolumeUpIcon</div>,
22
- PencilAltIcon: () => <div>PencilAltIcon</div>,
14
+ RhUiLikeIcon: () => <div>RhUiLikeIcon</div>,
15
+ RhUiLikeFillIcon: () => <div>RhUiLikeFillIcon</div>,
16
+ RhUiDislikeIcon: () => <div>RhUiDislikeIcon</div>,
17
+ RhUiDislikeFillIcon: () => <div>RhUiDislikeFillIcon</div>,
18
+ RhUiCopyIcon: () => <div>RhUiCopyIcon</div>,
19
+ RhUiCopyFillIcon: () => <div>RhUiCopyFillIcon</div>,
20
+ RhUiEditIcon: () => <div>RhUiEditIcon</div>,
21
+ RhUiEditFillIcon: () => <div>RhUiEditFillIcon</div>,
22
+ RhUiVolumeUpIcon: () => <div>RhUiVolumeUpIcon</div>,
23
+ RhUiVolumeUpFillIcon: () => <div>RhUiVolumeUpFillIcon</div>,
24
+ RhUiExportIcon: () => <div>RhUiExportIcon</div>,
25
+ RhUiExportFillIcon: () => <div>RhUiExportFillIcon</div>,
23
26
  CheckIcon: () => <div>CheckIcon</div>,
24
27
  CloseIcon: () => <div>CloseIcon</div>,
25
28
  ExternalLinkSquareAltIcon: () => <div>ExternalLinkSquareAltIcon</div>,
@@ -118,6 +121,13 @@ const TABLE = `
118
121
 
119
122
  `;
120
123
 
124
+ const TABLE_WITH_INLINE_CODE = `
125
+ | Status | Finding |
126
+ |---|---|
127
+ | \`1/1 Running\`, 0 restarts | Healthy — no crashes |
128
+ | \`1/1 Ready\` | Desired replicas met |
129
+ `;
130
+
121
131
  const ONE_COLUMN_TABLE = `
122
132
 
123
133
  | Column 1 |
@@ -1041,6 +1051,24 @@ describe('Message', () => {
1041
1051
  render(<Message avatar="./img" role="user" name="User" content={TABLE} tableProps={{ 'aria-label': 'Test' }} />);
1042
1052
  expect(screen.getByRole('grid', { name: /Test/i })).toBeTruthy();
1043
1053
  });
1054
+ it('should wrap table cell content so inline code does not break grid layout', () => {
1055
+ render(
1056
+ <Message
1057
+ avatar="./img"
1058
+ role="user"
1059
+ name="User"
1060
+ content={TABLE_WITH_INLINE_CODE}
1061
+ tableProps={{ 'aria-label': 'Inline code table' }}
1062
+ />
1063
+ );
1064
+ const statusCell = screen.getByRole('cell', { name: /1\/1 Running/i });
1065
+ expect(statusCell.querySelector(':scope > .pf-chatbot__message-table-cell-content')).toBeTruthy();
1066
+ expect(statusCell.querySelector(':scope > code')).toBeFalsy();
1067
+ expect(statusCell.querySelector('.pf-chatbot__message-inline-code')).toBeTruthy();
1068
+ expect(
1069
+ screen.getByRole('columnheader', { name: /Status/i }).querySelector('.pf-chatbot__message-table-cell-content')
1070
+ ).toBeTruthy();
1071
+ });
1044
1072
  it('should render footnote correctly', () => {
1045
1073
  render(<Message avatar="./img" role="user" name="User" content={FOOTNOTE} />);
1046
1074
  expect(screen.getByText(/This is some text with a footnote/i)).toBeTruthy();
@@ -1398,12 +1426,12 @@ describe('Message', () => {
1398
1426
  />
1399
1427
  );
1400
1428
 
1401
- expect(screen.getByText('OutlinedThumbsUpIcon')).toBeInTheDocument();
1429
+ expect(screen.getByText('RhUiLikeIcon')).toBeInTheDocument();
1402
1430
 
1403
1431
  await user.click(screen.getByRole('button', { name: /Good response/i }));
1404
1432
 
1405
- expect(screen.getByText('OutlinedThumbsUpIcon')).toBeInTheDocument();
1406
- expect(screen.queryByText('ThumbsUpIcon')).not.toBeInTheDocument();
1433
+ expect(screen.getByText('RhUiLikeIcon')).toBeInTheDocument();
1434
+ expect(screen.queryByText('RhUiLikeFillIcon')).not.toBeInTheDocument();
1407
1435
  });
1408
1436
 
1409
1437
  it('should swap icons when useFilledIconsOnClick is true', async () => {
@@ -1424,8 +1452,8 @@ describe('Message', () => {
1424
1452
 
1425
1453
  await user.click(screen.getByRole('button', { name: /Good response/i }));
1426
1454
 
1427
- expect(screen.getByText('ThumbsUpIcon')).toBeInTheDocument();
1428
- expect(screen.queryByText('OutlinedThumbsUpIcon')).not.toBeInTheDocument();
1455
+ expect(screen.getByText('RhUiLikeFillIcon')).toBeInTheDocument();
1456
+ expect(screen.queryByText('RhUiLikeIcon')).not.toBeInTheDocument();
1429
1457
  });
1430
1458
 
1431
1459
  it('should apply pf-m-visible-interaction class to response actions when showActionsOnInteraction is true', () => {
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Wraps table cell content in a single element so phrasing content (e.g. inline
3
+ * code mixed with text) is not a direct child of td/th.
4
+ */
5
+ const TableCellContent = ({ children }: { children?: React.ReactNode }) => (
6
+ <span className="pf-chatbot__message-table-cell-content">{children}</span>
7
+ );
8
+
9
+ export default TableCellContent;
@@ -4,7 +4,12 @@
4
4
 
5
5
  import { ExtraProps } from 'react-markdown';
6
6
  import { Td, TdProps } from '@patternfly/react-table';
7
+ import TableCellContent from './TableCellContent';
7
8
 
8
- const TdMessage = ({ children, ...props }: Omit<TdProps, 'ref'> & ExtraProps) => <Td {...props}>{children}</Td>;
9
+ const TdMessage = ({ children, ...props }: Omit<TdProps, 'ref'> & ExtraProps) => (
10
+ <Td {...props}>
11
+ <TableCellContent>{children}</TableCellContent>
12
+ </Td>
13
+ );
9
14
 
10
15
  export default TdMessage;
@@ -4,7 +4,12 @@
4
4
 
5
5
  import { ExtraProps } from 'react-markdown';
6
6
  import { Th, ThProps } from '@patternfly/react-table';
7
+ import TableCellContent from './TableCellContent';
7
8
 
8
- const ThMessage = ({ children, ...props }: Omit<ThProps, 'ref'> & ExtraProps) => <Th {...props}>{children}</Th>;
9
+ const ThMessage = ({ children, ...props }: Omit<ThProps, 'ref'> & ExtraProps) => (
10
+ <Th {...props}>
11
+ <TableCellContent>{children}</TableCellContent>
12
+ </Th>
13
+ );
9
14
 
10
15
  export default ThMessage;
@@ -7,17 +7,21 @@ import Message from '../Message';
7
7
 
8
8
  // Mock the icon components
9
9
  jest.mock('@patternfly/react-icons', () => ({
10
- OutlinedThumbsUpIcon: () => <div>OutlinedThumbsUpIcon</div>,
11
- ThumbsUpIcon: () => <div>ThumbsUpIcon</div>,
12
- OutlinedThumbsDownIcon: () => <div>OutlinedThumbsDownIcon</div>,
13
- ThumbsDownIcon: () => <div>ThumbsDownIcon</div>,
14
- OutlinedCopyIcon: () => <div>OutlinedCopyIcon</div>,
10
+ RhUiLikeIcon: () => <div>RhUiLikeIcon</div>,
11
+ RhUiLikeFillIcon: () => <div>RhUiLikeFillIcon</div>,
12
+ RhUiDislikeIcon: () => <div>RhUiDislikeIcon</div>,
13
+ RhUiDislikeFillIcon: () => <div>RhUiDislikeFillIcon</div>,
14
+ RhUiCopyIcon: () => <div>RhUiCopyIcon</div>,
15
+ RhUiCopyFillIcon: () => <div>RhUiCopyFillIcon</div>,
16
+ RhUiEditIcon: () => <div>RhUiEditIcon</div>,
17
+ RhUiEditFillIcon: () => <div>RhUiEditFillIcon</div>,
18
+ RhUiVolumeUpIcon: () => <div>RhUiVolumeUpIcon</div>,
19
+ RhUiVolumeUpFillIcon: () => <div>RhUiVolumeUpFillIcon</div>,
20
+ RhUiExportIcon: () => <div>RhUiExportIcon</div>,
21
+ RhUiExportFillIcon: () => <div>RhUiExportFillIcon</div>,
15
22
  DownloadIcon: () => <div>DownloadIcon</div>,
16
23
  InfoCircleIcon: () => <div>InfoCircleIcon</div>,
17
- RedoIcon: () => <div>RedoIcon</div>,
18
- ExternalLinkAltIcon: () => <div>ExternalLinkAltIcon</div>,
19
- VolumeUpIcon: () => <div>VolumeUpIcon</div>,
20
- PencilAltIcon: () => <div>PencilAltIcon</div>
24
+ RedoIcon: () => <div>RedoIcon</div>
21
25
  }));
22
26
 
23
27
  const ALL_ACTIONS = [
@@ -507,11 +511,11 @@ describe('ResponseActions', () => {
507
511
  />
508
512
  );
509
513
 
510
- expect(screen.getByText('OutlinedThumbsUpIcon')).toBeInTheDocument();
511
- expect(screen.getByText('OutlinedThumbsDownIcon')).toBeInTheDocument();
514
+ expect(screen.getByText('RhUiLikeIcon')).toBeInTheDocument();
515
+ expect(screen.getByText('RhUiDislikeIcon')).toBeInTheDocument();
512
516
 
513
- expect(screen.queryByText('ThumbsUpIcon')).not.toBeInTheDocument();
514
- expect(screen.queryByText('ThumbsDownIcon')).not.toBeInTheDocument();
517
+ expect(screen.queryByText('RhUiLikeFillIcon')).not.toBeInTheDocument();
518
+ expect(screen.queryByText('RhUiDislikeFillIcon')).not.toBeInTheDocument();
515
519
  });
516
520
 
517
521
  describe('positive actions', () => {
@@ -529,8 +533,8 @@ describe('ResponseActions', () => {
529
533
 
530
534
  await user.click(screen.getByRole('button', { name: 'Good response' }));
531
535
 
532
- expect(screen.getByText('OutlinedThumbsUpIcon')).toBeInTheDocument();
533
- expect(screen.queryByText('ThumbsUpIcon')).not.toBeInTheDocument();
536
+ expect(screen.getByText('RhUiLikeIcon')).toBeInTheDocument();
537
+ expect(screen.queryByText('RhUiLikeFillIcon')).not.toBeInTheDocument();
534
538
  });
535
539
 
536
540
  it('should swap positive icon from outline to filled when clicked with useFilledIconsOnClick', async () => {
@@ -547,8 +551,8 @@ describe('ResponseActions', () => {
547
551
 
548
552
  await user.click(screen.getByRole('button', { name: 'Good response' }));
549
553
 
550
- expect(screen.getByText('ThumbsUpIcon')).toBeInTheDocument();
551
- expect(screen.queryByText('OutlinedThumbsUpIcon')).not.toBeInTheDocument();
554
+ expect(screen.getByText('RhUiLikeFillIcon')).toBeInTheDocument();
555
+ expect(screen.queryByText('RhUiLikeIcon')).not.toBeInTheDocument();
552
556
  });
553
557
 
554
558
  it('should revert positive icon to outline icon when clicking outside', async () => {
@@ -567,10 +571,10 @@ describe('ResponseActions', () => {
567
571
  );
568
572
 
569
573
  await user.click(screen.getByRole('button', { name: 'Good response' }));
570
- expect(screen.getByText('ThumbsUpIcon')).toBeInTheDocument();
574
+ expect(screen.getByText('RhUiLikeFillIcon')).toBeInTheDocument();
571
575
 
572
576
  await user.click(screen.getByTestId('outside'));
573
- expect(screen.getByText('OutlinedThumbsUpIcon')).toBeInTheDocument();
577
+ expect(screen.getByText('RhUiLikeIcon')).toBeInTheDocument();
574
578
  });
575
579
 
576
580
  it('should not revert positive icon to outline icon when clicking outside if persistActionSelection is true', async () => {
@@ -590,10 +594,10 @@ describe('ResponseActions', () => {
590
594
  );
591
595
 
592
596
  await user.click(screen.getByRole('button', { name: 'Good response' }));
593
- expect(screen.getByText('ThumbsUpIcon')).toBeInTheDocument();
597
+ expect(screen.getByText('RhUiLikeFillIcon')).toBeInTheDocument();
594
598
 
595
599
  await user.click(screen.getByTestId('outside'));
596
- expect(screen.getByText('ThumbsUpIcon')).toBeInTheDocument();
600
+ expect(screen.getByText('RhUiLikeFillIcon')).toBeInTheDocument();
597
601
  });
598
602
 
599
603
  describe('negative actions', () => {
@@ -611,8 +615,8 @@ describe('ResponseActions', () => {
611
615
 
612
616
  await user.click(screen.getByRole('button', { name: 'Bad response' }));
613
617
 
614
- expect(screen.getByText('OutlinedThumbsDownIcon')).toBeInTheDocument();
615
- expect(screen.queryByText('ThumbsDownIcon')).not.toBeInTheDocument();
618
+ expect(screen.getByText('RhUiDislikeIcon')).toBeInTheDocument();
619
+ expect(screen.queryByText('RhUiDislikeFillIcon')).not.toBeInTheDocument();
616
620
  });
617
621
 
618
622
  it('should swap negative icon from outline to filled when clicked with useFilledIconsOnClick', async () => {
@@ -629,8 +633,8 @@ describe('ResponseActions', () => {
629
633
 
630
634
  await user.click(screen.getByRole('button', { name: 'Bad response' }));
631
635
 
632
- expect(screen.getByText('ThumbsDownIcon')).toBeInTheDocument();
633
- expect(screen.queryByText('OutlinedThumbsDownIcon')).not.toBeInTheDocument();
636
+ expect(screen.getByText('RhUiDislikeFillIcon')).toBeInTheDocument();
637
+ expect(screen.queryByText('RhUiDislikeIcon')).not.toBeInTheDocument();
634
638
  });
635
639
 
636
640
  it('should revert negative icon to outline when clicking outside', async () => {
@@ -649,10 +653,10 @@ describe('ResponseActions', () => {
649
653
  );
650
654
 
651
655
  await user.click(screen.getByRole('button', { name: 'Bad response' }));
652
- expect(screen.getByText('ThumbsDownIcon')).toBeInTheDocument();
656
+ expect(screen.getByText('RhUiDislikeFillIcon')).toBeInTheDocument();
653
657
 
654
658
  await user.click(screen.getByTestId('outside'));
655
- expect(screen.getByText('OutlinedThumbsDownIcon')).toBeInTheDocument();
659
+ expect(screen.getByText('RhUiDislikeIcon')).toBeInTheDocument();
656
660
  });
657
661
 
658
662
  it('should not revert negative icon to outline icon when clicking outside if persistActionSelection is true', async () => {
@@ -672,10 +676,10 @@ describe('ResponseActions', () => {
672
676
  );
673
677
 
674
678
  await user.click(screen.getByRole('button', { name: 'Bad response' }));
675
- expect(screen.getByText('ThumbsDownIcon')).toBeInTheDocument();
679
+ expect(screen.getByText('RhUiDislikeFillIcon')).toBeInTheDocument();
676
680
 
677
681
  await user.click(screen.getByTestId('outside'));
678
- expect(screen.getByText('ThumbsDownIcon')).toBeInTheDocument();
682
+ expect(screen.getByText('RhUiDislikeFillIcon')).toBeInTheDocument();
679
683
  });
680
684
  });
681
685
  });
@@ -1,15 +1,18 @@
1
1
  import type { FunctionComponent, MouseEvent } from 'react';
2
2
  import { useEffect, useRef, useState } from 'react';
3
3
  import {
4
- ExternalLinkAltIcon,
5
- VolumeUpIcon,
6
- OutlinedThumbsUpIcon,
7
- ThumbsUpIcon,
8
- OutlinedThumbsDownIcon,
9
- ThumbsDownIcon,
10
- OutlinedCopyIcon,
11
- DownloadIcon,
12
- PencilAltIcon
4
+ RhUiLikeIcon,
5
+ RhUiLikeFillIcon,
6
+ RhUiDislikeIcon,
7
+ RhUiDislikeFillIcon,
8
+ RhUiCopyIcon,
9
+ RhUiCopyFillIcon,
10
+ RhUiEditIcon,
11
+ RhUiEditFillIcon,
12
+ RhUiVolumeUpIcon,
13
+ RhUiVolumeUpFillIcon,
14
+ RhUiExportIcon,
15
+ RhUiExportFillIcon
13
16
  } from '@patternfly/react-icons';
14
17
  import ResponseActionButton from './ResponseActionButton';
15
18
  import { ButtonProps, TooltipProps } from '@patternfly/react-core';
@@ -164,12 +167,28 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
164
167
 
165
168
  const iconMap = {
166
169
  positive: {
167
- filled: <ThumbsUpIcon />,
168
- outlined: <OutlinedThumbsUpIcon />
170
+ filled: <RhUiLikeFillIcon />,
171
+ outlined: <RhUiLikeIcon />
169
172
  },
170
173
  negative: {
171
- filled: <ThumbsDownIcon />,
172
- outlined: <OutlinedThumbsDownIcon />
174
+ filled: <RhUiDislikeFillIcon />,
175
+ outlined: <RhUiDislikeIcon />
176
+ },
177
+ listen: {
178
+ filled: <RhUiVolumeUpFillIcon />,
179
+ outlined: <RhUiVolumeUpIcon />
180
+ },
181
+ copy: {
182
+ filled: <RhUiCopyFillIcon />,
183
+ outlined: <RhUiCopyIcon />
184
+ },
185
+ edit: {
186
+ filled: <RhUiEditFillIcon />,
187
+ outlined: <RhUiEditIcon />
188
+ },
189
+ download: {
190
+ filled: <RhUiExportFillIcon />,
191
+ outlined: <RhUiExportIcon />
173
192
  }
174
193
  };
175
194
 
@@ -247,7 +266,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
247
266
  tooltipContent={copy.tooltipContent ?? 'Copy'}
248
267
  clickedTooltipContent={copy.clickedTooltipContent ?? 'Copied'}
249
268
  tooltipProps={getTooltipProps(copy.tooltipProps)}
250
- icon={<OutlinedCopyIcon />}
269
+ icon={getIcon('copy')}
251
270
  isClicked={activeButton === 'copy'}
252
271
  ref={copy.ref}
253
272
  aria-expanded={copy['aria-expanded']}
@@ -265,7 +284,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
265
284
  tooltipContent={edit.tooltipContent ?? 'Edit '}
266
285
  clickedTooltipContent={edit.clickedTooltipContent ?? 'Editing'}
267
286
  tooltipProps={getTooltipProps(edit.tooltipProps)}
268
- icon={<PencilAltIcon />}
287
+ icon={getIcon('edit')}
269
288
  isClicked={activeButton === 'edit'}
270
289
  ref={edit.ref}
271
290
  aria-expanded={edit['aria-expanded']}
@@ -283,7 +302,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
283
302
  tooltipContent={share.tooltipContent ?? 'Share'}
284
303
  clickedTooltipContent={share.clickedTooltipContent ?? 'Shared'}
285
304
  tooltipProps={getTooltipProps(share.tooltipProps)}
286
- icon={<ExternalLinkAltIcon />}
305
+ icon={getIcon('download')}
287
306
  isClicked={activeButton === 'share'}
288
307
  ref={share.ref}
289
308
  aria-expanded={share['aria-expanded']}
@@ -301,7 +320,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
301
320
  tooltipContent={download.tooltipContent ?? 'Download'}
302
321
  clickedTooltipContent={download.clickedTooltipContent ?? 'Downloaded'}
303
322
  tooltipProps={getTooltipProps(download.tooltipProps)}
304
- icon={<DownloadIcon />}
323
+ icon={getIcon('download')}
305
324
  isClicked={activeButton === 'download'}
306
325
  ref={download.ref}
307
326
  aria-expanded={download['aria-expanded']}
@@ -319,7 +338,7 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
319
338
  tooltipContent={listen.tooltipContent ?? 'Listen'}
320
339
  clickedTooltipContent={listen.clickedTooltipContent ?? 'Listening'}
321
340
  tooltipProps={getTooltipProps(listen.tooltipProps)}
322
- icon={<VolumeUpIcon />}
341
+ icon={getIcon('listen')}
323
342
  isClicked={activeButton === 'listen'}
324
343
  ref={listen.ref}
325
344
  aria-expanded={listen['aria-expanded']}
@@ -25,6 +25,11 @@
25
25
  list-style: none;
26
26
  gap: var(--pf-t--global--spacer--xs);
27
27
  }
28
+
29
+ .pf-chatbot__sources-list-item {
30
+ width: 100%;
31
+ max-width: var(--pf-chatbot-sources-card-max-width);
32
+ }
28
33
  }
29
34
 
30
35
  .pf-chatbot__sources-card {