@patternfly/chatbot 6.5.0-prerelease.3 → 6.5.0-prerelease.30

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 (351) hide show
  1. package/dist/cjs/AttachMenu/AttachMenu.d.ts +8 -2
  2. package/dist/cjs/AttachMenu/AttachMenu.js +2 -2
  3. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +9 -1
  4. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +9 -2
  5. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +38 -0
  6. package/dist/cjs/ChatbotFooter/ChatbotFooter.d.ts +5 -2
  7. package/dist/cjs/ChatbotFooter/ChatbotFooter.js +2 -2
  8. package/dist/cjs/ChatbotFooter/ChatbotFooter.test.js +5 -1
  9. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +29 -2
  10. package/dist/cjs/CodeModal/CodeModal.d.ts +2 -0
  11. package/dist/cjs/CodeModal/CodeModal.js +53 -8
  12. package/dist/cjs/DeepThinking/DeepThinking.d.ts +13 -0
  13. package/dist/cjs/DeepThinking/DeepThinking.js +31 -3
  14. package/dist/cjs/DeepThinking/DeepThinking.test.js +80 -0
  15. package/dist/cjs/FileDetailsLabel/FileDetailsLabel.d.ts +2 -1
  16. package/dist/cjs/MarkdownContent/MarkdownContent.d.ts +44 -0
  17. package/dist/cjs/MarkdownContent/MarkdownContent.js +181 -0
  18. package/dist/cjs/MarkdownContent/MarkdownContent.test.d.ts +1 -0
  19. package/dist/cjs/MarkdownContent/MarkdownContent.test.js +192 -0
  20. package/dist/cjs/MarkdownContent/index.d.ts +2 -0
  21. package/dist/cjs/MarkdownContent/index.js +23 -0
  22. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.d.ts +5 -1
  23. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +16 -5
  24. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.test.d.ts +1 -0
  25. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.test.js +131 -0
  26. package/dist/cjs/Message/ErrorMessage/ErrorMessage.d.ts +15 -1
  27. package/dist/cjs/Message/ErrorMessage/ErrorMessage.js +5 -3
  28. package/dist/cjs/Message/ErrorMessage/ErrorMessage.test.d.ts +1 -0
  29. package/dist/cjs/Message/ErrorMessage/ErrorMessage.test.js +30 -0
  30. package/dist/cjs/Message/LinkMessage/LinkMessage.d.ts +5 -1
  31. package/dist/cjs/Message/LinkMessage/LinkMessage.js +4 -3
  32. package/dist/cjs/Message/ListMessage/OrderedListMessage.d.ts +9 -1
  33. package/dist/cjs/Message/ListMessage/OrderedListMessage.js +2 -1
  34. package/dist/cjs/Message/ListMessage/UnorderedListMessage.d.ts +7 -1
  35. package/dist/cjs/Message/ListMessage/UnorderedListMessage.js +2 -1
  36. package/dist/cjs/Message/Message.d.ts +22 -3
  37. package/dist/cjs/Message/Message.js +8 -161
  38. package/dist/cjs/Message/Message.test.js +161 -2
  39. package/dist/cjs/Message/MessageAndActions/MessageAndActions.d.ts +14 -0
  40. package/dist/cjs/Message/MessageAndActions/MessageAndActions.js +22 -0
  41. package/dist/cjs/Message/MessageAndActions/MessageAndActions.test.d.ts +1 -0
  42. package/dist/cjs/Message/MessageAndActions/MessageAndActions.test.js +25 -0
  43. package/dist/cjs/Message/MessageAndActions/index.d.ts +1 -0
  44. package/dist/cjs/Message/MessageAndActions/index.js +17 -0
  45. package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.d.ts +13 -0
  46. package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.js +22 -0
  47. package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.test.d.ts +1 -0
  48. package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.test.js +25 -0
  49. package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.d.ts +13 -0
  50. package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.js +22 -0
  51. package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.test.d.ts +1 -0
  52. package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.test.js +25 -0
  53. package/dist/cjs/Message/MessageAttachments/index.d.ts +2 -0
  54. package/dist/cjs/Message/MessageAttachments/index.js +18 -0
  55. package/dist/cjs/Message/MessageInput.d.ts +1 -1
  56. package/dist/cjs/Message/MessageInput.js +3 -1
  57. package/dist/cjs/Message/MessageLoading.d.ts +13 -3
  58. package/dist/cjs/Message/MessageLoading.js +19 -5
  59. package/dist/cjs/Message/MessageLoading.test.d.ts +1 -0
  60. package/dist/cjs/Message/MessageLoading.test.js +25 -0
  61. package/dist/cjs/Message/QuickResponse/QuickResponse.js +3 -2
  62. package/dist/cjs/Message/QuickResponse/QuickResponse.test.d.ts +1 -0
  63. package/dist/cjs/Message/QuickResponse/QuickResponse.test.js +109 -0
  64. package/dist/cjs/Message/QuickResponse/index.d.ts +1 -0
  65. package/dist/cjs/Message/QuickResponse/index.js +17 -0
  66. package/dist/cjs/Message/QuickStarts/QuickStartTile.d.ts +1 -1
  67. package/dist/cjs/Message/QuickStarts/QuickStartTile.js +3 -2
  68. package/dist/cjs/Message/QuickStarts/index.d.ts +2 -0
  69. package/dist/cjs/Message/QuickStarts/index.js +18 -0
  70. package/dist/cjs/Message/TableMessage/TableMessage.d.ts +9 -1
  71. package/dist/cjs/Message/TableMessage/TableMessage.js +3 -2
  72. package/dist/cjs/Message/TextMessage/TextMessage.d.ts +11 -1
  73. package/dist/cjs/Message/TextMessage/TextMessage.js +3 -2
  74. package/dist/cjs/Message/UserFeedback/UserFeedback.d.ts +3 -1
  75. package/dist/cjs/Message/UserFeedback/UserFeedback.js +8 -6
  76. package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.d.ts +1 -1
  77. package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.js +3 -2
  78. package/dist/cjs/Message/UserFeedback/index.d.ts +2 -0
  79. package/dist/cjs/Message/UserFeedback/index.js +18 -0
  80. package/dist/cjs/Message/index.d.ts +8 -0
  81. package/dist/cjs/Message/index.js +8 -0
  82. package/dist/cjs/MessageBar/AttachButton.d.ts +2 -0
  83. package/dist/cjs/MessageBar/AttachButton.js +2 -2
  84. package/dist/cjs/MessageBar/AttachButton.test.js +4 -0
  85. package/dist/cjs/MessageBar/MessageBar.d.ts +22 -6
  86. package/dist/cjs/MessageBar/MessageBar.js +43 -11
  87. package/dist/cjs/MessageBar/MessageBar.test.js +74 -0
  88. package/dist/cjs/Onboarding/Onboarding.d.ts +36 -0
  89. package/dist/cjs/Onboarding/Onboarding.js +37 -0
  90. package/dist/cjs/Onboarding/Onboarding.test.d.ts +1 -0
  91. package/dist/cjs/Onboarding/Onboarding.test.js +80 -0
  92. package/dist/cjs/Onboarding/index.d.ts +2 -0
  93. package/dist/cjs/Onboarding/index.js +23 -0
  94. package/dist/cjs/ResponseActions/ResponseActions.d.ts +7 -0
  95. package/dist/cjs/ResponseActions/ResponseActions.js +28 -7
  96. package/dist/cjs/ResponseActions/ResponseActions.test.js +67 -12
  97. package/dist/cjs/ResponseActions/ResponseActionsGroups.d.ts +13 -0
  98. package/dist/cjs/ResponseActions/ResponseActionsGroups.js +22 -0
  99. package/dist/cjs/ResponseActions/ResponseActionsGroups.test.d.ts +1 -0
  100. package/dist/cjs/ResponseActions/ResponseActionsGroups.test.js +25 -0
  101. package/dist/cjs/ResponseActions/index.d.ts +1 -0
  102. package/dist/cjs/ResponseActions/index.js +1 -0
  103. package/dist/cjs/ToolCall/ToolCall.d.ts +11 -0
  104. package/dist/cjs/ToolCall/ToolCall.js +24 -3
  105. package/dist/cjs/ToolCall/ToolCall.test.js +57 -0
  106. package/dist/cjs/ToolResponse/ToolResponse.d.ts +17 -0
  107. package/dist/cjs/ToolResponse/ToolResponse.js +49 -3
  108. package/dist/cjs/ToolResponse/ToolResponse.test.js +100 -0
  109. package/dist/cjs/__mocks__/monaco-editor.d.ts +11 -0
  110. package/dist/cjs/__mocks__/monaco-editor.js +18 -0
  111. package/dist/cjs/index.d.ts +4 -0
  112. package/dist/cjs/index.js +7 -1
  113. package/dist/css/main.css +336 -30
  114. package/dist/css/main.css.map +1 -1
  115. package/dist/dynamic/MarkdownContent/package.json +1 -0
  116. package/dist/dynamic/Onboarding/package.json +1 -0
  117. package/dist/esm/AttachMenu/AttachMenu.d.ts +8 -2
  118. package/dist/esm/AttachMenu/AttachMenu.js +2 -2
  119. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +9 -1
  120. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +10 -3
  121. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +38 -0
  122. package/dist/esm/ChatbotFooter/ChatbotFooter.d.ts +5 -2
  123. package/dist/esm/ChatbotFooter/ChatbotFooter.js +2 -2
  124. package/dist/esm/ChatbotFooter/ChatbotFooter.test.js +5 -1
  125. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +30 -3
  126. package/dist/esm/CodeModal/CodeModal.d.ts +2 -0
  127. package/dist/esm/CodeModal/CodeModal.js +54 -9
  128. package/dist/esm/DeepThinking/DeepThinking.d.ts +13 -0
  129. package/dist/esm/DeepThinking/DeepThinking.js +28 -3
  130. package/dist/esm/DeepThinking/DeepThinking.test.js +80 -0
  131. package/dist/esm/FileDetailsLabel/FileDetailsLabel.d.ts +2 -1
  132. package/dist/esm/MarkdownContent/MarkdownContent.d.ts +44 -0
  133. package/dist/esm/MarkdownContent/MarkdownContent.js +174 -0
  134. package/dist/esm/MarkdownContent/MarkdownContent.test.d.ts +1 -0
  135. package/dist/esm/MarkdownContent/MarkdownContent.test.js +187 -0
  136. package/dist/esm/MarkdownContent/index.d.ts +2 -0
  137. package/dist/esm/MarkdownContent/index.js +2 -0
  138. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.d.ts +5 -1
  139. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +16 -5
  140. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.test.d.ts +1 -0
  141. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.test.js +126 -0
  142. package/dist/esm/Message/ErrorMessage/ErrorMessage.d.ts +15 -1
  143. package/dist/esm/Message/ErrorMessage/ErrorMessage.js +3 -3
  144. package/dist/esm/Message/ErrorMessage/ErrorMessage.test.d.ts +1 -0
  145. package/dist/esm/Message/ErrorMessage/ErrorMessage.test.js +25 -0
  146. package/dist/esm/Message/LinkMessage/LinkMessage.d.ts +5 -1
  147. package/dist/esm/Message/LinkMessage/LinkMessage.js +4 -3
  148. package/dist/esm/Message/ListMessage/OrderedListMessage.d.ts +9 -1
  149. package/dist/esm/Message/ListMessage/OrderedListMessage.js +2 -1
  150. package/dist/esm/Message/ListMessage/UnorderedListMessage.d.ts +7 -1
  151. package/dist/esm/Message/ListMessage/UnorderedListMessage.js +2 -1
  152. package/dist/esm/Message/Message.d.ts +22 -3
  153. package/dist/esm/Message/Message.js +9 -162
  154. package/dist/esm/Message/Message.test.js +161 -2
  155. package/dist/esm/Message/MessageAndActions/MessageAndActions.d.ts +14 -0
  156. package/dist/esm/Message/MessageAndActions/MessageAndActions.js +18 -0
  157. package/dist/esm/Message/MessageAndActions/MessageAndActions.test.d.ts +1 -0
  158. package/dist/esm/Message/MessageAndActions/MessageAndActions.test.js +20 -0
  159. package/dist/esm/Message/MessageAndActions/index.d.ts +1 -0
  160. package/dist/esm/Message/MessageAndActions/index.js +1 -0
  161. package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.d.ts +13 -0
  162. package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.js +18 -0
  163. package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.test.d.ts +1 -0
  164. package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.test.js +20 -0
  165. package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.d.ts +13 -0
  166. package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.js +18 -0
  167. package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.test.d.ts +1 -0
  168. package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.test.js +20 -0
  169. package/dist/esm/Message/MessageAttachments/index.d.ts +2 -0
  170. package/dist/esm/Message/MessageAttachments/index.js +2 -0
  171. package/dist/esm/Message/MessageInput.d.ts +1 -1
  172. package/dist/esm/Message/MessageInput.js +1 -1
  173. package/dist/esm/Message/MessageLoading.d.ts +13 -3
  174. package/dist/esm/Message/MessageLoading.js +16 -4
  175. package/dist/esm/Message/MessageLoading.test.d.ts +1 -0
  176. package/dist/esm/Message/MessageLoading.test.js +20 -0
  177. package/dist/esm/Message/QuickResponse/QuickResponse.js +3 -2
  178. package/dist/esm/Message/QuickResponse/QuickResponse.test.d.ts +1 -0
  179. package/dist/esm/Message/QuickResponse/QuickResponse.test.js +104 -0
  180. package/dist/esm/Message/QuickResponse/index.d.ts +1 -0
  181. package/dist/esm/Message/QuickResponse/index.js +1 -0
  182. package/dist/esm/Message/QuickStarts/QuickStartTile.d.ts +1 -1
  183. package/dist/esm/Message/QuickStarts/QuickStartTile.js +1 -1
  184. package/dist/esm/Message/QuickStarts/index.d.ts +2 -0
  185. package/dist/esm/Message/QuickStarts/index.js +2 -0
  186. package/dist/esm/Message/TableMessage/TableMessage.d.ts +9 -1
  187. package/dist/esm/Message/TableMessage/TableMessage.js +3 -2
  188. package/dist/esm/Message/TextMessage/TextMessage.d.ts +11 -1
  189. package/dist/esm/Message/TextMessage/TextMessage.js +3 -2
  190. package/dist/esm/Message/UserFeedback/UserFeedback.d.ts +3 -1
  191. package/dist/esm/Message/UserFeedback/UserFeedback.js +7 -7
  192. package/dist/esm/Message/UserFeedback/UserFeedbackComplete.d.ts +1 -1
  193. package/dist/esm/Message/UserFeedback/UserFeedbackComplete.js +1 -2
  194. package/dist/esm/Message/UserFeedback/index.d.ts +2 -0
  195. package/dist/esm/Message/UserFeedback/index.js +2 -0
  196. package/dist/esm/Message/index.d.ts +8 -0
  197. package/dist/esm/Message/index.js +8 -0
  198. package/dist/esm/MessageBar/AttachButton.d.ts +2 -0
  199. package/dist/esm/MessageBar/AttachButton.js +2 -2
  200. package/dist/esm/MessageBar/AttachButton.test.js +4 -0
  201. package/dist/esm/MessageBar/MessageBar.d.ts +22 -6
  202. package/dist/esm/MessageBar/MessageBar.js +43 -11
  203. package/dist/esm/MessageBar/MessageBar.test.js +74 -0
  204. package/dist/esm/Onboarding/Onboarding.d.ts +36 -0
  205. package/dist/esm/Onboarding/Onboarding.js +30 -0
  206. package/dist/esm/Onboarding/Onboarding.test.d.ts +1 -0
  207. package/dist/esm/Onboarding/Onboarding.test.js +75 -0
  208. package/dist/esm/Onboarding/index.d.ts +2 -0
  209. package/dist/esm/Onboarding/index.js +2 -0
  210. package/dist/esm/ResponseActions/ResponseActions.d.ts +7 -0
  211. package/dist/esm/ResponseActions/ResponseActions.js +28 -7
  212. package/dist/esm/ResponseActions/ResponseActions.test.js +67 -12
  213. package/dist/esm/ResponseActions/ResponseActionsGroups.d.ts +13 -0
  214. package/dist/esm/ResponseActions/ResponseActionsGroups.js +18 -0
  215. package/dist/esm/ResponseActions/ResponseActionsGroups.test.d.ts +1 -0
  216. package/dist/esm/ResponseActions/ResponseActionsGroups.test.js +20 -0
  217. package/dist/esm/ResponseActions/index.d.ts +1 -0
  218. package/dist/esm/ResponseActions/index.js +1 -0
  219. package/dist/esm/ToolCall/ToolCall.d.ts +11 -0
  220. package/dist/esm/ToolCall/ToolCall.js +21 -3
  221. package/dist/esm/ToolCall/ToolCall.test.js +57 -0
  222. package/dist/esm/ToolResponse/ToolResponse.d.ts +17 -0
  223. package/dist/esm/ToolResponse/ToolResponse.js +46 -3
  224. package/dist/esm/ToolResponse/ToolResponse.test.js +100 -0
  225. package/dist/esm/__mocks__/monaco-editor.d.ts +11 -0
  226. package/dist/esm/__mocks__/monaco-editor.js +18 -0
  227. package/dist/esm/index.d.ts +4 -0
  228. package/dist/esm/index.js +4 -0
  229. package/dist/tsconfig.tsbuildinfo +1 -1
  230. package/package.json +13 -2
  231. package/patternfly-docs/content/extensions/chatbot/chatbot.md +57 -0
  232. package/patternfly-docs/content/extensions/chatbot/design-guidelines.md +12 -12
  233. package/patternfly-docs/content/extensions/chatbot/examples/Analytics/Analytics.md +1 -1
  234. package/patternfly-docs/content/extensions/chatbot/examples/Customizing Messages/Customizing Messages.md +1 -1
  235. package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +1 -0
  236. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithCustomStructure.tsx +102 -0
  237. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithDeepThinking.tsx +25 -11
  238. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithFeedback.tsx +14 -1
  239. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMarkdownDeepThinking.tsx +26 -0
  240. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMarkdownToolCall.tsx +29 -0
  241. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMarkdownToolResponse.tsx +200 -0
  242. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMultipleActionGroups.tsx +61 -0
  243. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithPersistedActions.tsx +22 -0
  244. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickResponses.tsx +11 -0
  245. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithToolCall.tsx +14 -1
  246. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithToolResponse.tsx +222 -105
  247. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +123 -14
  248. package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +1 -0
  249. package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessageWithExtraContent.tsx +3 -1
  250. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithSearchActions.tsx +198 -0
  251. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarCustomActions.tsx +190 -0
  252. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarIndicatorThinking.tsx +15 -0
  253. package/patternfly-docs/content/extensions/chatbot/examples/UI/CompactOnboarding.tsx +141 -0
  254. package/patternfly-docs/content/extensions/chatbot/examples/UI/Onboarding.tsx +151 -0
  255. package/patternfly-docs/content/extensions/chatbot/examples/UI/RH-Hat-Image.svg +9 -0
  256. package/patternfly-docs/content/extensions/chatbot/examples/UI/Settings.tsx +1 -1
  257. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +81 -30
  258. package/patternfly-docs/content/extensions/chatbot/examples/demos/AttachmentDemos.md +18 -18
  259. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +44 -22
  260. package/patternfly-docs/content/extensions/chatbot/examples/demos/WhiteEmbeddedChatbot.tsx +451 -0
  261. package/patternfly-docs/patternfly-docs.config.js +1 -1
  262. package/patternfly-docs/patternfly-docs.source.js +1 -1
  263. package/src/AttachMenu/AttachMenu.tsx +26 -11
  264. package/src/Chatbot/Chatbot.scss +23 -1
  265. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +43 -0
  266. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +95 -0
  267. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +51 -15
  268. package/src/ChatbotFooter/ChatbotFooter.scss +21 -0
  269. package/src/ChatbotFooter/ChatbotFooter.test.tsx +10 -1
  270. package/src/ChatbotFooter/ChatbotFooter.tsx +10 -3
  271. package/src/ChatbotHeader/ChatbotHeader.scss +19 -0
  272. package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +56 -14
  273. package/src/ChatbotModal/ChatbotModal.scss +3 -0
  274. package/src/CodeModal/CodeModal.tsx +72 -23
  275. package/src/DeepThinking/DeepThinking.scss +1 -1
  276. package/src/DeepThinking/DeepThinking.test.tsx +109 -0
  277. package/src/DeepThinking/DeepThinking.tsx +54 -5
  278. package/src/FileDetailsLabel/FileDetailsLabel.tsx +2 -2
  279. package/src/MarkdownContent/MarkdownContent.test.tsx +207 -0
  280. package/src/MarkdownContent/MarkdownContent.tsx +269 -0
  281. package/src/MarkdownContent/index.ts +2 -0
  282. package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +17 -0
  283. package/src/Message/CodeBlockMessage/CodeBlockMessage.test.tsx +171 -0
  284. package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +21 -5
  285. package/src/Message/ErrorMessage/ErrorMessage.test.tsx +38 -0
  286. package/src/Message/ErrorMessage/ErrorMessage.tsx +17 -2
  287. package/src/Message/LinkMessage/LinkMessage.scss +5 -0
  288. package/src/Message/LinkMessage/LinkMessage.tsx +24 -2
  289. package/src/Message/ListMessage/ListMessage.scss +8 -0
  290. package/src/Message/ListMessage/OrderedListMessage.tsx +16 -2
  291. package/src/Message/ListMessage/UnorderedListMessage.tsx +12 -2
  292. package/src/Message/Message.scss +11 -7
  293. package/src/Message/Message.test.tsx +239 -2
  294. package/src/Message/Message.tsx +133 -241
  295. package/src/Message/MessageAndActions/MessageAndActions.test.tsx +23 -0
  296. package/src/Message/MessageAndActions/MessageAndActions.tsx +22 -0
  297. package/src/Message/MessageAndActions/index.ts +1 -0
  298. package/src/Message/MessageAttachments/MessageAttachmentItem.test.tsx +23 -0
  299. package/src/Message/MessageAttachments/MessageAttachmentItem.tsx +25 -0
  300. package/src/Message/MessageAttachments/MessageAttachmentsContainer.test.tsx +23 -0
  301. package/src/Message/MessageAttachments/MessageAttachmentsContainer.tsx +25 -0
  302. package/src/Message/MessageAttachments/index.ts +2 -0
  303. package/src/Message/MessageInput.tsx +1 -1
  304. package/src/Message/MessageLoading.scss +7 -0
  305. package/src/Message/MessageLoading.test.tsx +23 -0
  306. package/src/Message/MessageLoading.tsx +17 -2
  307. package/src/Message/QuickResponse/QuickResponse.scss +3 -1
  308. package/src/Message/QuickResponse/QuickResponse.test.tsx +131 -0
  309. package/src/Message/QuickResponse/QuickResponse.tsx +3 -2
  310. package/src/Message/QuickResponse/index.ts +1 -0
  311. package/src/Message/QuickStarts/QuickStartTile.tsx +1 -1
  312. package/src/Message/QuickStarts/index.ts +2 -0
  313. package/src/Message/TableMessage/TableMessage.scss +17 -1
  314. package/src/Message/TableMessage/TableMessage.tsx +22 -2
  315. package/src/Message/TextMessage/TextMessage.scss +18 -0
  316. package/src/Message/TextMessage/TextMessage.tsx +39 -3
  317. package/src/Message/UserFeedback/UserFeedback.scss +30 -2
  318. package/src/Message/UserFeedback/UserFeedback.tsx +23 -13
  319. package/src/Message/UserFeedback/UserFeedbackComplete.tsx +1 -4
  320. package/src/Message/UserFeedback/index.ts +2 -0
  321. package/src/Message/index.ts +8 -0
  322. package/src/MessageBar/AttachButton.scss +0 -1
  323. package/src/MessageBar/AttachButton.test.tsx +4 -0
  324. package/src/MessageBar/AttachButton.tsx +4 -1
  325. package/src/MessageBar/MessageBar.scss +66 -6
  326. package/src/MessageBar/MessageBar.test.tsx +129 -1
  327. package/src/MessageBar/MessageBar.tsx +150 -56
  328. package/src/MessageBar/MicrophoneButton.scss +0 -1
  329. package/src/MessageBar/SendButton.scss +0 -1
  330. package/src/MessageBar/StopButton.scss +0 -1
  331. package/src/Onboarding/Onboarding.scss +101 -0
  332. package/src/Onboarding/Onboarding.test.tsx +148 -0
  333. package/src/Onboarding/Onboarding.tsx +126 -0
  334. package/src/Onboarding/index.ts +3 -0
  335. package/src/ResponseActions/ResponseActions.scss +12 -1
  336. package/src/ResponseActions/ResponseActions.test.tsx +111 -12
  337. package/src/ResponseActions/ResponseActions.tsx +44 -10
  338. package/src/ResponseActions/ResponseActionsGroups.test.tsx +23 -0
  339. package/src/ResponseActions/ResponseActionsGroups.tsx +28 -0
  340. package/src/ResponseActions/index.ts +1 -0
  341. package/src/ToolCall/ToolCall.scss +1 -1
  342. package/src/ToolCall/ToolCall.test.tsx +91 -0
  343. package/src/ToolCall/ToolCall.tsx +49 -4
  344. package/src/ToolResponse/ToolResponse.scss +13 -3
  345. package/src/ToolResponse/ToolResponse.test.tsx +119 -0
  346. package/src/ToolResponse/ToolResponse.tsx +82 -7
  347. package/src/__mocks__/monaco-editor.ts +19 -0
  348. package/src/index.ts +6 -0
  349. package/src/main.scss +2 -0
  350. package/tsconfig.json +1 -1
  351. package/patternfly-docs/content/extensions/chatbot/about-chatbot.md +0 -44
@@ -1,5 +1,6 @@
1
1
  import { PropsWithChildren } from 'react';
2
- export interface FileDetailsLabelProps {
2
+ import { LabelProps } from '@patternfly/react-core';
3
+ export interface FileDetailsLabelProps extends Omit<LabelProps, 'onClose' | 'onClick'> {
3
4
  /** Name of file, including extension */
4
5
  fileName: string;
5
6
  /** Unique id of file */
@@ -0,0 +1,44 @@
1
+ import { type FunctionComponent, ReactNode } from 'react';
2
+ import { Options } from 'react-markdown';
3
+ import { CodeBlockMessageProps } from '../Message/CodeBlockMessage/CodeBlockMessage';
4
+ import { TableProps } from '@patternfly/react-table';
5
+ import 'highlight.js/styles/vs2015.css';
6
+ import { PluggableList } from 'unified';
7
+ import { ButtonProps } from '@patternfly/react-core';
8
+ /**
9
+ * MarkdownContent renders content either as plain text or with content with markdown support.
10
+ *
11
+ * Use this component when passing children to Message to customize its structure.
12
+ */
13
+ export interface MarkdownContentProps {
14
+ /** The content to render. Supports markdown formatting by default, or plain text when isMarkdownDisabled is true. */
15
+ content?: string;
16
+ /** Disables markdown parsing, allowing only plain text input */
17
+ isMarkdownDisabled?: boolean;
18
+ /** Props for code blocks */
19
+ codeBlockProps?: CodeBlockMessageProps;
20
+ /** Props for table message. It is important to include a detailed aria-label that describes the purpose of the table. */
21
+ tableProps?: Required<Pick<TableProps, 'aria-label'>> & TableProps;
22
+ /** Additional rehype plugins passed from the consumer */
23
+ additionalRehypePlugins?: PluggableList;
24
+ /** Additional remark plugins passed from the consumer */
25
+ additionalRemarkPlugins?: PluggableList;
26
+ /** Whether to open links in message in new tab. */
27
+ openLinkInNewTab?: boolean;
28
+ /** Props for links */
29
+ linkProps?: ButtonProps;
30
+ /** Allows passing additional props down to markdown parser react-markdown, such as allowedElements and disallowedElements. See https://github.com/remarkjs/react-markdown?tab=readme-ov-file#options for options */
31
+ reactMarkdownProps?: Options;
32
+ /** Allows passing additional props down to remark-gfm. See https://github.com/remarkjs/remark-gfm?tab=readme-ov-file#options for options */
33
+ remarkGfmProps?: Options;
34
+ /** Whether to strip out images in markdown */
35
+ hasNoImages?: boolean;
36
+ /** Sets background colors to be appropriate on primary chatbot background */
37
+ isPrimary?: boolean;
38
+ /** Custom component to render when markdown is disabled */
39
+ textComponent?: ReactNode;
40
+ /** Flag indicating whether content should retain various styles of its context (typically font-size and text color). */
41
+ shouldRetainStyles?: boolean;
42
+ }
43
+ export declare const MarkdownContent: FunctionComponent<MarkdownContentProps>;
44
+ export default MarkdownContent;
@@ -0,0 +1,174 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
13
+ import Markdown from 'react-markdown';
14
+ import remarkGfm from 'remark-gfm';
15
+ import { ContentVariants } from '@patternfly/react-core';
16
+ import CodeBlockMessage from '../Message/CodeBlockMessage/CodeBlockMessage';
17
+ import TextMessage from '../Message/TextMessage/TextMessage';
18
+ import ListItemMessage from '../Message/ListMessage/ListItemMessage';
19
+ import UnorderedListMessage from '../Message/ListMessage/UnorderedListMessage';
20
+ import OrderedListMessage from '../Message/ListMessage/OrderedListMessage';
21
+ import TableMessage from '../Message/TableMessage/TableMessage';
22
+ import TrMessage from '../Message/TableMessage/TrMessage';
23
+ import TdMessage from '../Message/TableMessage/TdMessage';
24
+ import TbodyMessage from '../Message/TableMessage/TbodyMessage';
25
+ import TheadMessage from '../Message/TableMessage/TheadMessage';
26
+ import ThMessage from '../Message/TableMessage/ThMessage';
27
+ import ImageMessage from '../Message/ImageMessage/ImageMessage';
28
+ import rehypeUnwrapImages from 'rehype-unwrap-images';
29
+ import rehypeExternalLinks from 'rehype-external-links';
30
+ import rehypeSanitize from 'rehype-sanitize';
31
+ import rehypeHighlight from 'rehype-highlight';
32
+ import 'highlight.js/styles/vs2015.css';
33
+ import LinkMessage from '../Message/LinkMessage/LinkMessage';
34
+ import { rehypeMoveImagesOutOfParagraphs } from '../Message/Plugins/rehypeMoveImagesOutOfParagraphs';
35
+ import SuperscriptMessage from '../Message/SuperscriptMessage/SuperscriptMessage';
36
+ import { css } from '@patternfly/react-styles';
37
+ export const MarkdownContent = ({ content, isMarkdownDisabled, codeBlockProps, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], additionalRemarkPlugins = [], linkProps, reactMarkdownProps, remarkGfmProps, hasNoImages = false, isPrimary, textComponent, shouldRetainStyles }) => {
38
+ let rehypePlugins = [rehypeUnwrapImages, rehypeMoveImagesOutOfParagraphs, rehypeHighlight];
39
+ if (openLinkInNewTab) {
40
+ rehypePlugins = rehypePlugins.concat([[rehypeExternalLinks, { target: '_blank' }, rehypeSanitize]]);
41
+ }
42
+ if (additionalRehypePlugins) {
43
+ rehypePlugins.push(...additionalRehypePlugins);
44
+ }
45
+ const disallowedElements = hasNoImages ? ['img'] : [];
46
+ if (reactMarkdownProps && reactMarkdownProps.disallowedElements) {
47
+ disallowedElements.push(...reactMarkdownProps.disallowedElements);
48
+ }
49
+ if (isMarkdownDisabled) {
50
+ if (textComponent) {
51
+ return _jsx(_Fragment, { children: textComponent });
52
+ }
53
+ return (_jsx(TextMessage, { component: ContentVariants.p, isPrimary: isPrimary, children: content }));
54
+ }
55
+ return (_jsx(Markdown, Object.assign({ components: {
56
+ section: (props) => {
57
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
58
+ const { node } = props, rest = __rest(props, ["node"]);
59
+ return (_jsx("section", Object.assign({}, rest, { className: css('pf-chatbot__message-text', shouldRetainStyles && 'pf-m-markdown', rest === null || rest === void 0 ? void 0 : rest.className) })));
60
+ },
61
+ p: (props) => {
62
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
63
+ const { node } = props, rest = __rest(props, ["node"]);
64
+ return (_jsx(TextMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: ContentVariants.p }, rest, { isPrimary: isPrimary })));
65
+ },
66
+ code: (_a) => {
67
+ var { children } = _a, props = __rest(_a, ["children"]);
68
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
69
+ const { node } = props, codeProps = __rest(props, ["node"]);
70
+ return (_jsx(CodeBlockMessage, Object.assign({}, codeProps, codeBlockProps, { isPrimary: isPrimary, shouldRetainStyles: shouldRetainStyles, children: children })));
71
+ },
72
+ h1: (props) => {
73
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
74
+ const { node } = props, rest = __rest(props, ["node"]);
75
+ return _jsx(TextMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: ContentVariants.h1 }, rest));
76
+ },
77
+ h2: (props) => {
78
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
79
+ const { node } = props, rest = __rest(props, ["node"]);
80
+ return _jsx(TextMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: ContentVariants.h2 }, rest));
81
+ },
82
+ h3: (props) => {
83
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
84
+ const { node } = props, rest = __rest(props, ["node"]);
85
+ return _jsx(TextMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: ContentVariants.h3 }, rest));
86
+ },
87
+ h4: (props) => {
88
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
89
+ const { node } = props, rest = __rest(props, ["node"]);
90
+ return _jsx(TextMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: ContentVariants.h4 }, rest));
91
+ },
92
+ h5: (props) => {
93
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
94
+ const { node } = props, rest = __rest(props, ["node"]);
95
+ return _jsx(TextMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: ContentVariants.h5 }, rest));
96
+ },
97
+ h6: (props) => {
98
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
99
+ const { node } = props, rest = __rest(props, ["node"]);
100
+ return _jsx(TextMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: ContentVariants.h6 }, rest));
101
+ },
102
+ blockquote: (props) => {
103
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
104
+ const { node } = props, rest = __rest(props, ["node"]);
105
+ return (_jsx(TextMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: ContentVariants.blockquote }, rest)));
106
+ },
107
+ ul: (props) => {
108
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
109
+ const { node } = props, rest = __rest(props, ["node"]);
110
+ return _jsx(UnorderedListMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles }, rest));
111
+ },
112
+ ol: (props) => {
113
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
114
+ const { node } = props, rest = __rest(props, ["node"]);
115
+ return _jsx(OrderedListMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles }, rest));
116
+ },
117
+ li: (props) => {
118
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
119
+ const { node } = props, rest = __rest(props, ["node"]);
120
+ return _jsx(ListItemMessage, Object.assign({}, rest));
121
+ },
122
+ // table requires node attribute for calculating headers for mobile breakpoint
123
+ table: (props) => (_jsx(TableMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles }, props, tableProps, { isPrimary: isPrimary }))),
124
+ tbody: (props) => {
125
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
126
+ const { node } = props, rest = __rest(props, ["node"]);
127
+ return _jsx(TbodyMessage, Object.assign({}, rest));
128
+ },
129
+ thead: (props) => {
130
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
131
+ const { node } = props, rest = __rest(props, ["node"]);
132
+ return _jsx(TheadMessage, Object.assign({}, rest));
133
+ },
134
+ tr: (props) => {
135
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
136
+ const { node } = props, rest = __rest(props, ["node"]);
137
+ return _jsx(TrMessage, Object.assign({}, rest));
138
+ },
139
+ td: (props) => {
140
+ // Conflicts with Td type
141
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
142
+ const { node, width } = props, rest = __rest(props, ["node", "width"]);
143
+ return _jsx(TdMessage, Object.assign({}, rest));
144
+ },
145
+ th: (props) => {
146
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
147
+ const { node } = props, rest = __rest(props, ["node"]);
148
+ return _jsx(ThMessage, Object.assign({}, rest));
149
+ },
150
+ img: (props) => {
151
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
152
+ const { node } = props, rest = __rest(props, ["node"]);
153
+ return _jsx(ImageMessage, Object.assign({}, rest));
154
+ },
155
+ a: (props) => {
156
+ // node is just the details of the document structure - not needed
157
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
158
+ const { node } = props, rest = __rest(props, ["node"]);
159
+ return (
160
+ // some a types conflict with ButtonProps, but it's ok because we are using an a tag
161
+ // there are too many to handle manually
162
+ _jsx(LinkMessage, Object.assign({ shouldRetainStyles: shouldRetainStyles }, rest, linkProps, { children: props.children })));
163
+ },
164
+ // used for footnotes
165
+ sup: (props) => {
166
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
167
+ const { node } = props, rest = __rest(props, ["node"]);
168
+ return _jsx(SuperscriptMessage, Object.assign({}, rest));
169
+ }
170
+ }, remarkPlugins: [[remarkGfm, Object.assign({}, remarkGfmProps)], ...additionalRemarkPlugins], rehypePlugins: rehypePlugins }, reactMarkdownProps, { remarkRehypeOptions: Object.assign({
171
+ // removes sr-only class from footnote labels applied by default
172
+ footnoteLabelProperties: { className: [''] } }, reactMarkdownProps === null || reactMarkdownProps === void 0 ? void 0 : reactMarkdownProps.remarkRehypeOptions), disallowedElements: disallowedElements, children: content })));
173
+ };
174
+ export default MarkdownContent;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,187 @@
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 { jsx as _jsx } from "react/jsx-runtime";
11
+ import { render, screen } from '@testing-library/react';
12
+ import '@testing-library/jest-dom';
13
+ import MarkdownContent from './MarkdownContent';
14
+ import rehypeExternalLinks from '../__mocks__/rehype-external-links';
15
+ const BOLD_TEXT = '**Bold text**';
16
+ const ITALIC_TEXT = '*Italic text*';
17
+ const INLINE_CODE = 'Here is inline code: `const x = 5`';
18
+ const CODE_BLOCK = `\`\`\`javascript
19
+ function hello() {
20
+ console.log('Hello, world!');
21
+ }
22
+ \`\`\``;
23
+ const HEADING = '# Heading 1';
24
+ const LINK = '[PatternFly](https://www.patternfly.org/)';
25
+ const UNORDERED_LIST = `
26
+ * Item 1
27
+ * Item 2
28
+ * Item 3
29
+ `;
30
+ const ORDERED_LIST = `
31
+ 1. First item
32
+ 2. Second item
33
+ 3. Third item
34
+ `;
35
+ const TABLE = `
36
+ | Column 1 | Column 2 |
37
+ |----------|----------|
38
+ | Cell 1 | Cell 2 |
39
+ | Cell 3 | Cell 4 |
40
+ `;
41
+ const BLOCKQUOTE = '> This is a blockquote';
42
+ const IMAGE = '![Alt text](https://example.com/image.png)';
43
+ describe('MarkdownContent', () => {
44
+ beforeEach(() => {
45
+ jest.clearAllMocks();
46
+ });
47
+ it('should render bold text correctly', () => {
48
+ const { container } = render(_jsx(MarkdownContent, { content: BOLD_TEXT }));
49
+ expect(container.querySelector('strong')).toBeTruthy();
50
+ expect(screen.getByText('Bold text')).toBeTruthy();
51
+ });
52
+ it('should render italic text correctly', () => {
53
+ const { container } = render(_jsx(MarkdownContent, { content: ITALIC_TEXT }));
54
+ expect(container.querySelector('em')).toBeTruthy();
55
+ expect(screen.getByText('Italic text')).toBeTruthy();
56
+ });
57
+ it('should render inline code correctly', () => {
58
+ render(_jsx(MarkdownContent, { content: INLINE_CODE }));
59
+ expect(screen.getByText(/const x = 5/)).toBeTruthy();
60
+ });
61
+ it('should render code blocks correctly', () => {
62
+ render(_jsx(MarkdownContent, { content: CODE_BLOCK }));
63
+ expect(screen.getByText(/function hello/)).toBeVisible();
64
+ expect(screen.getByText(/console.log/)).toBeVisible();
65
+ expect(screen.getByRole('button', { name: 'Copy code' })).toBeVisible();
66
+ });
67
+ it('should render headings correctly', () => {
68
+ render(_jsx(MarkdownContent, { content: HEADING }));
69
+ expect(screen.getByRole('heading', { name: /Heading 1/i })).toBeTruthy();
70
+ });
71
+ it('should render links correctly', () => {
72
+ render(_jsx(MarkdownContent, { content: LINK }));
73
+ expect(screen.getByRole('link', { name: /PatternFly/i })).toBeTruthy();
74
+ });
75
+ it('should render unordered lists correctly', () => {
76
+ render(_jsx(MarkdownContent, { content: UNORDERED_LIST }));
77
+ expect(screen.getByText('Item 1')).toBeTruthy();
78
+ expect(screen.getByText('Item 2')).toBeTruthy();
79
+ expect(screen.getByText('Item 3')).toBeTruthy();
80
+ expect(screen.getAllByRole('listitem')).toHaveLength(3);
81
+ });
82
+ it('should render ordered lists correctly', () => {
83
+ render(_jsx(MarkdownContent, { content: ORDERED_LIST }));
84
+ expect(screen.getByText('First item')).toBeTruthy();
85
+ expect(screen.getByText('Second item')).toBeTruthy();
86
+ expect(screen.getByText('Third item')).toBeTruthy();
87
+ expect(screen.getAllByRole('listitem')).toHaveLength(3);
88
+ });
89
+ it('should render tables correctly', () => {
90
+ render(_jsx(MarkdownContent, { content: TABLE, tableProps: { 'aria-label': 'Test table' } }));
91
+ expect(screen.getByRole('grid', { name: /Test table/i })).toBeTruthy();
92
+ expect(screen.getByRole('columnheader', { name: /Column 1/i })).toBeTruthy();
93
+ expect(screen.getByRole('columnheader', { name: /Column 2/i })).toBeTruthy();
94
+ expect(screen.getByRole('cell', { name: /Cell 1/i })).toBeTruthy();
95
+ expect(screen.getByRole('cell', { name: /Cell 2/i })).toBeTruthy();
96
+ });
97
+ it('should render blockquotes correctly', () => {
98
+ var _a;
99
+ render(_jsx(MarkdownContent, { content: BLOCKQUOTE }));
100
+ const quote = screen.getByText(/This is a blockquote/);
101
+ expect(quote).toBeVisible();
102
+ expect((_a = quote.closest('.pf-v6-c-content--blockquote')) === null || _a === void 0 ? void 0 : _a.tagName).toBe('BLOCKQUOTE');
103
+ });
104
+ it('should render images when hasNoImages is false', () => {
105
+ render(_jsx(MarkdownContent, { content: IMAGE, hasNoImages: false }));
106
+ expect(screen.getByRole('img', { name: /Alt text/i })).toBeTruthy();
107
+ });
108
+ it('should not render images when hasNoImages is true', () => {
109
+ render(_jsx(MarkdownContent, { content: IMAGE, hasNoImages: true }));
110
+ expect(screen.queryByRole('img', { name: /Alt text/i })).toBeFalsy();
111
+ });
112
+ it('should disable markdown rendering when isMarkdownDisabled is true', () => {
113
+ render(_jsx(MarkdownContent, { content: BOLD_TEXT, isMarkdownDisabled: true }));
114
+ expect(screen.getByText('**Bold text**')).toBeTruthy();
115
+ });
116
+ it('should render text component when isMarkdownDisabled is true and textComponent is provided', () => {
117
+ const textComponent = _jsx("div", { "data-testid": "custom-text", children: "Custom text component" });
118
+ render(_jsx(MarkdownContent, { content: BOLD_TEXT, isMarkdownDisabled: true, textComponent: textComponent }));
119
+ expect(screen.getByTestId('custom-text')).toBeTruthy();
120
+ expect(screen.getByText('Custom text component')).toBeTruthy();
121
+ });
122
+ it('should apply isPrimary prop to elements', () => {
123
+ const { container } = render(_jsx(MarkdownContent, { content: INLINE_CODE, isPrimary: true }));
124
+ expect(container.querySelector('.pf-m-primary')).toBeTruthy();
125
+ });
126
+ it('should apply shouldRetainStyles prop to elements', () => {
127
+ const { container } = render(_jsx(MarkdownContent, { content: BOLD_TEXT, shouldRetainStyles: true }));
128
+ expect(container.querySelector('.pf-m-markdown')).toBeTruthy();
129
+ });
130
+ it('should pass codeBlockProps to code blocks', () => {
131
+ render(_jsx(MarkdownContent, { content: CODE_BLOCK, codeBlockProps: { 'aria-label': 'Custom code block' } }));
132
+ expect(screen.getByRole('button', { name: /Custom code block/i })).toBeTruthy();
133
+ });
134
+ it('should pass tableProps to tables', () => {
135
+ render(_jsx(MarkdownContent, { content: TABLE, tableProps: { 'aria-label': 'Custom table label' } }));
136
+ expect(screen.getByRole('grid', { name: /Custom table label/i })).toBeTruthy();
137
+ });
138
+ it('should open links in new tab when openLinkInNewTab is true', () => {
139
+ render(_jsx(MarkdownContent, { content: LINK, openLinkInNewTab: true }));
140
+ expect(rehypeExternalLinks).toHaveBeenCalledTimes(1);
141
+ });
142
+ it('should not open links in new tab when openLinkInNewTab is false', () => {
143
+ render(_jsx(MarkdownContent, { content: LINK, openLinkInNewTab: false }));
144
+ expect(rehypeExternalLinks).not.toHaveBeenCalled();
145
+ });
146
+ it('should pass linkProps to links', () => __awaiter(void 0, void 0, void 0, function* () {
147
+ const onClick = jest.fn();
148
+ render(_jsx(MarkdownContent, { content: LINK, linkProps: { onClick } }));
149
+ const link = screen.getByRole('link', { name: /PatternFly/i });
150
+ link.click();
151
+ expect(onClick).toHaveBeenCalledTimes(1);
152
+ }));
153
+ it('should handle reactMarkdownProps.disallowedElements', () => {
154
+ render(_jsx(MarkdownContent, { content: CODE_BLOCK, reactMarkdownProps: { disallowedElements: ['code'] } }));
155
+ // Code block should not render when disallowed
156
+ expect(screen.queryByRole('button', { name: /Copy code/i })).toBeFalsy();
157
+ });
158
+ it('should render plain text when no markdown is present', () => {
159
+ render(_jsx(MarkdownContent, { content: "Plain text without markdown" }));
160
+ expect(screen.getByText('Plain text without markdown')).toBeTruthy();
161
+ });
162
+ it('should handle empty content', () => {
163
+ const { container } = render(_jsx(MarkdownContent, { content: "" }));
164
+ expect(container.textContent).toBe('');
165
+ });
166
+ it('should handle undefined content', () => {
167
+ const { container } = render(_jsx(MarkdownContent, {}));
168
+ expect(container.textContent).toBe('');
169
+ });
170
+ it('should render multiple markdown elements together', () => {
171
+ const content = `# Heading
172
+
173
+ **Bold text** and *italic text*
174
+
175
+ \`\`\`javascript
176
+ const x = 5;
177
+ \`\`\`
178
+
179
+ [Link](https://example.com)`;
180
+ render(_jsx(MarkdownContent, { content: content }));
181
+ expect(screen.getByRole('heading', { name: /Heading/i })).toBeTruthy();
182
+ expect(screen.getByText('Bold text')).toBeTruthy();
183
+ expect(screen.getByText('italic text')).toBeTruthy();
184
+ expect(screen.getByText(/const x = 5/)).toBeTruthy();
185
+ expect(screen.getByRole('link', { name: /Link/i })).toBeTruthy();
186
+ });
187
+ });
@@ -0,0 +1,2 @@
1
+ export { default } from './MarkdownContent';
2
+ export * from './MarkdownContent';
@@ -0,0 +1,2 @@
1
+ export { default } from './MarkdownContent';
2
+ export * from './MarkdownContent';
@@ -18,6 +18,10 @@ export interface CodeBlockMessageProps {
18
18
  collapsedText?: string;
19
19
  /** Custom actions added to header of code block, after any default actions such as the "copy" action. */
20
20
  customActions?: React.ReactNode;
21
+ /** Sets background colors to be appropriate on primary chatbot background */
22
+ isPrimary?: boolean;
23
+ /** Flag indicating that the content should retain message styles when using Markdown. */
24
+ shouldRetainStyles?: boolean;
21
25
  }
22
- declare const CodeBlockMessage: ({ children, className, "aria-label": ariaLabel, isExpandable, expandableSectionProps, expandableSectionToggleProps, expandedText, collapsedText, customActions, ...props }: CodeBlockMessageProps) => import("react/jsx-runtime").JSX.Element;
26
+ declare const CodeBlockMessage: ({ children, className, "aria-label": ariaLabel, isExpandable, expandableSectionProps, expandableSectionToggleProps, expandedText, collapsedText, customActions, isPrimary, shouldRetainStyles, ...props }: CodeBlockMessageProps) => import("react/jsx-runtime").JSX.Element;
23
27
  export default CodeBlockMessage;
@@ -18,11 +18,12 @@ import { useState, useRef, useCallback, useEffect } from 'react';
18
18
  import { CodeBlock, CodeBlockAction, CodeBlockCode, Button, Tooltip, ExpandableSection, ExpandableSectionToggle, ExpandableSectionVariant, getUniqueId } from '@patternfly/react-core';
19
19
  import { CheckIcon } from '@patternfly/react-icons/dist/esm/icons/check-icon';
20
20
  import { CopyIcon } from '@patternfly/react-icons/dist/esm/icons/copy-icon';
21
+ import { css } from '@patternfly/react-styles';
21
22
  const DEFAULT_EXPANDED_TEXT = 'Show less';
22
23
  const DEFAULT_COLLAPSED_TEXT = 'Show more';
23
24
  const CodeBlockMessage = (_a) => {
24
25
  var _b;
25
- var { children, className, 'aria-label': ariaLabel, isExpandable = false, expandableSectionProps, expandableSectionToggleProps, expandedText = DEFAULT_EXPANDED_TEXT, collapsedText = DEFAULT_COLLAPSED_TEXT, customActions } = _a, props = __rest(_a, ["children", "className", 'aria-label', "isExpandable", "expandableSectionProps", "expandableSectionToggleProps", "expandedText", "collapsedText", "customActions"]);
26
+ var { children, className, 'aria-label': ariaLabel, isExpandable = false, expandableSectionProps, expandableSectionToggleProps, expandedText = DEFAULT_EXPANDED_TEXT, collapsedText = DEFAULT_COLLAPSED_TEXT, customActions, isPrimary, shouldRetainStyles } = _a, props = __rest(_a, ["children", "className", 'aria-label', "isExpandable", "expandableSectionProps", "expandableSectionToggleProps", "expandedText", "collapsedText", "customActions", "isPrimary", "shouldRetainStyles"]);
26
27
  const [copied, setCopied] = useState(false);
27
28
  const [isExpanded, setIsExpanded] = useState(false);
28
29
  const buttonRef = useRef();
@@ -45,8 +46,18 @@ const CodeBlockMessage = (_a) => {
45
46
  setIsExpanded(isExpanded);
46
47
  };
47
48
  // Handle clicking copy button
48
- const handleCopy = useCallback((event, text) => {
49
- navigator.clipboard.writeText(text.toString());
49
+ const handleCopy = useCallback((_event, text) => {
50
+ let textToCopy = '';
51
+ if (typeof text === 'string') {
52
+ textToCopy = text;
53
+ }
54
+ else {
55
+ if (codeBlockRef.current) {
56
+ const codeElement = codeBlockRef.current.querySelector('code');
57
+ textToCopy = (codeElement === null || codeElement === void 0 ? void 0 : codeElement.textContent) || '';
58
+ }
59
+ }
60
+ navigator.clipboard.writeText(textToCopy);
50
61
  setCopied(true);
51
62
  }, []);
52
63
  // Reset copied state
@@ -59,10 +70,10 @@ const CodeBlockMessage = (_a) => {
59
70
  }
60
71
  });
61
72
  if (!String(children).includes('\n')) {
62
- return (_jsx("code", Object.assign({}, props, { className: "pf-chatbot__message-inline-code", children: children })));
73
+ return (_jsx("code", Object.assign({}, props, { className: `pf-chatbot__message-inline-code ${isPrimary ? 'pf-m-primary' : ''}`, children: children })));
63
74
  }
64
75
  // Setup code block header
65
76
  const actions = (_jsxs(_Fragment, { children: [_jsxs(CodeBlockAction, { className: "pf-chatbot__message-code-block-default-action", children: [language && _jsx("div", { className: "pf-chatbot__message-code-block-language", children: language }), _jsx(Button, { ref: buttonRef, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : 'Copy code', variant: "plain", className: "pf-chatbot__button--copy", onClick: (event) => handleCopy(event, children), children: copied ? _jsx(CheckIcon, {}) : _jsx(CopyIcon, {}) }), _jsx(Tooltip, { id: tooltipID, content: "Copy", position: "top", triggerRef: buttonRef })] }), customActions] }));
66
- return (_jsx("div", { className: "pf-chatbot__message-code-block", ref: codeBlockRef, children: _jsxs(CodeBlock, { actions: actions, children: [_jsx(CodeBlockCode, { children: _jsx(_Fragment, { children: isExpandable ? (_jsx(ExpandableSection, Object.assign({ variant: ExpandableSectionVariant.truncate, isExpanded: isExpanded, isDetached: true, toggleId: toggleId, contentId: contentId }, expandableSectionProps, { children: children }))) : (children) }) }), isExpandable && (_jsx(ExpandableSectionToggle, Object.assign({ isExpanded: isExpanded, onToggle: onToggle, direction: "up", toggleId: toggleId, contentId: contentId, hasTruncatedContent: true, className: "pf-chatbot__message-code-toggle" }, expandableSectionToggleProps, { children: isExpanded ? finalExpandedText : finalCollapsedText })))] }) }));
77
+ return (_jsx("div", { className: css('pf-chatbot__message-code-block', shouldRetainStyles && 'pf-m-markdown'), ref: codeBlockRef, children: _jsxs(CodeBlock, { actions: actions, children: [_jsx(CodeBlockCode, { children: _jsx(_Fragment, { children: isExpandable ? (_jsx(ExpandableSection, Object.assign({ variant: ExpandableSectionVariant.truncate, isExpanded: isExpanded, isDetached: true, toggleId: toggleId, contentId: contentId }, expandableSectionProps, { children: children }))) : (children) }) }), isExpandable && (_jsx(ExpandableSectionToggle, Object.assign({ isExpanded: isExpanded, onToggle: onToggle, direction: "up", toggleId: toggleId, contentId: contentId, hasTruncatedContent: true, className: "pf-chatbot__message-code-toggle" }, expandableSectionToggleProps, { children: isExpanded ? finalExpandedText : finalCollapsedText })))] }) }));
67
78
  };
68
79
  export default CodeBlockMessage;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,126 @@
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 { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
+ import '@testing-library/jest-dom';
12
+ import { render, screen } from '@testing-library/react';
13
+ import userEvent from '@testing-library/user-event';
14
+ import CodeBlockMessage from './CodeBlockMessage';
15
+ // Mock clipboard API
16
+ Object.assign(navigator, {
17
+ clipboard: {
18
+ writeText: jest.fn()
19
+ }
20
+ });
21
+ describe('CodeBlockMessage', () => {
22
+ beforeEach(() => {
23
+ jest.clearAllMocks();
24
+ });
25
+ it('should render inline code for single-line content', () => {
26
+ render(_jsx(CodeBlockMessage, { className: "language-javascript", children: "const x = 5;" }));
27
+ const code = screen.getByText('const x = 5;');
28
+ expect(code.tagName).toBe('CODE');
29
+ expect(code).toHaveClass('pf-chatbot__message-inline-code');
30
+ });
31
+ it('should render code block for multi-line content', () => {
32
+ const multilineCode = 'const x = 5;\nconst y = 10;';
33
+ const { container } = render(_jsx(CodeBlockMessage, { className: "language-javascript", children: multilineCode }));
34
+ const codeElement = container.querySelector('code');
35
+ expect(codeElement === null || codeElement === void 0 ? void 0 : codeElement.textContent).toBe(multilineCode);
36
+ });
37
+ it('should display language label', () => {
38
+ const code = 'const x = 5;\nconst y = 10;';
39
+ render(_jsx(CodeBlockMessage, { className: "language-javascript", children: code }));
40
+ expect(screen.getByText('javascript')).toBeInTheDocument();
41
+ });
42
+ it('should render copy button', () => {
43
+ const code = 'const x = 5;\nconst y = 10;';
44
+ render(_jsx(CodeBlockMessage, { children: code }));
45
+ expect(screen.getByRole('button', { name: 'Copy code' })).toBeInTheDocument();
46
+ });
47
+ it('should copy plain string content to clipboard', () => __awaiter(void 0, void 0, void 0, function* () {
48
+ const code = 'const x = 5;\nconst y = 10;';
49
+ render(_jsx(CodeBlockMessage, { children: code }));
50
+ const copyButton = screen.getByRole('button', { name: 'Copy code' });
51
+ yield userEvent.click(copyButton);
52
+ expect(navigator.clipboard.writeText).toHaveBeenCalledWith(code);
53
+ }));
54
+ it('should extract text content from React elements when copying', () => __awaiter(void 0, void 0, void 0, function* () {
55
+ // Simulate what happens with syntax highlighting - children become React elements
56
+ const { container } = render(_jsxs(CodeBlockMessage, { className: "language-javascript", children: [_jsx("span", { className: "hljs-keyword", children: "const" }), " x = 5;", '\n', _jsx("span", { className: "hljs-keyword", children: "const" }), " y = 10;"] }));
57
+ const copyButton = screen.getByRole('button', { name: 'Copy code' });
58
+ yield userEvent.click(copyButton);
59
+ // Should extract actual text content from DOM, not "[object Object]"
60
+ const codeElement = container.querySelector('code');
61
+ const expectedText = (codeElement === null || codeElement === void 0 ? void 0 : codeElement.textContent) || '';
62
+ expect(navigator.clipboard.writeText).toHaveBeenCalledWith(expectedText);
63
+ expect(expectedText).not.toContain('[object Object]');
64
+ }));
65
+ it('should show check icon after copying', () => __awaiter(void 0, void 0, void 0, function* () {
66
+ const code = 'const x = 5;\nconst y = 10;';
67
+ render(_jsx(CodeBlockMessage, { children: code }));
68
+ const copyButton = screen.getByRole('button', { name: 'Copy code' });
69
+ yield userEvent.click(copyButton);
70
+ // Check icon should be visible (we can verify by checking if CopyIcon is not present)
71
+ const svgElement = copyButton.querySelector('svg');
72
+ expect(svgElement).toBeInTheDocument();
73
+ }));
74
+ it('should render expandable section when isExpandable is true', () => {
75
+ const code = 'const x = 5;\nconst y = 10;';
76
+ render(_jsx(CodeBlockMessage, { isExpandable: true, children: code }));
77
+ expect(screen.getByRole('button', { name: 'Show more' })).toBeInTheDocument();
78
+ });
79
+ it('should toggle expandable section', () => __awaiter(void 0, void 0, void 0, function* () {
80
+ const code = 'const x = 5;\nconst y = 10;';
81
+ render(_jsx(CodeBlockMessage, { isExpandable: true, children: code }));
82
+ const toggleButton = screen.getByRole('button', { name: 'Show more' });
83
+ yield userEvent.click(toggleButton);
84
+ expect(screen.getByRole('button', { name: 'Show less' })).toBeInTheDocument();
85
+ }));
86
+ it('should use custom expanded/collapsed text', () => {
87
+ const code = 'const x = 5;\nconst y = 10;';
88
+ render(_jsx(CodeBlockMessage, { isExpandable: true, expandedText: "Hide", collapsedText: "Reveal", children: code }));
89
+ expect(screen.getByRole('button', { name: 'Reveal' })).toBeInTheDocument();
90
+ });
91
+ it('should pass through expandableSectionProps', () => {
92
+ const code = 'const x = 5;\nconst y = 10;';
93
+ const { container } = render(_jsx(CodeBlockMessage, { isExpandable: true, expandableSectionProps: { className: 'custom-expandable-class' }, children: code }));
94
+ const expandableSection = container.querySelector('.pf-v6-c-expandable-section.custom-expandable-class');
95
+ expect(expandableSection).toBeInTheDocument();
96
+ });
97
+ it('should render custom actions', () => {
98
+ const code = 'const x = 5;\nconst y = 10;';
99
+ const customAction = _jsx("button", { "aria-label": "Custom action", children: "Custom" });
100
+ render(_jsx(CodeBlockMessage, { customActions: customAction, children: code }));
101
+ expect(screen.getByRole('button', { name: 'Custom action' })).toBeInTheDocument();
102
+ });
103
+ it('should apply isPrimary class to inline code', () => {
104
+ render(_jsx(CodeBlockMessage, { isPrimary: true, children: "const x = 5;" }));
105
+ const code = screen.getByText('const x = 5;');
106
+ expect(code).toHaveClass('pf-m-primary');
107
+ });
108
+ it('should apply shouldRetainStyles class to code block', () => {
109
+ const code = 'const x = 5;\nconst y = 10;';
110
+ const { container } = render(_jsx(CodeBlockMessage, { shouldRetainStyles: true, children: code }));
111
+ const codeBlockDiv = container.querySelector('.pf-chatbot__message-code-block');
112
+ expect(codeBlockDiv).toHaveClass('pf-m-markdown');
113
+ });
114
+ it('should use custom aria-label for copy button', () => {
115
+ const code = 'const x = 5;\nconst y = 10;';
116
+ render(_jsx(CodeBlockMessage, { "aria-label": "Copy this code", children: code }));
117
+ expect(screen.getByRole('button', { name: 'Copy this code' })).toBeInTheDocument();
118
+ });
119
+ it('should prioritize data-expanded-text over expandedText prop', () => {
120
+ const code = 'const x = 5;\nconst y = 10;';
121
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn());
122
+ render(_jsx(CodeBlockMessage, { isExpandable: true, expandedText: "Custom Expanded", "data-expanded-text": "Data Expanded", children: code }));
123
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Message:', expect.stringContaining('data-expanded-text or data-collapsed-text will override'));
124
+ consoleErrorSpy.mockRestore();
125
+ });
126
+ });
@@ -1,3 +1,17 @@
1
1
  import { AlertProps } from '@patternfly/react-core';
2
- declare const ErrorMessage: ({ title, actionLinks, children, ...props }: AlertProps) => import("react/jsx-runtime").JSX.Element;
2
+ /**
3
+ * ErrorMessage displays an inline danger alert for error states in messages.
4
+ * Use this component when passing children to Message to display error information.
5
+ */
6
+ export interface ErrorMessageProps extends Partial<AlertProps> {
7
+ /** Content to display in the error alert body */
8
+ children?: React.ReactNode;
9
+ /** Additional classes for the error alert */
10
+ className?: string;
11
+ /** Title of the error alert */
12
+ title?: React.ReactNode;
13
+ /** Action links to display in the alert footer */
14
+ actionLinks?: React.ReactNode;
15
+ }
16
+ export declare const ErrorMessage: ({ title, actionLinks, children, className, ...props }: ErrorMessageProps) => import("react/jsx-runtime").JSX.Element;
3
17
  export default ErrorMessage;