@patternfly/chatbot 6.3.0-prerelease.1 → 6.3.0-prerelease.11

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 (259) hide show
  1. package/dist/cjs/AttachmentEdit/AttachmentEdit.d.ts +2 -0
  2. package/dist/cjs/AttachmentEdit/AttachmentEdit.js +2 -2
  3. package/dist/cjs/Chatbot/Chatbot.d.ts +2 -0
  4. package/dist/cjs/Chatbot/Chatbot.js +2 -2
  5. package/dist/cjs/Chatbot/Chatbot.test.js +4 -0
  6. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +2 -0
  7. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +3 -3
  8. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +4 -0
  9. package/dist/cjs/ChatbotFooter/ChatbotFooter.d.ts +1 -0
  10. package/dist/cjs/ChatbotFooter/ChatbotFooter.js +2 -2
  11. package/dist/cjs/ChatbotFooter/ChatbotFooter.test.d.ts +1 -1
  12. package/dist/cjs/ChatbotFooter/ChatbotFooter.test.js +5 -0
  13. package/dist/cjs/ChatbotHeader/ChatbotHeader.js +1 -1
  14. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +4 -2
  15. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.js +20 -6
  16. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.test.d.ts +1 -1
  17. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.test.js +5 -0
  18. package/dist/cjs/ChatbotHeader/ChatbotHeaderMain.js +1 -1
  19. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.d.ts +3 -2
  20. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +20 -6
  21. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.test.d.ts +1 -1
  22. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.test.js +5 -0
  23. package/dist/cjs/ChatbotHeader/ChatbotHeaderOptionsDropdown.d.ts +1 -0
  24. package/dist/cjs/ChatbotHeader/ChatbotHeaderOptionsDropdown.js +3 -3
  25. package/dist/cjs/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.d.ts +1 -1
  26. package/dist/cjs/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.js +5 -0
  27. package/dist/cjs/ChatbotHeader/ChatbotHeaderSelectorDropdown.d.ts +1 -0
  28. package/dist/cjs/ChatbotHeader/ChatbotHeaderSelectorDropdown.js +2 -2
  29. package/dist/cjs/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.d.ts +1 -1
  30. package/dist/cjs/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.js +5 -0
  31. package/dist/cjs/ChatbotModal/ChatbotModal.d.ts +3 -0
  32. package/dist/cjs/ChatbotModal/ChatbotModal.js +2 -2
  33. package/dist/cjs/ChatbotModal/ChatbotModal.test.d.ts +1 -0
  34. package/dist/cjs/ChatbotModal/ChatbotModal.test.js +28 -0
  35. package/dist/cjs/ChatbotPopover/ChatbotPopover.js +1 -1
  36. package/dist/cjs/ChatbotWelcomePrompt/ChatbotWelcomePrompt.d.ts +1 -0
  37. package/dist/cjs/ChatbotWelcomePrompt/ChatbotWelcomePrompt.js +3 -3
  38. package/dist/cjs/ChatbotWelcomePrompt/ChatbotWelcomePrompt.test.js +4 -0
  39. package/dist/cjs/CodeModal/CodeModal.d.ts +2 -0
  40. package/dist/cjs/CodeModal/CodeModal.js +3 -3
  41. package/dist/cjs/CodeModal/CodeModal.test.d.ts +1 -0
  42. package/dist/cjs/CodeModal/CodeModal.test.js +15 -0
  43. package/dist/cjs/FileDetails/FileDetails.js +1 -1
  44. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +1 -1
  45. package/dist/cjs/Message/Message.d.ts +2 -0
  46. package/dist/cjs/Message/Message.js +6 -6
  47. package/dist/cjs/Message/Message.test.js +15 -3
  48. package/dist/cjs/Message/QuickResponse/QuickResponse.d.ts +2 -0
  49. package/dist/cjs/Message/QuickResponse/QuickResponse.js +2 -2
  50. package/dist/cjs/Message/QuickStarts/QuickStartTile.d.ts +2 -0
  51. package/dist/cjs/Message/QuickStarts/QuickStartTile.js +2 -2
  52. package/dist/cjs/Message/UserFeedback/UserFeedback.js +4 -4
  53. package/dist/cjs/Message/UserFeedback/UserFeedback.test.js +4 -0
  54. package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.js +4 -4
  55. package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.test.js +4 -0
  56. package/dist/cjs/MessageBar/AttachButton.d.ts +1 -0
  57. package/dist/cjs/MessageBar/AttachButton.js +3 -3
  58. package/dist/cjs/MessageBar/AttachButton.test.js +11 -7
  59. package/dist/cjs/MessageBar/MessageBar.d.ts +5 -0
  60. package/dist/cjs/MessageBar/MessageBar.js +14 -13
  61. package/dist/cjs/MessageBar/MessageBar.test.js +41 -28
  62. package/dist/cjs/MessageBar/MicrophoneButton.d.ts +1 -0
  63. package/dist/cjs/MessageBar/MicrophoneButton.js +3 -3
  64. package/dist/cjs/MessageBar/SendButton.d.ts +1 -0
  65. package/dist/cjs/MessageBar/SendButton.js +3 -3
  66. package/dist/cjs/MessageBar/SendButton.test.js +9 -5
  67. package/dist/cjs/MessageBar/StopButton.d.ts +1 -0
  68. package/dist/cjs/MessageBar/StopButton.js +3 -3
  69. package/dist/cjs/MessageBar/StopButton.test.js +9 -5
  70. package/dist/cjs/MessageBox/JumpButton.js +1 -1
  71. package/dist/cjs/MessageBox/JumpButton.test.js +4 -4
  72. package/dist/cjs/MessageBox/MessageBox.d.ts +4 -0
  73. package/dist/cjs/MessageBox/MessageBox.js +16 -2
  74. package/dist/cjs/MessageBox/MessageBox.test.js +43 -0
  75. package/dist/cjs/PreviewAttachment/PreviewAttachment.d.ts +2 -0
  76. package/dist/cjs/PreviewAttachment/PreviewAttachment.js +2 -2
  77. package/dist/cjs/Settings/SettingsForm.d.ts +2 -0
  78. package/dist/cjs/Settings/SettingsForm.js +2 -2
  79. package/dist/cjs/Settings/SettingsForm.test.d.ts +1 -1
  80. package/dist/cjs/Settings/SettingsForm.test.js +12 -0
  81. package/dist/cjs/SourcesCard/SourcesCard.js +2 -2
  82. package/dist/cjs/TermsOfUse/TermsOfUse.d.ts +2 -0
  83. package/dist/cjs/TermsOfUse/TermsOfUse.js +5 -5
  84. package/dist/css/main.css +218 -15
  85. package/dist/css/main.css.map +1 -1
  86. package/dist/esm/AttachmentEdit/AttachmentEdit.d.ts +2 -0
  87. package/dist/esm/AttachmentEdit/AttachmentEdit.js +2 -2
  88. package/dist/esm/Chatbot/Chatbot.d.ts +2 -0
  89. package/dist/esm/Chatbot/Chatbot.js +2 -2
  90. package/dist/esm/Chatbot/Chatbot.test.js +4 -0
  91. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +2 -0
  92. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +3 -3
  93. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +4 -0
  94. package/dist/esm/ChatbotFooter/ChatbotFooter.d.ts +1 -0
  95. package/dist/esm/ChatbotFooter/ChatbotFooter.js +2 -2
  96. package/dist/esm/ChatbotFooter/ChatbotFooter.test.d.ts +1 -1
  97. package/dist/esm/ChatbotFooter/ChatbotFooter.test.js +5 -0
  98. package/dist/esm/ChatbotHeader/ChatbotHeader.js +1 -1
  99. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +4 -2
  100. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.js +20 -6
  101. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.test.d.ts +1 -1
  102. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.test.js +5 -0
  103. package/dist/esm/ChatbotHeader/ChatbotHeaderMain.js +1 -1
  104. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.d.ts +3 -2
  105. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +20 -6
  106. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.test.d.ts +1 -1
  107. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.test.js +5 -0
  108. package/dist/esm/ChatbotHeader/ChatbotHeaderOptionsDropdown.d.ts +1 -0
  109. package/dist/esm/ChatbotHeader/ChatbotHeaderOptionsDropdown.js +3 -3
  110. package/dist/esm/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.d.ts +1 -1
  111. package/dist/esm/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.js +5 -0
  112. package/dist/esm/ChatbotHeader/ChatbotHeaderSelectorDropdown.d.ts +1 -0
  113. package/dist/esm/ChatbotHeader/ChatbotHeaderSelectorDropdown.js +2 -2
  114. package/dist/esm/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.d.ts +1 -1
  115. package/dist/esm/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.js +5 -0
  116. package/dist/esm/ChatbotModal/ChatbotModal.d.ts +3 -0
  117. package/dist/esm/ChatbotModal/ChatbotModal.js +2 -2
  118. package/dist/esm/ChatbotModal/ChatbotModal.test.d.ts +1 -0
  119. package/dist/esm/ChatbotModal/ChatbotModal.test.js +23 -0
  120. package/dist/esm/ChatbotPopover/ChatbotPopover.js +1 -1
  121. package/dist/esm/ChatbotWelcomePrompt/ChatbotWelcomePrompt.d.ts +1 -0
  122. package/dist/esm/ChatbotWelcomePrompt/ChatbotWelcomePrompt.js +3 -3
  123. package/dist/esm/ChatbotWelcomePrompt/ChatbotWelcomePrompt.test.js +4 -0
  124. package/dist/esm/CodeModal/CodeModal.d.ts +2 -0
  125. package/dist/esm/CodeModal/CodeModal.js +3 -3
  126. package/dist/esm/CodeModal/CodeModal.test.d.ts +1 -0
  127. package/dist/esm/CodeModal/CodeModal.test.js +10 -0
  128. package/dist/esm/FileDetails/FileDetails.js +1 -1
  129. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +1 -1
  130. package/dist/esm/Message/Message.d.ts +2 -0
  131. package/dist/esm/Message/Message.js +6 -6
  132. package/dist/esm/Message/Message.test.js +15 -3
  133. package/dist/esm/Message/QuickResponse/QuickResponse.d.ts +2 -0
  134. package/dist/esm/Message/QuickResponse/QuickResponse.js +2 -2
  135. package/dist/esm/Message/QuickStarts/QuickStartTile.d.ts +2 -0
  136. package/dist/esm/Message/QuickStarts/QuickStartTile.js +2 -2
  137. package/dist/esm/Message/UserFeedback/UserFeedback.js +4 -4
  138. package/dist/esm/Message/UserFeedback/UserFeedback.test.js +4 -0
  139. package/dist/esm/Message/UserFeedback/UserFeedbackComplete.js +4 -4
  140. package/dist/esm/Message/UserFeedback/UserFeedbackComplete.test.js +4 -0
  141. package/dist/esm/MessageBar/AttachButton.d.ts +1 -0
  142. package/dist/esm/MessageBar/AttachButton.js +3 -3
  143. package/dist/esm/MessageBar/AttachButton.test.js +11 -7
  144. package/dist/esm/MessageBar/MessageBar.d.ts +5 -0
  145. package/dist/esm/MessageBar/MessageBar.js +14 -13
  146. package/dist/esm/MessageBar/MessageBar.test.js +41 -28
  147. package/dist/esm/MessageBar/MicrophoneButton.d.ts +1 -0
  148. package/dist/esm/MessageBar/MicrophoneButton.js +3 -3
  149. package/dist/esm/MessageBar/SendButton.d.ts +1 -0
  150. package/dist/esm/MessageBar/SendButton.js +3 -3
  151. package/dist/esm/MessageBar/SendButton.test.js +9 -5
  152. package/dist/esm/MessageBar/StopButton.d.ts +1 -0
  153. package/dist/esm/MessageBar/StopButton.js +3 -3
  154. package/dist/esm/MessageBar/StopButton.test.js +9 -5
  155. package/dist/esm/MessageBox/JumpButton.js +1 -1
  156. package/dist/esm/MessageBox/JumpButton.test.js +4 -4
  157. package/dist/esm/MessageBox/MessageBox.d.ts +4 -0
  158. package/dist/esm/MessageBox/MessageBox.js +16 -2
  159. package/dist/esm/MessageBox/MessageBox.test.js +44 -1
  160. package/dist/esm/PreviewAttachment/PreviewAttachment.d.ts +2 -0
  161. package/dist/esm/PreviewAttachment/PreviewAttachment.js +2 -2
  162. package/dist/esm/Settings/SettingsForm.d.ts +2 -0
  163. package/dist/esm/Settings/SettingsForm.js +2 -2
  164. package/dist/esm/Settings/SettingsForm.test.d.ts +1 -1
  165. package/dist/esm/Settings/SettingsForm.test.js +12 -0
  166. package/dist/esm/SourcesCard/SourcesCard.js +2 -2
  167. package/dist/esm/TermsOfUse/TermsOfUse.d.ts +2 -0
  168. package/dist/esm/TermsOfUse/TermsOfUse.js +5 -5
  169. package/dist/tsconfig.tsbuildinfo +1 -1
  170. package/package.json +1 -1
  171. package/patternfly-docs/content/extensions/chatbot/examples/Messages/AttachmentEdit.tsx +10 -1
  172. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithFeedback.tsx +33 -0
  173. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickResponses.tsx +24 -0
  174. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickStart.tsx +11 -0
  175. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithSources.tsx +21 -0
  176. package/patternfly-docs/content/extensions/chatbot/examples/Messages/PreviewAttachment.tsx +10 -1
  177. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +9 -0
  178. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithActions.tsx +9 -0
  179. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithSelection.tsx +11 -2
  180. package/patternfly-docs/content/extensions/chatbot/examples/UI/CompactSettings.tsx +289 -0
  181. package/patternfly-docs/content/extensions/chatbot/examples/UI/TermsOfUseCompact.tsx +136 -0
  182. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +14 -0
  183. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +8 -1
  184. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotCompact.tsx +481 -0
  185. package/src/AttachmentEdit/AttachmentEdit.tsx +5 -1
  186. package/src/Chatbot/Chatbot.scss +7 -0
  187. package/src/Chatbot/Chatbot.test.tsx +9 -0
  188. package/src/Chatbot/Chatbot.tsx +4 -1
  189. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +38 -3
  190. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +18 -0
  191. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +9 -2
  192. package/src/ChatbotFooter/ChatbotFooter.scss +5 -0
  193. package/src/ChatbotFooter/ChatbotFooter.test.tsx +10 -0
  194. package/src/ChatbotFooter/ChatbotFooter.tsx +3 -1
  195. package/src/ChatbotHeader/ChatbotHeader.scss +25 -0
  196. package/src/ChatbotHeader/ChatbotHeader.tsx +1 -1
  197. package/src/ChatbotHeader/ChatbotHeaderCloseButton.test.tsx +6 -0
  198. package/src/ChatbotHeader/ChatbotHeaderCloseButton.tsx +12 -6
  199. package/src/ChatbotHeader/ChatbotHeaderMain.tsx +3 -1
  200. package/src/ChatbotHeader/ChatbotHeaderMenu.test.tsx +8 -0
  201. package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +10 -5
  202. package/src/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.tsx +6 -0
  203. package/src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx +5 -2
  204. package/src/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.tsx +10 -0
  205. package/src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx +4 -0
  206. package/src/ChatbotModal/ChatbotModal.scss +15 -4
  207. package/src/ChatbotModal/ChatbotModal.test.tsx +59 -0
  208. package/src/ChatbotModal/ChatbotModal.tsx +5 -1
  209. package/src/ChatbotPopover/ChatbotPopover.scss +9 -5
  210. package/src/ChatbotPopover/ChatbotPopover.tsx +1 -1
  211. package/src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss +9 -1
  212. package/src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.test.tsx +13 -0
  213. package/src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.tsx +13 -2
  214. package/src/ChatbotWelcomePrompt/__snapshots__/ChatbotWelcomePrompt.test.tsx.snap +1 -1
  215. package/src/CodeModal/CodeModal.scss +11 -3
  216. package/src/CodeModal/CodeModal.test.tsx +24 -0
  217. package/src/CodeModal/CodeModal.tsx +6 -2
  218. package/src/FileDetails/FileDetails.tsx +1 -1
  219. package/src/FileDetails/__snapshots__/FileDetails.test.tsx.snap +1 -1
  220. package/src/FileDetailsLabel/__snapshots__/FileDetailsLabel.test.tsx.snap +1 -1
  221. package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +1 -1
  222. package/src/Message/Message.scss +27 -0
  223. package/src/Message/Message.test.tsx +24 -3
  224. package/src/Message/Message.tsx +10 -3
  225. package/src/Message/QuickResponse/QuickResponse.tsx +5 -1
  226. package/src/Message/QuickStarts/QuickStartTile.tsx +5 -1
  227. package/src/Message/TextMessage/TextMessage.scss +25 -0
  228. package/src/Message/UserFeedback/UserFeedback.scss +24 -3
  229. package/src/Message/UserFeedback/UserFeedback.test.tsx +13 -0
  230. package/src/Message/UserFeedback/UserFeedback.tsx +4 -2
  231. package/src/Message/UserFeedback/UserFeedbackComplete.test.tsx +4 -0
  232. package/src/Message/UserFeedback/UserFeedbackComplete.tsx +10 -2
  233. package/src/MessageBar/AttachButton.scss +10 -0
  234. package/src/MessageBar/AttachButton.test.tsx +11 -7
  235. package/src/MessageBar/AttachButton.tsx +6 -3
  236. package/src/MessageBar/MessageBar.scss +17 -0
  237. package/src/MessageBar/MessageBar.test.tsx +41 -28
  238. package/src/MessageBar/MessageBar.tsx +23 -8
  239. package/src/MessageBar/MicrophoneButton.scss +10 -0
  240. package/src/MessageBar/MicrophoneButton.tsx +7 -3
  241. package/src/MessageBar/SendButton.scss +10 -0
  242. package/src/MessageBar/SendButton.test.tsx +10 -6
  243. package/src/MessageBar/SendButton.tsx +6 -3
  244. package/src/MessageBar/StopButton.scss +10 -0
  245. package/src/MessageBar/StopButton.test.tsx +10 -6
  246. package/src/MessageBar/StopButton.tsx +6 -3
  247. package/src/MessageBox/JumpButton.test.tsx +4 -4
  248. package/src/MessageBox/JumpButton.tsx +1 -1
  249. package/src/MessageBox/MessageBox.scss +6 -0
  250. package/src/MessageBox/MessageBox.test.tsx +45 -1
  251. package/src/MessageBox/MessageBox.tsx +11 -1
  252. package/src/PreviewAttachment/PreviewAttachment.tsx +5 -1
  253. package/src/Settings/Settings.scss +11 -0
  254. package/src/Settings/SettingsForm.test.tsx +17 -0
  255. package/src/Settings/SettingsForm.tsx +12 -2
  256. package/src/SourcesCard/SourcesCard.scss +8 -0
  257. package/src/SourcesCard/SourcesCard.tsx +2 -1
  258. package/src/TermsOfUse/TermsOfUse.scss +20 -0
  259. package/src/TermsOfUse/TermsOfUse.tsx +9 -4
@@ -73,9 +73,9 @@ describe('Message bar', () => {
73
73
  });
74
74
  it('should render correctly', () => {
75
75
  render(<MessageBar onSendMessage={jest.fn} />);
76
- expect(screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
77
- expect(screen.queryByRole('button', { name: 'Send button' })).toBeFalsy();
78
- expect(screen.queryByRole('button', { name: 'Microphone button' })).toBeFalsy();
76
+ expect(screen.getByRole('button', { name: 'Attach' })).toBeTruthy();
77
+ expect(screen.queryByRole('button', { name: 'Send' })).toBeFalsy();
78
+ expect(screen.queryByRole('button', { name: 'Use microphone' })).toBeFalsy();
79
79
  expect(screen.getByRole('textbox', { name: /Send a message.../i })).toBeTruthy();
80
80
  });
81
81
  it('can send via enter key', async () => {
@@ -96,6 +96,12 @@ describe('Message bar', () => {
96
96
  expect(spy).toHaveBeenCalledTimes(1);
97
97
  expect(spy).toHaveBeenCalledWith(expect.any(Object), 'A');
98
98
  });
99
+ it('can use specified placeholder text', async () => {
100
+ render(<MessageBar onSendMessage={jest.fn} placeholder="test placeholder" />);
101
+ const input = screen.getByRole('textbox', { name: /test placeholder/i });
102
+ await userEvent.type(input, 'Hello world');
103
+ expect(input).toHaveTextContent('Hello world');
104
+ });
99
105
 
100
106
  // Send button
101
107
  // --------------------------------------------------------------------------
@@ -104,15 +110,15 @@ describe('Message bar', () => {
104
110
  const input = screen.getByRole('textbox', { name: /Send a message.../i });
105
111
  await userEvent.type(input, 'Hello world');
106
112
  expect(input).toHaveTextContent('Hello world');
107
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
113
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
108
114
  });
109
115
  it('can disable send button shown when text is input', async () => {
110
116
  render(<MessageBar onSendMessage={jest.fn} isSendButtonDisabled />);
111
117
  const input = screen.getByRole('textbox', { name: /Send a message.../i });
112
118
  await userEvent.type(input, 'Hello world');
113
119
  expect(input).toHaveTextContent('Hello world');
114
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
115
- expect(screen.getByRole('button', { name: 'Send button' })).toBeDisabled();
120
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
121
+ expect(screen.getByRole('button', { name: 'Send' })).toBeDisabled();
116
122
  });
117
123
  it('can click send button', async () => {
118
124
  const spy = jest.fn();
@@ -120,26 +126,26 @@ describe('Message bar', () => {
120
126
  const input = screen.getByRole('textbox', { name: /Send a message.../i });
121
127
  await userEvent.type(input, 'Hello world');
122
128
  expect(input).toHaveTextContent('Hello world');
123
- const sendButton = screen.getByRole('button', { name: 'Send button' });
129
+ const sendButton = screen.getByRole('button', { name: 'Send' });
124
130
  expect(sendButton).toBeTruthy();
125
131
  await userEvent.click(sendButton);
126
132
  expect(spy).toHaveBeenCalledTimes(1);
127
133
  });
128
134
  it('can always show send button', () => {
129
135
  render(<MessageBar onSendMessage={jest.fn} alwayShowSendButton />);
130
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
131
- expect(screen.getByRole('button', { name: 'Send button' })).toBeEnabled();
136
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
137
+ expect(screen.getByRole('button', { name: 'Send' })).toBeEnabled();
132
138
  });
133
139
  it('can disable send button if always showing', () => {
134
140
  render(<MessageBar onSendMessage={jest.fn} alwayShowSendButton isSendButtonDisabled />);
135
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
136
- expect(screen.getByRole('button', { name: 'Send button' })).toBeDisabled();
141
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
142
+ expect(screen.getByRole('button', { name: 'Send' })).toBeDisabled();
137
143
  });
138
144
  it('can handle buttonProps tooltipContent appropriately for send', async () => {
139
145
  render(
140
146
  <MessageBar onSendMessage={jest.fn} alwayShowSendButton buttonProps={{ send: { tooltipContent: 'Test' } }} />
141
147
  );
142
- await userEvent.click(screen.getByRole('button', { name: 'Send button' }));
148
+ await userEvent.click(screen.getByRole('button', { name: 'Send' }));
143
149
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
144
150
  });
145
151
  it('can handle buttonProps props appropriately for send', async () => {
@@ -197,13 +203,13 @@ describe('Message bar', () => {
197
203
  expect(screen.queryByRole('menuitem', { name: /Logs/i })).toBeFalsy();
198
204
  expect(screen.queryByRole('menuitem', { name: /YAML - Status/i })).toBeFalsy();
199
205
  expect(screen.queryByRole('menuitem', { name: /YAML - All contents/i })).toBeFalsy();
200
- const attachButton = screen.getByRole('button', { name: 'Attach button' });
206
+ const attachButton = screen.getByRole('button', { name: 'Attach' });
201
207
  await userEvent.click(attachButton);
202
208
  expect(attachToggleClickSpy).toHaveBeenCalledTimes(1);
203
209
  });
204
210
  it('can hide attach button', () => {
205
211
  render(<MessageBar onSendMessage={jest.fn} hasAttachButton={false} />);
206
- expect(screen.queryByRole('button', { name: 'Attach button' })).toBeFalsy();
212
+ expect(screen.queryByRole('button', { name: 'Attach' })).toBeFalsy();
207
213
  });
208
214
  // Based on this because I had no idea how to do this and was looking around: https://stackoverflow.com/a/75562651
209
215
  // See also https://developer.mozilla.org/en-US/docs/Web/API/File/File for what that file variable is doing
@@ -217,17 +223,17 @@ describe('Message bar', () => {
217
223
  buttonProps={{ attach: { inputTestId: 'input' } }}
218
224
  />
219
225
  );
220
- expect(screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
221
- await userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
226
+ expect(screen.getByRole('button', { name: 'Attach' })).toBeTruthy();
227
+ await userEvent.click(screen.getByRole('button', { name: 'Attach' }));
222
228
  const file = new File(['test'], 'test.json');
223
229
  const input = screen.getByTestId('input') as HTMLInputElement;
224
230
  await userEvent.upload(input, file);
225
231
  expect(input.files).toHaveLength(1);
226
232
  expect(spy).toHaveBeenCalledTimes(1);
227
233
  });
228
- it('can handle buttonProps tooltipContent appropriately for attach', async () => {
234
+ it('can handle buttonProps tooltipContent appropriately for attach', async () => {
229
235
  render(<MessageBar onSendMessage={jest.fn} hasAttachButton buttonProps={{ attach: { tooltipContent: 'Test' } }} />);
230
- await userEvent.click(screen.getByRole('button', { name: 'Attach button' }));
236
+ await userEvent.click(screen.getByRole('button', { name: 'Attach' }));
231
237
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
232
238
  });
233
239
  it('can handle buttonProps props appropriately for attach', async () => {
@@ -245,12 +251,12 @@ describe('Message bar', () => {
245
251
  // --------------------------------------------------------------------------
246
252
  it('can show stop button', () => {
247
253
  render(<MessageBar onSendMessage={jest.fn} hasStopButton handleStopButton={jest.fn} />);
248
- expect(screen.getByRole('button', { name: 'Stop button' })).toBeTruthy();
254
+ expect(screen.getByRole('button', { name: 'Stop' })).toBeTruthy();
249
255
  });
250
256
  it('can call handleStopButton', async () => {
251
257
  const spy = jest.fn();
252
258
  render(<MessageBar onSendMessage={jest.fn} hasStopButton handleStopButton={spy} />);
253
- await userEvent.click(screen.getByRole('button', { name: 'Stop button' }));
259
+ await userEvent.click(screen.getByRole('button', { name: 'Stop' }));
254
260
  expect(spy).toHaveBeenCalledTimes(1);
255
261
  });
256
262
  it('can handle buttonProps tooltipContent appropriately for stop', async () => {
@@ -262,7 +268,7 @@ describe('Message bar', () => {
262
268
  buttonProps={{ stop: { tooltipContent: 'Test' } }}
263
269
  />
264
270
  );
265
- await userEvent.click(screen.getByRole('button', { name: 'Stop button' }));
271
+ await userEvent.click(screen.getByRole('button', { name: 'Stop' }));
266
272
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
267
273
  });
268
274
  it('can handle buttonProps props appropriately for stop', async () => {
@@ -281,12 +287,12 @@ describe('Message bar', () => {
281
287
  // --------------------------------------------------------------------------
282
288
  it('can hide microphone button when window.SpeechRecognition is not there', () => {
283
289
  render(<MessageBar onSendMessage={jest.fn} hasMicrophoneButton />);
284
- expect(screen.queryByRole('button', { name: 'Microphone button' })).toBeFalsy();
290
+ expect(screen.queryByRole('button', { name: 'Use microphone' })).toBeFalsy();
285
291
  });
286
292
  it('can show microphone button', () => {
287
293
  mockSpeechRecognition();
288
294
  render(<MessageBar onSendMessage={jest.fn} hasMicrophoneButton />);
289
- expect(screen.getByRole('button', { name: 'Microphone button' })).toBeTruthy();
295
+ expect(screen.getByRole('button', { name: 'Use microphone' })).toBeTruthy();
290
296
  });
291
297
  it('can handle buttonProps appropriately for microphone', async () => {
292
298
  mockSpeechRecognition();
@@ -299,11 +305,18 @@ describe('Message bar', () => {
299
305
  }}
300
306
  />
301
307
  );
302
- await userEvent.click(screen.getByRole('button', { name: 'Microphone button' }));
308
+ await userEvent.click(screen.getByRole('button', { name: 'Use microphone' }));
303
309
  expect(screen.getByRole('tooltip', { name: 'Currently listening' })).toBeTruthy();
304
- await userEvent.click(screen.getByRole('button', { name: 'Microphone button' }));
310
+ await userEvent.click(screen.getByRole('button', { name: 'Stop listening' }));
305
311
  expect(screen.getByRole('tooltip', { name: 'Not currently listening' })).toBeTruthy();
306
312
  });
313
+ it('can customize the listening placeholder', async () => {
314
+ mockSpeechRecognition();
315
+ render(<MessageBar onSendMessage={jest.fn} hasMicrophoneButton listeningText="I am listening" />);
316
+ await userEvent.click(screen.getByRole('button', { name: 'Use microphone' }));
317
+ const input = screen.getByRole('textbox', { name: /I am listening/i });
318
+ expect(input).toBeTruthy();
319
+ });
307
320
  it('can handle buttonProps props appropriately for microphone', async () => {
308
321
  mockSpeechRecognition();
309
322
  render(
@@ -317,9 +330,9 @@ describe('Message bar', () => {
317
330
  });
318
331
  it('can be controlled', () => {
319
332
  render(<MessageBar onSendMessage={jest.fn} value="test" />);
320
- expect(screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
321
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
322
- expect(screen.queryByRole('button', { name: 'Microphone button' })).toBeFalsy();
333
+ expect(screen.getByRole('button', { name: 'Attach' })).toBeTruthy();
334
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
335
+ expect(screen.queryByRole('button', { name: 'Use microphone' })).toBeFalsy();
323
336
  expect(screen.getByRole('textbox', { name: /Send a message.../i })).toBeTruthy();
324
337
  expect(screen.getByRole('textbox', { name: /Send a message.../i })).toHaveValue('test');
325
338
  });
@@ -37,10 +37,14 @@ export interface MessageBarProps extends TextAreaProps {
37
37
  className?: string;
38
38
  /** Flag to always to show the send button. By default send button is shown when there is a message in the input field */
39
39
  alwayShowSendButton?: boolean;
40
+ /** Placeholder for message input */
41
+ placeholder?: string;
40
42
  /** Flag to disable/enable the Attach button */
41
43
  hasAttachButton?: boolean;
42
44
  /** Flag to enable the Microphone button */
43
45
  hasMicrophoneButton?: boolean;
46
+ /** Placeholder text when listening */
47
+ listeningText?: string;
44
48
  /** Flag to enable the Stop button, used for streaming content */
45
49
  hasStopButton?: boolean;
46
50
  /** Callback function for when stop button is clicked */
@@ -72,14 +76,17 @@ export interface MessageBarProps extends TextAreaProps {
72
76
  onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>, value: string | number) => void;
73
77
  /** Display mode of chatbot, if you want to message bar to resize when the display mode changes */
74
78
  displayMode?: ChatbotDisplayMode;
79
+ isCompact?: boolean;
75
80
  }
76
81
 
77
82
  export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
78
83
  onSendMessage,
79
84
  className,
80
85
  alwayShowSendButton,
86
+ placeholder = 'Send a message...',
81
87
  hasAttachButton = true,
82
88
  hasMicrophoneButton,
89
+ listeningText = 'Listening',
83
90
  handleAttach,
84
91
  attachMenuProps,
85
92
  isSendButtonDisabled,
@@ -89,6 +96,7 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
89
96
  onChange,
90
97
  displayMode,
91
98
  value,
99
+ isCompact = false,
92
100
  ...props
93
101
  }: MessageBarProps) => {
94
102
  // Text Input
@@ -99,11 +107,13 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
99
107
  const textareaRef = React.useRef<HTMLTextAreaElement>(null);
100
108
  const attachButtonRef = React.useRef<HTMLButtonElement>(null);
101
109
 
110
+ const topMargin = '1rem';
111
+
102
112
  const setInitialLineHeight = (field: HTMLTextAreaElement) => {
103
113
  field.style.setProperty('line-height', '1rem');
104
114
  const parent = field.parentElement;
105
115
  if (parent) {
106
- parent.style.setProperty('margin-top', `1rem`);
116
+ parent.style.setProperty('margin-top', topMargin);
107
117
  parent.style.setProperty('margin-bottom', `0rem`);
108
118
  parent.style.setProperty('height', 'inherit');
109
119
 
@@ -129,8 +139,8 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
129
139
  parent.style.setProperty('height', `${height}px`);
130
140
 
131
141
  if (height > 32 || window.innerWidth <= 507) {
132
- parent.style.setProperty('margin-bottom', `1rem`);
133
- parent.style.setProperty('margin-top', `1rem`);
142
+ parent.style.setProperty('margin-bottom', topMargin);
143
+ parent.style.setProperty('margin-top', topMargin);
134
144
  }
135
145
  }
136
146
  };
@@ -154,8 +164,8 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
154
164
  const handleNewLine = (field: HTMLTextAreaElement) => {
155
165
  const parent = field.parentElement;
156
166
  if (parent) {
157
- parent.style.setProperty('margin-bottom', `1rem`);
158
- parent.style.setProperty('margin-top', `1rem`);
167
+ parent.style.setProperty('margin-bottom', topMargin);
168
+ parent.style.setProperty('margin-top', topMargin);
159
169
  }
160
170
  };
161
171
 
@@ -268,6 +278,7 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
268
278
  <StopButton
269
279
  onClick={handleStopButton}
270
280
  tooltipContent={buttonProps?.stop?.tooltipContent}
281
+ isCompact={isCompact}
271
282
  {...buttonProps?.stop?.props}
272
283
  />
273
284
  );
@@ -280,6 +291,7 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
280
291
  onClick={handleAttachMenuToggle}
281
292
  isDisabled={isListeningMessage}
282
293
  tooltipContent={buttonProps?.attach?.tooltipContent}
294
+ isCompact={isCompact}
283
295
  {...buttonProps?.attach?.props}
284
296
  />
285
297
  )}
@@ -289,6 +301,7 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
289
301
  isDisabled={isListeningMessage}
290
302
  tooltipContent={buttonProps?.attach?.tooltipContent}
291
303
  inputTestId={buttonProps?.attach?.inputTestId}
304
+ isCompact={isCompact}
292
305
  {...buttonProps?.attach?.props}
293
306
  />
294
307
  )}
@@ -299,6 +312,7 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
299
312
  onSpeechRecognition={handleSpeechRecognition}
300
313
  tooltipContent={buttonProps?.microphone?.tooltipContent}
301
314
  language={buttonProps?.microphone?.language}
315
+ isCompact={isCompact}
302
316
  {...buttonProps?.microphone?.props}
303
317
  />
304
318
  )}
@@ -308,6 +322,7 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
308
322
  onClick={() => handleSend(message)}
309
323
  isDisabled={isSendButtonDisabled}
310
324
  tooltipContent={buttonProps?.send?.tooltipContent}
325
+ isCompact={isCompact}
311
326
  {...buttonProps?.send?.props}
312
327
  />
313
328
  )}
@@ -317,13 +332,13 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
317
332
 
318
333
  const messageBarContents = (
319
334
  <>
320
- <div className="pf-chatbot__message-bar-input">
335
+ <div className={`pf-chatbot__message-bar-input ${isCompact ? 'pf-m-compact' : ''}`}>
321
336
  <TextArea
322
337
  className="pf-chatbot__message-textarea"
323
338
  value={message}
324
339
  onChange={handleChange}
325
- aria-label={isListeningMessage ? 'Listening' : 'Send a message...'}
326
- placeholder={isListeningMessage ? 'Listening' : 'Send a message...'}
340
+ aria-label={isListeningMessage ? listeningText : placeholder}
341
+ placeholder={isListeningMessage ? listeningText : placeholder}
327
342
  ref={textareaRef}
328
343
  onKeyDown={handleKeyDown}
329
344
  {...props}
@@ -46,3 +46,13 @@
46
46
  box-shadow: 0 0 0 16px rgba(0, 102, 204, 0);
47
47
  }
48
48
  }
49
+
50
+ // ============================================================================
51
+ // Information density styles
52
+ // ============================================================================
53
+ .pf-v6-c-button.pf-chatbot__button--microphone.pf-m-compact {
54
+ width: 1.5rem;
55
+ height: 1.5rem;
56
+ padding: var(--pf-t--global--spacer--sm);
57
+ align-items: center;
58
+ }
@@ -24,6 +24,7 @@ export interface MicrophoneButtonProps extends ButtonProps {
24
24
  tooltipContent?: { active?: string; inactive?: string };
25
25
  /** Locale code for language speech recognition is conducted in. This should be in the format 'en-US', a.k.a. the ISO 639-1 code, a dash, and the ISO_3166-1 code. */
26
26
  language?: string;
27
+ isCompact?: boolean;
27
28
  }
28
29
 
29
30
  export const MicrophoneButton: React.FunctionComponent<MicrophoneButtonProps> = ({
@@ -34,6 +35,7 @@ export const MicrophoneButton: React.FunctionComponent<MicrophoneButtonProps> =
34
35
  tooltipProps,
35
36
  tooltipContent = { active: 'Stop listening', inactive: 'Use microphone' },
36
37
  language = 'en-US',
38
+ isCompact,
37
39
  ...props
38
40
  }: MicrophoneButtonProps) => {
39
41
  // Microphone
@@ -102,14 +104,16 @@ export const MicrophoneButton: React.FunctionComponent<MicrophoneButtonProps> =
102
104
  >
103
105
  <Button
104
106
  variant="plain"
105
- className={`pf-chatbot__button--microphone ${isListening ? 'pf-chatbot__button--microphone--active' : ''} ${className ?? ''}`}
106
- aria-label={props['aria-label'] || 'Microphone button'}
107
+ className={`pf-chatbot__button--microphone ${isListening ? 'pf-chatbot__button--microphone--active' : ''} ${isCompact ? 'pf-m-compact' : ''} ${className ?? ''}`}
108
+ aria-label={props['aria-label'] || (isListening ? 'Stop listening' : 'Use microphone')}
109
+ aria-pressed={isListening}
107
110
  onClick={isListening ? stopListening : startListening}
108
111
  icon={
109
- <Icon iconSize="xl" isInline>
112
+ <Icon iconSize={isCompact ? 'lg' : 'xl'} isInline>
110
113
  <MicrophoneIcon />
111
114
  </Icon>
112
115
  }
116
+ size={isCompact ? 'sm' : undefined}
113
117
  {...props}
114
118
  />
115
119
  </Tooltip>
@@ -51,3 +51,13 @@
51
51
  transform: translate3d(0, 0, 0);
52
52
  }
53
53
  }
54
+
55
+ // ============================================================================
56
+ // Information density styles
57
+ // ============================================================================
58
+ .pf-v6-c-button.pf-chatbot__button--send.pf-m-compact {
59
+ width: 1.5rem;
60
+ height: 1.5rem;
61
+ padding: var(--pf-t--global--spacer--sm);
62
+ align-items: center;
63
+ }
@@ -5,30 +5,30 @@ import userEvent from '@testing-library/user-event';
5
5
  import { SendButton } from './SendButton';
6
6
  import { TooltipProps } from '@patternfly/react-core';
7
7
 
8
- const renderSend = (props?: { [key: string]: string | Omit<TooltipProps, 'content'> }) => {
8
+ const renderSend = (props?: { [key: string]: string | boolean | Omit<TooltipProps, 'content'> }) => {
9
9
  const spy = jest.fn();
10
10
  render(<SendButton onClick={spy} {...props} />);
11
11
  };
12
12
  describe('Send button', () => {
13
13
  it('should render button correctly', () => {
14
14
  renderSend();
15
- expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
15
+ expect(screen.getByRole('button', { name: 'Send' })).toBeTruthy();
16
16
  });
17
17
  it('should handle onClick correctly', async () => {
18
18
  const spy = jest.fn();
19
19
  render(<SendButton onClick={spy} />);
20
- await userEvent.click(screen.getByRole('button', { name: 'Send button' }));
20
+ await userEvent.click(screen.getByRole('button', { name: 'Send' }));
21
21
  expect(screen.getByRole('tooltip', { name: 'Send' })).toBeTruthy();
22
22
  expect(spy).toHaveBeenCalledTimes(1);
23
23
  });
24
24
  it('should handle custom tooltip correctly', async () => {
25
25
  render(<SendButton onClick={jest.fn} tooltipContent="Test" />);
26
- await userEvent.click(screen.getByRole('button', { name: 'Send button' }));
26
+ await userEvent.click(screen.getByRole('button', { name: 'Send' }));
27
27
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
28
28
  });
29
29
  it('should handle className prop', () => {
30
30
  renderSend({ className: 'test' });
31
- expect(screen.getByRole('button', { name: 'Send button' })).toHaveClass('test');
31
+ expect(screen.getByRole('button', { name: 'Send' })).toHaveClass('test');
32
32
  });
33
33
 
34
34
  it('should handle spread props, including aria-label', () => {
@@ -37,7 +37,11 @@ describe('Send button', () => {
37
37
  });
38
38
  it('should handle tooltipProps prop', async () => {
39
39
  renderSend({ tooltipProps: { id: 'test' } });
40
- await userEvent.click(screen.getByRole('button', { name: 'Send button' }));
40
+ await userEvent.click(screen.getByRole('button', { name: 'Send' }));
41
41
  expect(screen.getByRole('tooltip', { name: 'Send' })).toHaveAttribute('id', 'test');
42
42
  });
43
+ it('should handle isCompact', () => {
44
+ renderSend({ 'data-testid': 'button', isCompact: true });
45
+ expect(screen.getByTestId('button')).toHaveClass('pf-m-compact');
46
+ });
43
47
  });
@@ -17,6 +17,7 @@ export interface SendButtonProps extends ButtonProps {
17
17
  tooltipProps?: Omit<TooltipProps, 'content'>;
18
18
  /** English text "Send" used in the tooltip */
19
19
  tooltipContent?: string;
20
+ isCompact?: boolean;
20
21
  }
21
22
 
22
23
  export const SendButton: React.FunctionComponent<SendButtonProps> = ({
@@ -24,6 +25,7 @@ export const SendButton: React.FunctionComponent<SendButtonProps> = ({
24
25
  onClick,
25
26
  tooltipProps,
26
27
  tooltipContent = 'Send',
28
+ isCompact,
27
29
  ...props
28
30
  }: SendButtonProps) => (
29
31
  <Tooltip
@@ -40,14 +42,15 @@ export const SendButton: React.FunctionComponent<SendButtonProps> = ({
40
42
  >
41
43
  <Button
42
44
  variant="plain"
43
- className={`pf-chatbot__button--send ${className ?? ''}`}
44
- aria-label={props['aria-label'] || 'Send button'}
45
+ className={`pf-chatbot__button--send ${isCompact ? 'pf-m-compact' : ''} ${className ?? ''}`}
46
+ aria-label={props['aria-label'] || 'Send'}
45
47
  onClick={onClick}
46
48
  icon={
47
- <Icon iconSize="xl" isInline>
49
+ <Icon iconSize={isCompact ? 'lg' : 'xl'} isInline>
48
50
  <PaperPlaneIcon />
49
51
  </Icon>
50
52
  }
53
+ size={isCompact ? 'sm' : undefined}
51
54
  {...props}
52
55
  />
53
56
  </Tooltip>
@@ -34,3 +34,13 @@
34
34
  }
35
35
  }
36
36
  }
37
+
38
+ // ============================================================================
39
+ // Information density styles
40
+ // ============================================================================
41
+ .pf-v6-c-button.pf-chatbot__button--stop.pf-m-compact {
42
+ width: 1.5rem;
43
+ height: 1.5rem;
44
+ padding: var(--pf-t--global--spacer--sm);
45
+ align-items: center;
46
+ }
@@ -5,30 +5,30 @@ import userEvent from '@testing-library/user-event';
5
5
  import { StopButton } from './StopButton';
6
6
  import { TooltipProps } from '@patternfly/react-core';
7
7
 
8
- const renderStop = (props?: { [key: string]: string | Omit<TooltipProps, 'content'> }) => {
8
+ const renderStop = (props?: { [key: string]: string | boolean | Omit<TooltipProps, 'content'> }) => {
9
9
  const spy = jest.fn();
10
10
  render(<StopButton onClick={spy} {...props} />);
11
11
  };
12
12
  describe('Stop button', () => {
13
13
  it('should render button correctly', () => {
14
14
  renderStop();
15
- expect(screen.getByRole('button', { name: 'Stop button' })).toBeTruthy();
15
+ expect(screen.getByRole('button', { name: 'Stop' })).toBeTruthy();
16
16
  });
17
17
  it('should handle onClick correctly', async () => {
18
18
  const spy = jest.fn();
19
19
  render(<StopButton onClick={spy} />);
20
- await userEvent.click(screen.getByRole('button', { name: 'Stop button' }));
20
+ await userEvent.click(screen.getByRole('button', { name: 'Stop' }));
21
21
  expect(screen.getByRole('tooltip', { name: 'Stop' })).toBeTruthy();
22
22
  expect(spy).toHaveBeenCalledTimes(1);
23
23
  });
24
24
  it('should handle custom tooltip correctly', async () => {
25
25
  render(<StopButton onClick={jest.fn} tooltipContent="Test" />);
26
- await userEvent.click(screen.getByRole('button', { name: 'Stop button' }));
26
+ await userEvent.click(screen.getByRole('button', { name: 'Stop' }));
27
27
  expect(screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
28
28
  });
29
29
  it('should handle className prop', () => {
30
30
  renderStop({ className: 'test' });
31
- expect(screen.getByRole('button', { name: 'Stop button' })).toHaveClass('test');
31
+ expect(screen.getByRole('button', { name: 'Stop' })).toHaveClass('test');
32
32
  });
33
33
  it('should handle spread props, including aria-label', () => {
34
34
  renderStop({ 'aria-label': 'test' });
@@ -36,7 +36,11 @@ describe('Stop button', () => {
36
36
  });
37
37
  it('should handle tooltipProps prop', async () => {
38
38
  renderStop({ tooltipProps: { id: 'test' } });
39
- await userEvent.click(screen.getByRole('button', { name: 'Stop button' }));
39
+ await userEvent.click(screen.getByRole('button', { name: 'Stop' }));
40
40
  expect(screen.getByRole('tooltip', { name: 'Stop' })).toHaveAttribute('id', 'test');
41
41
  });
42
+ it('should handle isCompact', () => {
43
+ renderStop({ 'data-testid': 'button', isCompact: true });
44
+ expect(screen.getByTestId('button')).toHaveClass('pf-m-compact');
45
+ });
42
46
  });
@@ -15,6 +15,7 @@ export interface StopButtonProps extends ButtonProps {
15
15
  tooltipProps?: Omit<TooltipProps, 'content'>;
16
16
  /** English text "Stop" used in the tooltip */
17
17
  tooltipContent?: string;
18
+ isCompact?: boolean;
18
19
  }
19
20
 
20
21
  export const StopButton: React.FunctionComponent<StopButtonProps> = ({
@@ -22,6 +23,7 @@ export const StopButton: React.FunctionComponent<StopButtonProps> = ({
22
23
  onClick,
23
24
  tooltipProps,
24
25
  tooltipContent = 'Stop',
26
+ isCompact,
25
27
  ...props
26
28
  }: StopButtonProps) => (
27
29
  <Tooltip
@@ -37,12 +39,12 @@ export const StopButton: React.FunctionComponent<StopButtonProps> = ({
37
39
  {...tooltipProps}
38
40
  >
39
41
  <Button
40
- className={`pf-chatbot__button--stop ${className ?? ''}`}
42
+ className={`pf-chatbot__button--stop ${isCompact ? 'pf-m-compact' : ''} ${className ?? ''}`}
41
43
  variant="link"
42
- aria-label={props['aria-label'] || 'Stop button'}
44
+ aria-label={props['aria-label'] || 'Stop'}
43
45
  onClick={onClick}
44
46
  icon={
45
- <Icon iconSize="xl" isInline>
47
+ <Icon iconSize={isCompact ? 'lg' : 'xl'} isInline>
46
48
  <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
47
49
  <path
48
50
  d="M0.5 3C0.5 1.62109 1.62109 0.5 3 0.5H13C14.3789 0.5 15.5 1.62109 15.5 3V13C15.5 14.3789 14.3789 15.5 13 15.5H3C1.62109 15.5 0.5 14.3789 0.5 13V3Z"
@@ -51,6 +53,7 @@ export const StopButton: React.FunctionComponent<StopButtonProps> = ({
51
53
  </svg>
52
54
  </Icon>
53
55
  }
56
+ size={isCompact ? 'sm' : undefined}
54
57
  {...props}
55
58
  />
56
59
  </Tooltip>
@@ -7,20 +7,20 @@ import userEvent from '@testing-library/user-event';
7
7
  describe('JumpButton', () => {
8
8
  it('should render top button correctly', () => {
9
9
  render(<JumpButton position="top" onClick={jest.fn()} />);
10
- expect(screen.getByRole('button', { name: /Jump top button/i })).toBeTruthy();
10
+ expect(screen.getByRole('button', { name: /Jump top/i })).toBeTruthy();
11
11
  });
12
12
  it('should render bottom button correctly', () => {
13
13
  render(<JumpButton position="bottom" onClick={jest.fn()} />);
14
- expect(screen.getByRole('button', { name: /Jump bottom button/i })).toBeTruthy();
14
+ expect(screen.getByRole('button', { name: /Jump bottom/i })).toBeTruthy();
15
15
  });
16
16
  it('should call onClick appropriately', async () => {
17
17
  const spy = jest.fn();
18
18
  render(<JumpButton position="bottom" onClick={spy} />);
19
- await userEvent.click(screen.getByRole('button', { name: /Jump bottom button/i }));
19
+ await userEvent.click(screen.getByRole('button', { name: /Jump bottom/i }));
20
20
  expect(spy).toHaveBeenCalledTimes(1);
21
21
  });
22
22
  it('should be hidden if isHidden prop is used', async () => {
23
23
  render(<JumpButton position="bottom" onClick={jest.fn()} isHidden />);
24
- expect(screen.queryByRole('button', { name: /Jump bottom button/i })).toBeFalsy();
24
+ expect(screen.queryByRole('button', { name: /Jump bottom/i })).toBeFalsy();
25
25
  });
26
26
  });
@@ -24,7 +24,7 @@ const JumpButton: React.FunctionComponent<JumpButtonProps> = ({ position, isHidd
24
24
  <Button
25
25
  variant="plain"
26
26
  className={`pf-chatbot__jump pf-chatbot__jump--${position}`}
27
- aria-label={`Jump ${position} button`}
27
+ aria-label={`Jump ${position}`}
28
28
  onClick={onClick}
29
29
  >
30
30
  <Icon iconSize="lg" isInline>
@@ -45,3 +45,9 @@
45
45
  }
46
46
  }
47
47
  }
48
+
49
+ .pf-chatbot.pf-m-compact {
50
+ .pf-chatbot__messagebox {
51
+ padding: var(--pf-t--global--spacer--md);
52
+ }
53
+ }