@patternfly/chatbot 6.5.0-prerelease.9 → 6.6.0-prerelease.1

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 (315) hide show
  1. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +9 -1
  2. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +9 -2
  3. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +38 -0
  4. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +29 -2
  5. package/dist/cjs/CodeModal/CodeModal.d.ts +2 -0
  6. package/dist/cjs/CodeModal/CodeModal.js +53 -12
  7. package/dist/cjs/DeepThinking/DeepThinking.d.ts +13 -0
  8. package/dist/cjs/DeepThinking/DeepThinking.js +31 -3
  9. package/dist/cjs/DeepThinking/DeepThinking.test.js +80 -0
  10. package/dist/cjs/MarkdownContent/MarkdownContent.d.ts +44 -0
  11. package/dist/cjs/MarkdownContent/MarkdownContent.js +181 -0
  12. package/dist/cjs/MarkdownContent/MarkdownContent.test.d.ts +1 -0
  13. package/dist/cjs/MarkdownContent/MarkdownContent.test.js +192 -0
  14. package/dist/cjs/MarkdownContent/index.d.ts +2 -0
  15. package/dist/cjs/MarkdownContent/index.js +23 -0
  16. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.d.ts +3 -1
  17. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +15 -4
  18. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.test.d.ts +1 -0
  19. package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.test.js +131 -0
  20. package/dist/cjs/Message/ErrorMessage/ErrorMessage.d.ts +15 -1
  21. package/dist/cjs/Message/ErrorMessage/ErrorMessage.js +5 -3
  22. package/dist/cjs/Message/ErrorMessage/ErrorMessage.test.d.ts +1 -0
  23. package/dist/cjs/Message/ErrorMessage/ErrorMessage.test.js +30 -0
  24. package/dist/cjs/Message/LinkMessage/LinkMessage.d.ts +5 -1
  25. package/dist/cjs/Message/LinkMessage/LinkMessage.js +4 -3
  26. package/dist/cjs/Message/ListMessage/OrderedListMessage.d.ts +9 -1
  27. package/dist/cjs/Message/ListMessage/OrderedListMessage.js +2 -1
  28. package/dist/cjs/Message/ListMessage/UnorderedListMessage.d.ts +7 -1
  29. package/dist/cjs/Message/ListMessage/UnorderedListMessage.js +2 -1
  30. package/dist/cjs/Message/Message.d.ts +20 -3
  31. package/dist/cjs/Message/Message.js +7 -160
  32. package/dist/cjs/Message/Message.test.js +129 -2
  33. package/dist/cjs/Message/MessageAndActions/MessageAndActions.d.ts +14 -0
  34. package/dist/cjs/Message/MessageAndActions/MessageAndActions.js +22 -0
  35. package/dist/cjs/Message/MessageAndActions/MessageAndActions.test.d.ts +1 -0
  36. package/dist/cjs/Message/MessageAndActions/MessageAndActions.test.js +25 -0
  37. package/dist/cjs/Message/MessageAndActions/index.d.ts +1 -0
  38. package/dist/cjs/Message/MessageAndActions/index.js +17 -0
  39. package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.d.ts +13 -0
  40. package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.js +22 -0
  41. package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.test.d.ts +1 -0
  42. package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.test.js +25 -0
  43. package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.d.ts +13 -0
  44. package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.js +22 -0
  45. package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.test.d.ts +1 -0
  46. package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.test.js +25 -0
  47. package/dist/cjs/Message/MessageAttachments/index.d.ts +2 -0
  48. package/dist/cjs/Message/MessageAttachments/index.js +18 -0
  49. package/dist/cjs/Message/MessageInput.d.ts +1 -1
  50. package/dist/cjs/Message/MessageInput.js +3 -1
  51. package/dist/cjs/Message/MessageLoading.d.ts +13 -4
  52. package/dist/cjs/Message/MessageLoading.js +19 -5
  53. package/dist/cjs/Message/MessageLoading.test.d.ts +1 -0
  54. package/dist/cjs/Message/MessageLoading.test.js +25 -0
  55. package/dist/cjs/Message/QuickResponse/QuickResponse.js +3 -2
  56. package/dist/cjs/Message/QuickResponse/QuickResponse.test.d.ts +1 -0
  57. package/dist/cjs/Message/QuickResponse/QuickResponse.test.js +109 -0
  58. package/dist/cjs/Message/QuickResponse/index.d.ts +1 -0
  59. package/dist/cjs/Message/QuickResponse/index.js +17 -0
  60. package/dist/cjs/Message/QuickStarts/QuickStartTile.d.ts +1 -1
  61. package/dist/cjs/Message/QuickStarts/QuickStartTile.js +3 -2
  62. package/dist/cjs/Message/QuickStarts/index.d.ts +2 -0
  63. package/dist/cjs/Message/QuickStarts/index.js +18 -0
  64. package/dist/cjs/Message/TableMessage/TableMessage.d.ts +6 -1
  65. package/dist/cjs/Message/TableMessage/TableMessage.js +3 -2
  66. package/dist/cjs/Message/TextMessage/TextMessage.d.ts +8 -1
  67. package/dist/cjs/Message/TextMessage/TextMessage.js +3 -2
  68. package/dist/cjs/Message/UserFeedback/UserFeedback.d.ts +3 -1
  69. package/dist/cjs/Message/UserFeedback/UserFeedback.js +8 -6
  70. package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.d.ts +1 -1
  71. package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.js +3 -2
  72. package/dist/cjs/Message/UserFeedback/index.d.ts +2 -0
  73. package/dist/cjs/Message/UserFeedback/index.js +18 -0
  74. package/dist/cjs/Message/index.d.ts +8 -0
  75. package/dist/cjs/Message/index.js +8 -0
  76. package/dist/cjs/MessageBar/MessageBar.d.ts +10 -0
  77. package/dist/cjs/MessageBar/MessageBar.js +42 -10
  78. package/dist/cjs/MessageBar/MessageBar.test.js +20 -0
  79. package/dist/cjs/Onboarding/Onboarding.d.ts +36 -0
  80. package/dist/cjs/Onboarding/Onboarding.js +37 -0
  81. package/dist/cjs/Onboarding/Onboarding.test.d.ts +1 -0
  82. package/dist/cjs/Onboarding/Onboarding.test.js +80 -0
  83. package/dist/cjs/Onboarding/index.d.ts +2 -0
  84. package/dist/cjs/Onboarding/index.js +23 -0
  85. package/dist/cjs/ResponseActions/ResponseActions.d.ts +7 -0
  86. package/dist/cjs/ResponseActions/ResponseActions.js +28 -7
  87. package/dist/cjs/ResponseActions/ResponseActions.test.js +67 -12
  88. package/dist/cjs/ResponseActions/ResponseActionsGroups.d.ts +13 -0
  89. package/dist/cjs/ResponseActions/ResponseActionsGroups.js +22 -0
  90. package/dist/cjs/ResponseActions/ResponseActionsGroups.test.d.ts +1 -0
  91. package/dist/cjs/ResponseActions/ResponseActionsGroups.test.js +25 -0
  92. package/dist/cjs/ResponseActions/index.d.ts +1 -0
  93. package/dist/cjs/ResponseActions/index.js +1 -0
  94. package/dist/cjs/ToolCall/ToolCall.d.ts +11 -0
  95. package/dist/cjs/ToolCall/ToolCall.js +24 -3
  96. package/dist/cjs/ToolCall/ToolCall.test.js +57 -0
  97. package/dist/cjs/ToolResponse/ToolResponse.d.ts +17 -0
  98. package/dist/cjs/ToolResponse/ToolResponse.js +49 -3
  99. package/dist/cjs/ToolResponse/ToolResponse.test.js +100 -0
  100. package/dist/cjs/index.d.ts +4 -0
  101. package/dist/cjs/index.js +7 -1
  102. package/dist/css/main.css +276 -30
  103. package/dist/css/main.css.map +1 -1
  104. package/dist/dynamic/MarkdownContent/package.json +1 -0
  105. package/dist/dynamic/Onboarding/package.json +1 -0
  106. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +9 -1
  107. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +10 -3
  108. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +38 -0
  109. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +30 -3
  110. package/dist/esm/CodeModal/CodeModal.d.ts +2 -0
  111. package/dist/esm/CodeModal/CodeModal.js +54 -13
  112. package/dist/esm/DeepThinking/DeepThinking.d.ts +13 -0
  113. package/dist/esm/DeepThinking/DeepThinking.js +28 -3
  114. package/dist/esm/DeepThinking/DeepThinking.test.js +80 -0
  115. package/dist/esm/MarkdownContent/MarkdownContent.d.ts +44 -0
  116. package/dist/esm/MarkdownContent/MarkdownContent.js +174 -0
  117. package/dist/esm/MarkdownContent/MarkdownContent.test.d.ts +1 -0
  118. package/dist/esm/MarkdownContent/MarkdownContent.test.js +187 -0
  119. package/dist/esm/MarkdownContent/index.d.ts +2 -0
  120. package/dist/esm/MarkdownContent/index.js +2 -0
  121. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.d.ts +3 -1
  122. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +15 -4
  123. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.test.d.ts +1 -0
  124. package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.test.js +126 -0
  125. package/dist/esm/Message/ErrorMessage/ErrorMessage.d.ts +15 -1
  126. package/dist/esm/Message/ErrorMessage/ErrorMessage.js +3 -3
  127. package/dist/esm/Message/ErrorMessage/ErrorMessage.test.d.ts +1 -0
  128. package/dist/esm/Message/ErrorMessage/ErrorMessage.test.js +25 -0
  129. package/dist/esm/Message/LinkMessage/LinkMessage.d.ts +5 -1
  130. package/dist/esm/Message/LinkMessage/LinkMessage.js +4 -3
  131. package/dist/esm/Message/ListMessage/OrderedListMessage.d.ts +9 -1
  132. package/dist/esm/Message/ListMessage/OrderedListMessage.js +2 -1
  133. package/dist/esm/Message/ListMessage/UnorderedListMessage.d.ts +7 -1
  134. package/dist/esm/Message/ListMessage/UnorderedListMessage.js +2 -1
  135. package/dist/esm/Message/Message.d.ts +20 -3
  136. package/dist/esm/Message/Message.js +8 -161
  137. package/dist/esm/Message/Message.test.js +129 -2
  138. package/dist/esm/Message/MessageAndActions/MessageAndActions.d.ts +14 -0
  139. package/dist/esm/Message/MessageAndActions/MessageAndActions.js +18 -0
  140. package/dist/esm/Message/MessageAndActions/MessageAndActions.test.d.ts +1 -0
  141. package/dist/esm/Message/MessageAndActions/MessageAndActions.test.js +20 -0
  142. package/dist/esm/Message/MessageAndActions/index.d.ts +1 -0
  143. package/dist/esm/Message/MessageAndActions/index.js +1 -0
  144. package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.d.ts +13 -0
  145. package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.js +18 -0
  146. package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.test.d.ts +1 -0
  147. package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.test.js +20 -0
  148. package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.d.ts +13 -0
  149. package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.js +18 -0
  150. package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.test.d.ts +1 -0
  151. package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.test.js +20 -0
  152. package/dist/esm/Message/MessageAttachments/index.d.ts +2 -0
  153. package/dist/esm/Message/MessageAttachments/index.js +2 -0
  154. package/dist/esm/Message/MessageInput.d.ts +1 -1
  155. package/dist/esm/Message/MessageInput.js +1 -1
  156. package/dist/esm/Message/MessageLoading.d.ts +13 -4
  157. package/dist/esm/Message/MessageLoading.js +16 -4
  158. package/dist/esm/Message/MessageLoading.test.d.ts +1 -0
  159. package/dist/esm/Message/MessageLoading.test.js +20 -0
  160. package/dist/esm/Message/QuickResponse/QuickResponse.js +3 -2
  161. package/dist/esm/Message/QuickResponse/QuickResponse.test.d.ts +1 -0
  162. package/dist/esm/Message/QuickResponse/QuickResponse.test.js +104 -0
  163. package/dist/esm/Message/QuickResponse/index.d.ts +1 -0
  164. package/dist/esm/Message/QuickResponse/index.js +1 -0
  165. package/dist/esm/Message/QuickStarts/QuickStartTile.d.ts +1 -1
  166. package/dist/esm/Message/QuickStarts/QuickStartTile.js +1 -1
  167. package/dist/esm/Message/QuickStarts/index.d.ts +2 -0
  168. package/dist/esm/Message/QuickStarts/index.js +2 -0
  169. package/dist/esm/Message/TableMessage/TableMessage.d.ts +6 -1
  170. package/dist/esm/Message/TableMessage/TableMessage.js +3 -2
  171. package/dist/esm/Message/TextMessage/TextMessage.d.ts +8 -1
  172. package/dist/esm/Message/TextMessage/TextMessage.js +3 -2
  173. package/dist/esm/Message/UserFeedback/UserFeedback.d.ts +3 -1
  174. package/dist/esm/Message/UserFeedback/UserFeedback.js +7 -7
  175. package/dist/esm/Message/UserFeedback/UserFeedbackComplete.d.ts +1 -1
  176. package/dist/esm/Message/UserFeedback/UserFeedbackComplete.js +1 -2
  177. package/dist/esm/Message/UserFeedback/index.d.ts +2 -0
  178. package/dist/esm/Message/UserFeedback/index.js +2 -0
  179. package/dist/esm/Message/index.d.ts +8 -0
  180. package/dist/esm/Message/index.js +8 -0
  181. package/dist/esm/MessageBar/MessageBar.d.ts +10 -0
  182. package/dist/esm/MessageBar/MessageBar.js +42 -10
  183. package/dist/esm/MessageBar/MessageBar.test.js +20 -0
  184. package/dist/esm/Onboarding/Onboarding.d.ts +36 -0
  185. package/dist/esm/Onboarding/Onboarding.js +30 -0
  186. package/dist/esm/Onboarding/Onboarding.test.d.ts +1 -0
  187. package/dist/esm/Onboarding/Onboarding.test.js +75 -0
  188. package/dist/esm/Onboarding/index.d.ts +2 -0
  189. package/dist/esm/Onboarding/index.js +2 -0
  190. package/dist/esm/ResponseActions/ResponseActions.d.ts +7 -0
  191. package/dist/esm/ResponseActions/ResponseActions.js +28 -7
  192. package/dist/esm/ResponseActions/ResponseActions.test.js +67 -12
  193. package/dist/esm/ResponseActions/ResponseActionsGroups.d.ts +13 -0
  194. package/dist/esm/ResponseActions/ResponseActionsGroups.js +18 -0
  195. package/dist/esm/ResponseActions/ResponseActionsGroups.test.d.ts +1 -0
  196. package/dist/esm/ResponseActions/ResponseActionsGroups.test.js +20 -0
  197. package/dist/esm/ResponseActions/index.d.ts +1 -0
  198. package/dist/esm/ResponseActions/index.js +1 -0
  199. package/dist/esm/ToolCall/ToolCall.d.ts +11 -0
  200. package/dist/esm/ToolCall/ToolCall.js +21 -3
  201. package/dist/esm/ToolCall/ToolCall.test.js +57 -0
  202. package/dist/esm/ToolResponse/ToolResponse.d.ts +17 -0
  203. package/dist/esm/ToolResponse/ToolResponse.js +46 -3
  204. package/dist/esm/ToolResponse/ToolResponse.test.js +100 -0
  205. package/dist/esm/index.d.ts +4 -0
  206. package/dist/esm/index.js +4 -0
  207. package/dist/tsconfig.tsbuildinfo +1 -1
  208. package/package.json +13 -3
  209. package/patternfly-docs/content/extensions/chatbot/chatbot.md +57 -0
  210. package/patternfly-docs/content/extensions/chatbot/design-guidelines.md +12 -12
  211. package/patternfly-docs/content/extensions/chatbot/examples/Analytics/Analytics.md +1 -1
  212. package/patternfly-docs/content/extensions/chatbot/examples/Customizing Messages/Customizing Messages.md +1 -1
  213. package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +1 -0
  214. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithCustomStructure.tsx +102 -0
  215. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithDeepThinking.tsx +25 -11
  216. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithFeedback.tsx +14 -1
  217. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMarkdownDeepThinking.tsx +26 -0
  218. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMarkdownToolCall.tsx +29 -0
  219. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMarkdownToolResponse.tsx +200 -0
  220. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMultipleActionGroups.tsx +61 -0
  221. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithPersistedActions.tsx +22 -0
  222. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickResponses.tsx +11 -0
  223. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithToolCall.tsx +14 -1
  224. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithToolResponse.tsx +222 -105
  225. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +123 -14
  226. package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +1 -0
  227. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithSearchActions.tsx +198 -0
  228. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarCustomActions.tsx +190 -0
  229. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarIndicatorThinking.tsx +15 -0
  230. package/patternfly-docs/content/extensions/chatbot/examples/UI/CompactOnboarding.tsx +141 -0
  231. package/patternfly-docs/content/extensions/chatbot/examples/UI/Onboarding.tsx +151 -0
  232. package/patternfly-docs/content/extensions/chatbot/examples/UI/RH-Hat-Image.svg +9 -0
  233. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +81 -30
  234. package/patternfly-docs/content/extensions/chatbot/examples/demos/AttachmentDemos.md +18 -18
  235. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +33 -19
  236. package/patternfly-docs/patternfly-docs.config.js +1 -1
  237. package/patternfly-docs/patternfly-docs.source.js +1 -1
  238. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +43 -0
  239. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +95 -0
  240. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +51 -15
  241. package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +56 -14
  242. package/src/ChatbotModal/ChatbotModal.scss +3 -0
  243. package/src/CodeModal/CodeModal.tsx +71 -26
  244. package/src/DeepThinking/DeepThinking.scss +1 -1
  245. package/src/DeepThinking/DeepThinking.test.tsx +109 -0
  246. package/src/DeepThinking/DeepThinking.tsx +54 -5
  247. package/src/MarkdownContent/MarkdownContent.test.tsx +207 -0
  248. package/src/MarkdownContent/MarkdownContent.tsx +269 -0
  249. package/src/MarkdownContent/index.ts +2 -0
  250. package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +13 -0
  251. package/src/Message/CodeBlockMessage/CodeBlockMessage.test.tsx +171 -0
  252. package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +17 -4
  253. package/src/Message/ErrorMessage/ErrorMessage.test.tsx +38 -0
  254. package/src/Message/ErrorMessage/ErrorMessage.tsx +17 -2
  255. package/src/Message/LinkMessage/LinkMessage.scss +5 -0
  256. package/src/Message/LinkMessage/LinkMessage.tsx +24 -2
  257. package/src/Message/ListMessage/ListMessage.scss +8 -0
  258. package/src/Message/ListMessage/OrderedListMessage.tsx +16 -2
  259. package/src/Message/ListMessage/UnorderedListMessage.tsx +12 -2
  260. package/src/Message/Message.scss +11 -7
  261. package/src/Message/Message.test.tsx +202 -2
  262. package/src/Message/Message.tsx +129 -241
  263. package/src/Message/MessageAndActions/MessageAndActions.test.tsx +23 -0
  264. package/src/Message/MessageAndActions/MessageAndActions.tsx +22 -0
  265. package/src/Message/MessageAndActions/index.ts +1 -0
  266. package/src/Message/MessageAttachments/MessageAttachmentItem.test.tsx +23 -0
  267. package/src/Message/MessageAttachments/MessageAttachmentItem.tsx +25 -0
  268. package/src/Message/MessageAttachments/MessageAttachmentsContainer.test.tsx +23 -0
  269. package/src/Message/MessageAttachments/MessageAttachmentsContainer.tsx +25 -0
  270. package/src/Message/MessageAttachments/index.ts +2 -0
  271. package/src/Message/MessageInput.tsx +1 -1
  272. package/src/Message/MessageLoading.test.tsx +23 -0
  273. package/src/Message/MessageLoading.tsx +17 -2
  274. package/src/Message/QuickResponse/QuickResponse.scss +3 -1
  275. package/src/Message/QuickResponse/QuickResponse.test.tsx +131 -0
  276. package/src/Message/QuickResponse/QuickResponse.tsx +3 -2
  277. package/src/Message/QuickResponse/index.ts +1 -0
  278. package/src/Message/QuickStarts/QuickStartTile.tsx +1 -1
  279. package/src/Message/QuickStarts/index.ts +2 -0
  280. package/src/Message/TableMessage/TableMessage.scss +13 -1
  281. package/src/Message/TableMessage/TableMessage.tsx +18 -2
  282. package/src/Message/TextMessage/TextMessage.scss +12 -0
  283. package/src/Message/TextMessage/TextMessage.tsx +29 -2
  284. package/src/Message/UserFeedback/UserFeedback.scss +28 -1
  285. package/src/Message/UserFeedback/UserFeedback.tsx +23 -13
  286. package/src/Message/UserFeedback/UserFeedbackComplete.tsx +1 -4
  287. package/src/Message/UserFeedback/index.ts +2 -0
  288. package/src/Message/index.ts +8 -0
  289. package/src/MessageBar/AttachButton.scss +0 -1
  290. package/src/MessageBar/MessageBar.scss +63 -7
  291. package/src/MessageBar/MessageBar.test.tsx +39 -0
  292. package/src/MessageBar/MessageBar.tsx +124 -48
  293. package/src/MessageBar/MicrophoneButton.scss +0 -1
  294. package/src/MessageBar/SendButton.scss +0 -1
  295. package/src/MessageBar/StopButton.scss +0 -1
  296. package/src/Onboarding/Onboarding.scss +101 -0
  297. package/src/Onboarding/Onboarding.test.tsx +148 -0
  298. package/src/Onboarding/Onboarding.tsx +126 -0
  299. package/src/Onboarding/index.ts +3 -0
  300. package/src/ResponseActions/ResponseActions.scss +12 -1
  301. package/src/ResponseActions/ResponseActions.test.tsx +111 -12
  302. package/src/ResponseActions/ResponseActions.tsx +44 -10
  303. package/src/ResponseActions/ResponseActionsGroups.test.tsx +23 -0
  304. package/src/ResponseActions/ResponseActionsGroups.tsx +28 -0
  305. package/src/ResponseActions/index.ts +1 -0
  306. package/src/ToolCall/ToolCall.scss +1 -1
  307. package/src/ToolCall/ToolCall.test.tsx +91 -0
  308. package/src/ToolCall/ToolCall.tsx +49 -4
  309. package/src/ToolResponse/ToolResponse.scss +13 -3
  310. package/src/ToolResponse/ToolResponse.test.tsx +119 -0
  311. package/src/ToolResponse/ToolResponse.tsx +82 -7
  312. package/src/index.ts +6 -0
  313. package/src/main.scss +2 -0
  314. package/tsconfig.json +1 -1
  315. package/patternfly-docs/content/extensions/chatbot/about-chatbot.md +0 -44
@@ -1,5 +1,5 @@
1
1
  import type { FunctionComponent } from 'react';
2
- import { ButtonProps, DrawerProps, DrawerPanelContentProps, DrawerContentProps, DrawerContentBodyProps, DrawerHeadProps, DrawerActionsProps, DrawerCloseButtonProps, DrawerPanelBodyProps, SkeletonProps, MenuProps, TitleProps, MenuListProps, SearchInputProps, MenuItemProps, MenuGroupProps, MenuContentProps } from '@patternfly/react-core';
2
+ import { ButtonProps, DrawerProps, DrawerPanelContentProps, DrawerContentProps, DrawerContentBodyProps, DrawerHeadProps, DrawerActionsProps, DrawerCloseButtonProps, DrawerPanelBodyProps, SkeletonProps, TitleProps, SearchInputProps, MenuProps, MenuListProps, MenuItemProps, MenuGroupProps, MenuContentProps } from '@patternfly/react-core';
3
3
  import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
4
4
  import { HistoryEmptyStateProps } from './EmptyState';
5
5
  export interface Conversation {
@@ -84,6 +84,8 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
84
84
  drawerCloseButtonProps?: DrawerCloseButtonProps;
85
85
  /** Additional props appleid to drawer panel body */
86
86
  drawerPanelBodyProps?: DrawerPanelBodyProps;
87
+ /** Flag indicating whether a divider should render between the drawer head and title. */
88
+ hasDrawerHeadDivider?: boolean;
87
89
  /** Whether to show drawer loading state */
88
90
  isLoading?: boolean;
89
91
  /** Additional props for loading state */
@@ -104,6 +106,12 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
104
106
  navTitleProps?: Partial<TitleProps>;
105
107
  /** Visually hidden text that gets announced by assistive technologies. Should be used to convey the result count when the search input value changes. */
106
108
  searchInputScreenReaderText?: string;
109
+ /** Custom action rendered before the search input. */
110
+ searchActionStart?: React.ReactNode;
111
+ /** Custom action rendered after the search input. */
112
+ searchActionEnd?: React.ReactNode;
113
+ /** A custom search toolbar to render below the title. This will override the default search actions and/or search input. */
114
+ searchToolbar?: React.ReactNode;
107
115
  /** Additional props passed to MenuContent */
108
116
  menuContentProps?: Omit<MenuContentProps, 'ref'>;
109
117
  }
@@ -25,7 +25,7 @@ const ChatbotConversationHistoryDropdown_1 = __importDefault(require("./ChatbotC
25
25
  const LoadingState_1 = __importDefault(require("./LoadingState"));
26
26
  const EmptyState_1 = __importDefault(require("./EmptyState"));
27
27
  const ChatbotConversationHistoryNav = (_a) => {
28
- var { onDrawerToggle, isDrawerOpen, setIsDrawerOpen, activeItemId, onSelectActiveItem, conversations, menuListProps, newChatButtonText = 'New chat', drawerContent, onNewChat, newChatButtonProps, searchInputPlaceholder = 'Search previous conversations...', searchInputAriaLabel = 'Search previous conversations', searchInputProps, handleTextInputChange, displayMode, reverseButtonOrder = false, drawerActionsTestId = 'chatbot-nav-drawer-actions', drawerPanelContentProps, drawerContentProps, drawerContentBodyProps, drawerHeadProps, drawerActionsProps, drawerCloseButtonProps, drawerPanelBodyProps, isLoading, loadingState, errorState, emptyState, noResultsState, isCompact, title = 'Chat history', navTitleProps, navTitleIcon = (0, jsx_runtime_1.jsx)(react_icons_1.OutlinedClockIcon, {}), searchInputScreenReaderText, menuProps, menuGroupProps, menuContentProps } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "menuListProps", "newChatButtonText", "drawerContent", "onNewChat", "newChatButtonProps", "searchInputPlaceholder", "searchInputAriaLabel", "searchInputProps", "handleTextInputChange", "displayMode", "reverseButtonOrder", "drawerActionsTestId", "drawerPanelContentProps", "drawerContentProps", "drawerContentBodyProps", "drawerHeadProps", "drawerActionsProps", "drawerCloseButtonProps", "drawerPanelBodyProps", "isLoading", "loadingState", "errorState", "emptyState", "noResultsState", "isCompact", "title", "navTitleProps", "navTitleIcon", "searchInputScreenReaderText", "menuProps", "menuGroupProps", "menuContentProps"]);
28
+ var { onDrawerToggle, isDrawerOpen, setIsDrawerOpen, activeItemId, onSelectActiveItem, conversations, menuListProps, newChatButtonText = 'New chat', drawerContent, onNewChat, newChatButtonProps, searchInputPlaceholder = 'Search previous conversations...', searchInputAriaLabel = 'Search previous conversations', searchInputProps, handleTextInputChange, displayMode, reverseButtonOrder = false, drawerActionsTestId = 'chatbot-nav-drawer-actions', drawerPanelContentProps, drawerContentProps, drawerContentBodyProps, drawerHeadProps, drawerActionsProps, drawerCloseButtonProps, drawerPanelBodyProps, hasDrawerHeadDivider, isLoading, loadingState, errorState, emptyState, noResultsState, isCompact, title = 'Chat history', navTitleProps, navTitleIcon = (0, jsx_runtime_1.jsx)(react_icons_1.OutlinedClockIcon, {}), searchInputScreenReaderText, searchActionStart, searchActionEnd, searchToolbar, menuProps, menuGroupProps, menuContentProps } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "menuListProps", "newChatButtonText", "drawerContent", "onNewChat", "newChatButtonProps", "searchInputPlaceholder", "searchInputAriaLabel", "searchInputProps", "handleTextInputChange", "displayMode", "reverseButtonOrder", "drawerActionsTestId", "drawerPanelContentProps", "drawerContentProps", "drawerContentBodyProps", "drawerHeadProps", "drawerActionsProps", "drawerCloseButtonProps", "drawerPanelBodyProps", "hasDrawerHeadDivider", "isLoading", "loadingState", "errorState", "emptyState", "noResultsState", "isCompact", "title", "navTitleProps", "navTitleIcon", "searchInputScreenReaderText", "searchActionStart", "searchActionEnd", "searchToolbar", "menuProps", "menuGroupProps", "menuContentProps"]);
29
29
  const drawerRef = (0, react_1.useRef)(null);
30
30
  const onExpand = () => {
31
31
  drawerRef.current && drawerRef.current.focus();
@@ -70,8 +70,15 @@ const ChatbotConversationHistoryNav = (_a) => {
70
70
  return ((0, jsx_runtime_1.jsx)(react_core_1.Menu, Object.assign({ isPlain: true, onSelect: onSelectActiveItem, activeItemId: activeItemId }, menuProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.MenuContent, Object.assign({}, menuContentProps, { children: buildConversations() })) })));
71
71
  };
72
72
  const renderDrawerContent = () => ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(react_core_1.DrawerPanelBody, Object.assign({}, drawerPanelBodyProps, { children: renderMenuContent() })) }));
73
+ const searchInputContainer = handleTextInputChange && ((0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__input", children: [(0, jsx_runtime_1.jsx)(react_core_1.SearchInput, Object.assign({ "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }, searchInputProps)), searchInputScreenReaderText && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__filter-announcement pf-chatbot-m-hidden", children: searchInputScreenReaderText }))] }));
74
+ const renderSearchAndActions = () => {
75
+ if (searchToolbar) {
76
+ return searchToolbar;
77
+ }
78
+ return searchActionStart || searchActionEnd ? ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__history-search-actions", children: (0, jsx_runtime_1.jsxs)(react_core_1.InputGroup, { children: [searchActionStart && (0, jsx_runtime_1.jsx)(react_core_1.InputGroupItem, { children: searchActionStart }), searchInputContainer && (0, jsx_runtime_1.jsx)(react_core_1.InputGroupItem, { isFill: true, children: searchInputContainer }), searchActionEnd && (0, jsx_runtime_1.jsx)(react_core_1.InputGroupItem, { children: searchActionEnd })] }) })) : (searchInputContainer);
79
+ };
73
80
  const renderPanelContent = () => {
74
- const drawer = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.DrawerHead, Object.assign({}, drawerHeadProps, { children: (0, jsx_runtime_1.jsxs)(react_core_1.DrawerActions, Object.assign({ "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' }, drawerActionsProps, { children: [(0, jsx_runtime_1.jsx)(react_core_1.DrawerCloseButton, Object.assign({ onClick: onDrawerToggle }, drawerCloseButtonProps)), onNewChat && ((0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ size: isCompact ? 'sm' : undefined, onClick: onNewChat, icon: (0, jsx_runtime_1.jsx)(react_icons_1.PenToSquareIcon, {}) }, newChatButtonProps, { children: newChatButtonText })))] })) })), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__heading-container", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__title-container", children: [(0, jsx_runtime_1.jsx)(react_core_1.Icon, { size: "lg", className: "pf-chatbot__title-icon", children: navTitleIcon }), (0, jsx_runtime_1.jsx)(react_core_1.Title, Object.assign({ className: "pf-chatbot__title", headingLevel: "h2" }, navTitleProps, { children: title }))] }), !isLoading && handleTextInputChange && ((0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__input", children: [(0, jsx_runtime_1.jsx)(react_core_1.SearchInput, Object.assign({ "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }, searchInputProps)), searchInputScreenReaderText && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__filter-announcement pf-chatbot-m-hidden", children: searchInputScreenReaderText }))] }))] }), isLoading ? (0, jsx_runtime_1.jsx)(LoadingState_1.default, Object.assign({}, loadingState)) : renderDrawerContent()] }));
81
+ const drawer = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.DrawerHead, Object.assign({}, drawerHeadProps, { children: (0, jsx_runtime_1.jsxs)(react_core_1.DrawerActions, Object.assign({ "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' }, drawerActionsProps, { children: [(0, jsx_runtime_1.jsx)(react_core_1.DrawerCloseButton, Object.assign({ onClick: onDrawerToggle }, drawerCloseButtonProps)), onNewChat && ((0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ size: isCompact ? 'sm' : undefined, onClick: onNewChat, icon: (0, jsx_runtime_1.jsx)(react_icons_1.PenToSquareIcon, {}) }, newChatButtonProps, { children: newChatButtonText })))] })) })), hasDrawerHeadDivider && (0, jsx_runtime_1.jsx)(react_core_1.Divider, { className: "pf-chatbot__heading-divider" }), (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__heading-container", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__title-container", children: [(0, jsx_runtime_1.jsx)(react_core_1.Icon, { size: "lg", className: "pf-chatbot__title-icon", children: navTitleIcon }), (0, jsx_runtime_1.jsx)(react_core_1.Title, Object.assign({ className: "pf-chatbot__title", headingLevel: "h2" }, navTitleProps, { children: title }))] }), !isLoading && renderSearchAndActions()] }), isLoading ? (0, jsx_runtime_1.jsx)(LoadingState_1.default, Object.assign({}, loadingState)) : renderDrawerContent()] }));
75
82
  return ((0, jsx_runtime_1.jsx)(react_core_1.DrawerPanelContent, Object.assign({ "aria-live": "polite", focusTrap: { enabled: true }, defaultSize: "384px" }, drawerPanelContentProps, { children: drawer })));
76
83
  };
77
84
  // An onKeyDown property must be passed to the Drawer component to handle closing
@@ -227,6 +227,44 @@ describe('ChatbotConversationHistoryNav', () => {
227
227
  (0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: initialConversations, handleTextInputChange: jest.fn(), searchInputProps: { value: 'I am a sample search' } }));
228
228
  expect(react_1.screen.getByRole('dialog', { name: /Chat history I am a sample search/i })).toBeInTheDocument();
229
229
  });
230
+ it('Does not render search actions by default', () => {
231
+ var _a, _b;
232
+ const handleSearch = jest.fn();
233
+ const groupedConversations = {
234
+ Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
235
+ };
236
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, conversations: groupedConversations, handleTextInputChange: handleSearch }));
237
+ const searchInput = react_1.screen.getByPlaceholderText(/Search/i);
238
+ expect((_a = searchInput.parentElement) === null || _a === void 0 ? void 0 : _a.previousElementSibling).toBeNull();
239
+ expect((_b = searchInput.parentElement) === null || _b === void 0 ? void 0 : _b.nextElementSibling).toBeNull();
240
+ });
241
+ it('Renders with action at start when searchActionStart is passed', () => {
242
+ const handleSearch = jest.fn();
243
+ const groupedConversations = {
244
+ Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
245
+ };
246
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, conversations: groupedConversations, handleTextInputChange: handleSearch, searchActionStart: (0, jsx_runtime_1.jsx)("div", { children: "Search action start test" }) }));
247
+ expect(react_1.screen.getByText('Search action start test')).toBeVisible();
248
+ });
249
+ it('Renders with action at end when searchActionEnd is passed', () => {
250
+ const handleSearch = jest.fn();
251
+ const groupedConversations = {
252
+ Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
253
+ };
254
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, handleTextInputChange: handleSearch, conversations: groupedConversations, searchActionEnd: (0, jsx_runtime_1.jsx)("div", { children: "Search action end test" }) }));
255
+ expect(react_1.screen.getByText('Search action end test')).toBeVisible();
256
+ });
257
+ it('Overrides default search input and actions when searchToolbar is passed', () => {
258
+ const handleSearch = jest.fn();
259
+ const groupedConversations = {
260
+ Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
261
+ };
262
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, conversations: groupedConversations, handleTextInputChange: handleSearch, searchActionStart: (0, jsx_runtime_1.jsx)("div", { children: "Search action start test" }), searchActionEnd: (0, jsx_runtime_1.jsx)("div", { children: "Search action end test" }), searchToolbar: (0, jsx_runtime_1.jsx)("div", { children: "Custom toolbar" }) }));
263
+ expect(react_1.screen.queryByPlaceholderText(/Search/i)).not.toBeInTheDocument();
264
+ expect(react_1.screen.queryByText('Search action start test')).not.toBeInTheDocument();
265
+ expect(react_1.screen.queryByText('Search action end test')).not.toBeInTheDocument();
266
+ expect(react_1.screen.getByText('Custom toolbar')).toBeInTheDocument();
267
+ });
230
268
  it('overrides nav title heading level when navTitleProps.headingLevel is passed', () => {
231
269
  (0, react_1.render)((0, jsx_runtime_1.jsx)(ChatbotConversationHistoryNav_1.default, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: Chatbot_1.ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: { Today: initialConversations }, navTitleProps: { headingLevel: 'h1' } }));
232
270
  expect(react_1.screen.queryByRole('heading', { name: /Chat history/i, level: 2 })).not.toBeInTheDocument();
@@ -21,8 +21,35 @@ const react_core_1 = require("@patternfly/react-core");
21
21
  const bars_icon_1 = __importDefault(require("@patternfly/react-icons/dist/esm/icons/bars-icon"));
22
22
  const ChatbotHeaderMenuBase = (_a) => {
23
23
  var { className, onMenuToggle, tooltipProps, menuAriaLabel = 'Chat history menu', innerRef, tooltipContent = 'Chat history menu', isCompact } = _a, props = __rest(_a, ["className", "onMenuToggle", "tooltipProps", "menuAriaLabel", "innerRef", "tooltipContent", "isCompact"]);
24
- return ((0, jsx_runtime_1.jsx)("div", { className: `pf-chatbot__menu ${className}`, children: (0, jsx_runtime_1.jsx)(react_core_1.Tooltip, Object.assign({ content: tooltipContent, position: "bottom",
24
+ const [isDrawerAnimating, setIsDrawerAnimating] = (0, react_1.useState)(false);
25
+ // I'd like to use a prop here later if this works
26
+ const drawerState = props['aria-expanded'];
27
+ const isDrawerOpen = drawerState === true;
28
+ const prevDrawerStateRef = (0, react_1.useRef)(isDrawerOpen);
29
+ const buttonRef = (0, react_1.useRef)(null);
30
+ (0, react_1.useEffect)(() => {
31
+ if (drawerState !== undefined) {
32
+ const wasDrawerOpen = prevDrawerStateRef.current === true;
33
+ const isDrawerClosing = wasDrawerOpen && !isDrawerOpen;
34
+ setIsDrawerAnimating(true);
35
+ const timeout = setTimeout(() => {
36
+ setIsDrawerAnimating(false);
37
+ if (isDrawerClosing) {
38
+ requestAnimationFrame(() => {
39
+ var _a;
40
+ (_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.focus();
41
+ });
42
+ }
43
+ }, 350);
44
+ prevDrawerStateRef.current = isDrawerOpen;
45
+ return () => clearTimeout(timeout);
46
+ }
47
+ }, [drawerState, isDrawerOpen]);
48
+ const button = (0, react_1.useMemo)(() => ((0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ className: `pf-chatbot__button--toggle-menu ${isCompact ? 'pf-m-compact' : ''}`, variant: "plain", onClick: onMenuToggle, "aria-label": menuAriaLabel, ref: innerRef !== null && innerRef !== void 0 ? innerRef : buttonRef, icon: (0, jsx_runtime_1.jsx)(react_core_1.Icon, { size: isCompact ? 'lg' : 'xl', isInline: true, children: (0, jsx_runtime_1.jsx)(bars_icon_1.default, {}) }), size: isCompact ? 'sm' : undefined }, props))),
49
+ // eslint-disable-next-line react-hooks/exhaustive-deps
50
+ [isCompact, menuAriaLabel, onMenuToggle, innerRef, buttonRef]);
51
+ return ((0, jsx_runtime_1.jsx)("div", { className: `pf-chatbot__menu ${className}`, children: isDrawerAnimating ? (button) : ((0, jsx_runtime_1.jsx)(react_core_1.Tooltip, Object.assign({ content: tooltipContent, position: "bottom",
25
52
  // prevents VO announcements of both aria label and tooltip
26
- aria: "none" }, tooltipProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ className: `pf-chatbot__button--toggle-menu ${isCompact ? 'pf-m-compact' : ''}`, variant: "plain", onClick: onMenuToggle, "aria-label": menuAriaLabel, ref: innerRef, icon: (0, jsx_runtime_1.jsx)(react_core_1.Icon, { size: isCompact ? 'lg' : 'xl', isInline: true, children: (0, jsx_runtime_1.jsx)(bars_icon_1.default, {}) }), size: isCompact ? 'sm' : undefined }, props)) })) }));
53
+ aria: "none" }, tooltipProps, { children: button }))) }));
27
54
  };
28
55
  exports.ChatbotHeaderMenu = (0, react_1.forwardRef)((props, ref) => ((0, jsx_runtime_1.jsx)(ChatbotHeaderMenuBase, Object.assign({ innerRef: ref }, props))));
@@ -37,6 +37,8 @@ export interface CodeModalProps {
37
37
  modalBodyClassName?: string;
38
38
  /** Class applied to modal footer */
39
39
  modalFooterClassName?: string;
40
+ /** Aria label applied to spinner when loading Monaco */
41
+ spinnerAriaLabel?: string;
40
42
  }
41
43
  export declare const CodeModal: FunctionComponent<CodeModalProps>;
42
44
  export default CodeModal;
@@ -22,6 +22,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
25
34
  var __rest = (this && this.__rest) || function (s, e) {
26
35
  var t = {};
27
36
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -41,22 +50,45 @@ exports.CodeModal = void 0;
41
50
  const jsx_runtime_1 = require("react/jsx-runtime");
42
51
  const react_1 = require("react");
43
52
  const path_browserify_1 = __importDefault(require("path-browserify"));
44
- const monaco = __importStar(require("monaco-editor"));
45
- const react_2 = require("@monaco-editor/react");
46
53
  // Import PatternFly components
47
54
  const react_code_editor_1 = require("@patternfly/react-code-editor");
48
55
  const react_core_1 = require("@patternfly/react-core");
49
56
  const FileDetails_1 = __importStar(require("../FileDetails"));
50
57
  const Chatbot_1 = require("../Chatbot");
51
58
  const ChatbotModal_1 = __importDefault(require("../ChatbotModal/ChatbotModal"));
52
- // Configure Monaco loader to use the npm package instead of CDN
53
- react_2.loader.config({ monaco });
59
+ // Try to lazy load - some consumers need to be below a certain bundle size, but can't use the CDN and don't have webpack
60
+ let monacoInstance = null;
61
+ const loadMonaco = () => __awaiter(void 0, void 0, void 0, function* () {
62
+ if (!monacoInstance) {
63
+ const [monaco, { loader }] = yield Promise.all([Promise.resolve().then(() => __importStar(require('monaco-editor'))), Promise.resolve().then(() => __importStar(require('@monaco-editor/react')))]);
64
+ monacoInstance = monaco;
65
+ loader.config({ monaco });
66
+ }
67
+ return monacoInstance;
68
+ });
54
69
  const CodeModal = (_a) => {
55
- var { fileName, code, codeEditorControlClassName: codeEditorClassName, handleModalToggle, isCopyEnabled, isLineNumbersVisible, isModalOpen, isReadOnly, onPrimaryAction, onSecondaryAction, primaryActionBtn, secondaryActionBtn, title, displayMode = Chatbot_1.ChatbotDisplayMode.default, isCompact, modalHeaderClassName, modalBodyClassName, modalFooterClassName } = _a, props = __rest(_a, ["fileName", "code", "codeEditorControlClassName", "handleModalToggle", "isCopyEnabled", "isLineNumbersVisible", "isModalOpen", "isReadOnly", "onPrimaryAction", "onSecondaryAction", "primaryActionBtn", "secondaryActionBtn", "title", "displayMode", "isCompact", "modalHeaderClassName", "modalBodyClassName", "modalFooterClassName"]);
70
+ var { fileName, code, codeEditorControlClassName: codeEditorClassName, handleModalToggle, isCopyEnabled, isLineNumbersVisible, isModalOpen, isReadOnly, onPrimaryAction, onSecondaryAction, primaryActionBtn, secondaryActionBtn, title, displayMode = Chatbot_1.ChatbotDisplayMode.default, isCompact, modalHeaderClassName, modalBodyClassName, modalFooterClassName, spinnerAriaLabel = 'Loading' } = _a, props = __rest(_a, ["fileName", "code", "codeEditorControlClassName", "handleModalToggle", "isCopyEnabled", "isLineNumbersVisible", "isModalOpen", "isReadOnly", "onPrimaryAction", "onSecondaryAction", "primaryActionBtn", "secondaryActionBtn", "title", "displayMode", "isCompact", "modalHeaderClassName", "modalBodyClassName", "modalFooterClassName", "spinnerAriaLabel"]);
56
71
  const [newCode, setNewCode] = (0, react_1.useState)(code);
57
72
  const [editorInstance, setEditorInstance] = (0, react_1.useState)(null);
58
73
  const [isEditorReady, setIsEditorReady] = (0, react_1.useState)(false);
74
+ const [isMonacoLoading, setIsMonacoLoading] = (0, react_1.useState)(false);
75
+ const [isMonacoLoaded, setIsMonacoLoaded] = (0, react_1.useState)(false);
59
76
  const containerRef = (0, react_1.useRef)(null);
77
+ (0, react_1.useEffect)(() => {
78
+ if (isModalOpen && !isMonacoLoaded && !isMonacoLoading) {
79
+ setIsMonacoLoading(true);
80
+ loadMonaco()
81
+ .then(() => {
82
+ setIsMonacoLoaded(true);
83
+ setIsMonacoLoading(false);
84
+ })
85
+ .catch((error) => {
86
+ // eslint-disable-next-line no-console
87
+ console.error('Failed to load Monaco editor:', error);
88
+ setIsMonacoLoading(false);
89
+ });
90
+ }
91
+ }, [isModalOpen, isMonacoLoaded, isMonacoLoading]);
60
92
  (0, react_1.useEffect)(() => {
61
93
  if (!isModalOpen || !isEditorReady || !editorInstance || !containerRef.current) {
62
94
  return;
@@ -106,13 +138,22 @@ const CodeModal = (_a) => {
106
138
  setNewCode(value);
107
139
  }
108
140
  };
109
- const modal = ((0, jsx_runtime_1.jsxs)(ChatbotModal_1.default, { isOpen: isModalOpen, onClose: handleModalToggle, ouiaId: "CodeModal", "aria-labelledby": "code-modal-title", "aria-describedby": "code-modal", className: `pf-chatbot__code-modal ${isCompact ? 'pf-m-compact' : ''} pf-chatbot__code-modal--${displayMode}`, displayMode: displayMode, isCompact: isCompact, children: [(0, jsx_runtime_1.jsx)(react_core_1.ModalHeader, { className: modalHeaderClassName, title: title, labelId: "code-modal-title" }), (0, jsx_runtime_1.jsx)(react_core_1.ModalBody, { className: modalBodyClassName, id: "code-modal-body", children: (0, jsx_runtime_1.jsxs)(react_core_1.Stack, { className: "pf-chatbot__code-modal-body", children: [(0, jsx_runtime_1.jsx)(react_core_1.StackItem, { className: "pf-chatbot__code-modal-file-details", children: (0, jsx_runtime_1.jsx)(FileDetails_1.default, { fileName: fileName }) }), (0, jsx_runtime_1.jsx)("div", { className: "pf-v6-l-stack__item pf-chatbot__code-modal-editor", ref: containerRef, children: (0, jsx_runtime_1.jsx)(react_code_editor_1.CodeEditor, Object.assign({ isDarkTheme: true, isLineNumbersVisible: isLineNumbersVisible, isLanguageLabelVisible: true, isCopyEnabled: isCopyEnabled, isReadOnly: isReadOnly, code: newCode, language: FileDetails_1.extensionToLanguage[path_browserify_1.default.extname(fileName).slice(1)], onEditorDidMount: onEditorDidMount, onCodeChange: onCodeChange, className: codeEditorClassName, isFullHeight: true, options: {
110
- glyphMargin: false,
111
- folding: false,
112
- // prevents Monaco from handling resizing itself
113
- // was causing ResizeObserver issues
114
- automaticLayout: false
115
- } }, props)) })] }) }), (0, jsx_runtime_1.jsxs)(react_core_1.ModalFooter, { className: modalFooterClassName, children: [(0, jsx_runtime_1.jsx)(react_core_1.Button, { isBlock: true, variant: "primary", onClick: handlePrimaryAction, form: "code-modal-form", children: primaryActionBtn }, "code-modal-primary"), (0, jsx_runtime_1.jsx)(react_core_1.Button, { isBlock: true, variant: "link", onClick: handleSecondaryAction, children: secondaryActionBtn }, "code-modal-secondary")] })] }));
141
+ const renderMonacoEditor = () => {
142
+ if (isMonacoLoading) {
143
+ return ((0, jsx_runtime_1.jsx)(react_core_1.Bullseye, { children: (0, jsx_runtime_1.jsx)(react_core_1.Spinner, { "aria-label": spinnerAriaLabel }) }));
144
+ }
145
+ if (isMonacoLoaded) {
146
+ return ((0, jsx_runtime_1.jsx)(react_code_editor_1.CodeEditor, Object.assign({ isDarkTheme: true, isLineNumbersVisible: isLineNumbersVisible, isLanguageLabelVisible: true, isCopyEnabled: isCopyEnabled, isReadOnly: isReadOnly, code: newCode, language: FileDetails_1.extensionToLanguage[path_browserify_1.default.extname(fileName).slice(1)], onEditorDidMount: onEditorDidMount, onCodeChange: onCodeChange, className: codeEditorClassName, isFullHeight: true, options: {
147
+ glyphMargin: false,
148
+ folding: false,
149
+ // prevents Monaco from handling resizing itself
150
+ // was causing ResizeObserver issues
151
+ automaticLayout: false
152
+ } }, props)));
153
+ }
154
+ return null;
155
+ };
156
+ const modal = ((0, jsx_runtime_1.jsxs)(ChatbotModal_1.default, { isOpen: isModalOpen, onClose: handleModalToggle, ouiaId: "CodeModal", "aria-labelledby": "code-modal-title", "aria-describedby": "code-modal", className: `pf-chatbot__code-modal ${isCompact ? 'pf-m-compact' : ''} pf-chatbot__code-modal--${displayMode}`, displayMode: displayMode, isCompact: isCompact, children: [(0, jsx_runtime_1.jsx)(react_core_1.ModalHeader, { className: modalHeaderClassName, title: title, labelId: "code-modal-title" }), (0, jsx_runtime_1.jsx)(react_core_1.ModalBody, { className: modalBodyClassName, id: "code-modal-body", children: (0, jsx_runtime_1.jsxs)(react_core_1.Stack, { className: "pf-chatbot__code-modal-body", children: [(0, jsx_runtime_1.jsx)(react_core_1.StackItem, { className: "pf-chatbot__code-modal-file-details", children: (0, jsx_runtime_1.jsx)(FileDetails_1.default, { fileName: fileName }) }), (0, jsx_runtime_1.jsx)("div", { className: "pf-v6-l-stack__item pf-chatbot__code-modal-editor", ref: containerRef, children: renderMonacoEditor() })] }) }), (0, jsx_runtime_1.jsxs)(react_core_1.ModalFooter, { className: modalFooterClassName, children: [(0, jsx_runtime_1.jsx)(react_core_1.Button, { isBlock: true, variant: "primary", onClick: handlePrimaryAction, form: "code-modal-form", children: primaryActionBtn }, "code-modal-primary"), (0, jsx_runtime_1.jsx)(react_core_1.Button, { isBlock: true, variant: "link", onClick: handleSecondaryAction, children: secondaryActionBtn }, "code-modal-secondary")] })] }));
116
157
  return modal;
117
158
  };
118
159
  exports.CodeModal = CodeModal;
@@ -1,8 +1,11 @@
1
1
  import { CardBodyProps, CardProps, ExpandableSectionProps } from '@patternfly/react-core';
2
2
  import { type FunctionComponent } from 'react';
3
+ import type { MarkdownContentProps } from '../MarkdownContent';
3
4
  export interface DeepThinkingProps {
4
5
  /** Toggle content shown for expandable section */
5
6
  toggleContent: React.ReactNode;
7
+ /** Flag indicating whether the expandable content is expanded by default. */
8
+ isDefaultExpanded?: boolean;
6
9
  /** Additional props passed to expandable section */
7
10
  expandableSectionProps?: Omit<ExpandableSectionProps, 'ref'>;
8
11
  /** Subheading rendered inside expandable section */
@@ -13,6 +16,16 @@ export interface DeepThinkingProps {
13
16
  cardProps?: CardProps;
14
17
  /** Additional props passed to main card body */
15
18
  cardBodyProps?: CardBodyProps;
19
+ /** Whether to enable markdown rendering for toggleContent. When true and toggleContent is a string, it will be parsed as markdown. */
20
+ isToggleContentMarkdown?: boolean;
21
+ /** Whether to enable markdown rendering for subheading. When true, subheading will be parsed as markdown. */
22
+ isSubheadingMarkdown?: boolean;
23
+ /** Whether to enable markdown rendering for body. When true and body is a string, it will be parsed as markdown. */
24
+ isBodyMarkdown?: boolean;
25
+ /** Props passed to MarkdownContent component when markdown is enabled */
26
+ markdownContentProps?: Omit<MarkdownContentProps, 'content'>;
27
+ /** Whether to retain styles in the MarkdownContent component. Defaults to false. */
28
+ shouldRetainStyles?: boolean;
16
29
  }
17
30
  export declare const DeepThinking: FunctionComponent<DeepThinkingProps>;
18
31
  export default DeepThinking;
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.DeepThinking = void 0;
4
7
  const jsx_runtime_1 = require("react/jsx-runtime");
@@ -7,12 +10,37 @@ const jsx_runtime_1 = require("react/jsx-runtime");
7
10
  // ============================================================================
8
11
  const react_core_1 = require("@patternfly/react-core");
9
12
  const react_1 = require("react");
10
- const DeepThinking = ({ body, cardProps, expandableSectionProps, subheading, toggleContent, cardBodyProps }) => {
11
- const [isExpanded, setIsExpanded] = (0, react_1.useState)(true);
13
+ const MarkdownContent_1 = __importDefault(require("../MarkdownContent"));
14
+ const DeepThinking = ({ body, cardProps, expandableSectionProps, subheading, toggleContent, isDefaultExpanded = true, cardBodyProps, isToggleContentMarkdown, isSubheadingMarkdown, isBodyMarkdown, markdownContentProps, shouldRetainStyles = false }) => {
15
+ const [isExpanded, setIsExpanded] = (0, react_1.useState)(isDefaultExpanded);
12
16
  const onToggle = (_event, isExpanded) => {
13
17
  setIsExpanded(isExpanded);
14
18
  };
15
- return ((0, jsx_runtime_1.jsx)(react_core_1.Card, Object.assign({ isCompact: true, className: "pf-chatbot__deep-thinking" }, cardProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.CardBody, Object.assign({}, cardBodyProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.ExpandableSection, Object.assign({ toggleContent: toggleContent, onToggle: onToggle, isExpanded: isExpanded, isIndented: true, className: "pf-chatbot__deep-thinking-expandable-section" }, expandableSectionProps, { children: (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__deep-thinking-section", children: [subheading && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__deep-thinking-subheading", children: (0, jsx_runtime_1.jsx)("span", { children: subheading }) })), body && (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__deep-thinking-body", children: body })] }) })) })) })));
19
+ const renderToggleContent = () => {
20
+ if (isToggleContentMarkdown && typeof toggleContent === 'string') {
21
+ return ((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, content: toggleContent }, markdownContentProps)));
22
+ }
23
+ return toggleContent;
24
+ };
25
+ const renderSubheading = () => {
26
+ if (!subheading) {
27
+ return null;
28
+ }
29
+ if (isSubheadingMarkdown) {
30
+ return (0, jsx_runtime_1.jsx)(MarkdownContent_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, content: subheading }, markdownContentProps));
31
+ }
32
+ return subheading;
33
+ };
34
+ const renderBody = () => {
35
+ if (!body) {
36
+ return null;
37
+ }
38
+ if (isBodyMarkdown && typeof body === 'string') {
39
+ return (0, jsx_runtime_1.jsx)(MarkdownContent_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, content: body }, markdownContentProps));
40
+ }
41
+ return body;
42
+ };
43
+ return ((0, jsx_runtime_1.jsx)(react_core_1.Card, Object.assign({ isCompact: true, className: "pf-chatbot__deep-thinking" }, cardProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.CardBody, Object.assign({}, cardBodyProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.ExpandableSection, Object.assign({ toggleContent: renderToggleContent(), onToggle: onToggle, isExpanded: isExpanded, isIndented: true, className: "pf-chatbot__deep-thinking-expandable-section" }, expandableSectionProps, { children: (0, jsx_runtime_1.jsxs)("div", { className: "pf-chatbot__deep-thinking-section", children: [subheading && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__deep-thinking-subheading", children: (0, jsx_runtime_1.jsx)("span", { children: renderSubheading() }) })), body && (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__deep-thinking-body", children: renderBody() })] }) })) })) })));
16
44
  };
17
45
  exports.DeepThinking = DeepThinking;
18
46
  exports.default = exports.DeepThinking;
@@ -1,10 +1,20 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
5
14
  Object.defineProperty(exports, "__esModule", { value: true });
6
15
  const jsx_runtime_1 = require("react/jsx-runtime");
7
16
  const react_1 = require("@testing-library/react");
17
+ const user_event_1 = __importDefault(require("@testing-library/user-event"));
8
18
  require("@testing-library/jest-dom");
9
19
  const DeepThinking_1 = __importDefault(require("./DeepThinking"));
10
20
  describe('DeepThinking', () => {
@@ -45,4 +55,74 @@ describe('DeepThinking', () => {
45
55
  const subheadingContainer = container.querySelector('.pf-chatbot__tool-response-subheading');
46
56
  expect(subheadingContainer).toBeFalsy();
47
57
  });
58
+ it('should pass through cardBodyProps', () => {
59
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, defaultProps, { body: "Thinking content", cardBodyProps: { className: 'custom-card-body-class' } })));
60
+ const cardBody = react_1.screen.getByText('Thinking content').closest('.pf-v6-c-card__body');
61
+ expect(cardBody).toHaveClass('custom-card-body-class');
62
+ });
63
+ it('Renders expanded by default', () => {
64
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, defaultProps, { body: "Thinking content" })));
65
+ expect(react_1.screen.getByRole('button', { name: defaultProps.toggleContent })).toHaveAttribute('aria-expanded', 'true');
66
+ expect(react_1.screen.getByText('Thinking content')).toBeVisible();
67
+ });
68
+ it('Renders collapsed when isDefaultExpanded is false', () => {
69
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({ isDefaultExpanded: false }, defaultProps, { body: "Thinking content" })));
70
+ expect(react_1.screen.getByRole('button', { name: defaultProps.toggleContent })).toHaveAttribute('aria-expanded', 'false');
71
+ expect(react_1.screen.getByText('Thinking content')).not.toBeVisible();
72
+ });
73
+ it('expandableSectionProps.isExpanded overrides isDefaultExpanded', () => {
74
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, defaultProps, { isDefaultExpanded: false, body: "Thinking content", expandableSectionProps: { isExpanded: true } })));
75
+ expect(react_1.screen.getByRole('button', { name: defaultProps.toggleContent })).toHaveAttribute('aria-expanded', 'true');
76
+ expect(react_1.screen.getByText('Thinking content')).toBeVisible();
77
+ });
78
+ it('expandableSectionProps.onToggle overrides internal onToggle behavior', () => __awaiter(void 0, void 0, void 0, function* () {
79
+ const user = user_event_1.default.setup();
80
+ const customOnToggle = jest.fn();
81
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, defaultProps, { isDefaultExpanded: false, body: "Thinking content", expandableSectionProps: { onToggle: customOnToggle } })));
82
+ const toggleButton = react_1.screen.getByRole('button', { name: defaultProps.toggleContent });
83
+ expect(toggleButton).toHaveAttribute('aria-expanded', 'false');
84
+ yield user.click(toggleButton);
85
+ expect(customOnToggle).toHaveBeenCalled();
86
+ expect(toggleButton).toHaveAttribute('aria-expanded', 'false');
87
+ expect(react_1.screen.getByText('Thinking content')).not.toBeVisible();
88
+ }));
89
+ it('should render toggleContent as markdown when isToggleContentMarkdown is true', () => {
90
+ const toggleContent = '**Bold thinking**';
91
+ const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, { toggleContent: toggleContent, isToggleContentMarkdown: true }));
92
+ expect(container.querySelector('strong')).toBeTruthy();
93
+ expect(react_1.screen.getByText('Bold thinking')).toBeTruthy();
94
+ });
95
+ it('should not render toggleContent as markdown when isToggleContentMarkdown is false', () => {
96
+ const toggleContent = '**Bold thinking**';
97
+ const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, { toggleContent: toggleContent }));
98
+ expect(container.querySelector('strong')).toBeFalsy();
99
+ expect(react_1.screen.getByText('**Bold thinking**')).toBeTruthy();
100
+ });
101
+ it('should render subheading as markdown when isSubheadingMarkdown is true', () => {
102
+ const subheading = '**Bold subheading**';
103
+ const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, defaultProps, { subheading: subheading, isSubheadingMarkdown: true })));
104
+ expect(container.querySelector('strong')).toBeTruthy();
105
+ expect(react_1.screen.getByText('Bold subheading')).toBeTruthy();
106
+ });
107
+ it('should not render subheading as markdown when isSubheadingMarkdown is false', () => {
108
+ const subheading = '**Bold subheading**';
109
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, defaultProps, { subheading: subheading })));
110
+ expect(react_1.screen.getByText('**Bold subheading**')).toBeTruthy();
111
+ });
112
+ it('should render body as markdown when isBodyMarkdown is true', () => {
113
+ const body = '**Bold body**';
114
+ const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, defaultProps, { body: body, isBodyMarkdown: true })));
115
+ expect(container.querySelector('strong')).toBeTruthy();
116
+ expect(react_1.screen.getByText('Bold body')).toBeTruthy();
117
+ });
118
+ it('should not render body as markdown when isBodyMarkdown is false', () => {
119
+ const body = '**Bold body**';
120
+ (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, defaultProps, { body: body })));
121
+ expect(react_1.screen.getByText('**Bold body**')).toBeTruthy();
122
+ });
123
+ it('should pass markdownContentProps to MarkdownContent component', () => {
124
+ const body = '**Bold body**';
125
+ const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(DeepThinking_1.default, Object.assign({}, defaultProps, { body: body, isBodyMarkdown: true, markdownContentProps: { isPrimary: true } })));
126
+ expect(container.querySelector('.pf-m-primary')).toBeTruthy();
127
+ });
48
128
  });
@@ -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;