@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.
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +9 -1
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +9 -2
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +38 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +29 -2
- package/dist/cjs/CodeModal/CodeModal.d.ts +2 -0
- package/dist/cjs/CodeModal/CodeModal.js +53 -12
- package/dist/cjs/DeepThinking/DeepThinking.d.ts +13 -0
- package/dist/cjs/DeepThinking/DeepThinking.js +31 -3
- package/dist/cjs/DeepThinking/DeepThinking.test.js +80 -0
- package/dist/cjs/MarkdownContent/MarkdownContent.d.ts +44 -0
- package/dist/cjs/MarkdownContent/MarkdownContent.js +181 -0
- package/dist/cjs/MarkdownContent/MarkdownContent.test.d.ts +1 -0
- package/dist/cjs/MarkdownContent/MarkdownContent.test.js +192 -0
- package/dist/cjs/MarkdownContent/index.d.ts +2 -0
- package/dist/cjs/MarkdownContent/index.js +23 -0
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.d.ts +3 -1
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +15 -4
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.test.d.ts +1 -0
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.test.js +131 -0
- package/dist/cjs/Message/ErrorMessage/ErrorMessage.d.ts +15 -1
- package/dist/cjs/Message/ErrorMessage/ErrorMessage.js +5 -3
- package/dist/cjs/Message/ErrorMessage/ErrorMessage.test.d.ts +1 -0
- package/dist/cjs/Message/ErrorMessage/ErrorMessage.test.js +30 -0
- package/dist/cjs/Message/LinkMessage/LinkMessage.d.ts +5 -1
- package/dist/cjs/Message/LinkMessage/LinkMessage.js +4 -3
- package/dist/cjs/Message/ListMessage/OrderedListMessage.d.ts +9 -1
- package/dist/cjs/Message/ListMessage/OrderedListMessage.js +2 -1
- package/dist/cjs/Message/ListMessage/UnorderedListMessage.d.ts +7 -1
- package/dist/cjs/Message/ListMessage/UnorderedListMessage.js +2 -1
- package/dist/cjs/Message/Message.d.ts +20 -3
- package/dist/cjs/Message/Message.js +7 -160
- package/dist/cjs/Message/Message.test.js +129 -2
- package/dist/cjs/Message/MessageAndActions/MessageAndActions.d.ts +14 -0
- package/dist/cjs/Message/MessageAndActions/MessageAndActions.js +22 -0
- package/dist/cjs/Message/MessageAndActions/MessageAndActions.test.d.ts +1 -0
- package/dist/cjs/Message/MessageAndActions/MessageAndActions.test.js +25 -0
- package/dist/cjs/Message/MessageAndActions/index.d.ts +1 -0
- package/dist/cjs/Message/MessageAndActions/index.js +17 -0
- package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.d.ts +13 -0
- package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.js +22 -0
- package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.test.d.ts +1 -0
- package/dist/cjs/Message/MessageAttachments/MessageAttachmentItem.test.js +25 -0
- package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.d.ts +13 -0
- package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.js +22 -0
- package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.test.d.ts +1 -0
- package/dist/cjs/Message/MessageAttachments/MessageAttachmentsContainer.test.js +25 -0
- package/dist/cjs/Message/MessageAttachments/index.d.ts +2 -0
- package/dist/cjs/Message/MessageAttachments/index.js +18 -0
- package/dist/cjs/Message/MessageInput.d.ts +1 -1
- package/dist/cjs/Message/MessageInput.js +3 -1
- package/dist/cjs/Message/MessageLoading.d.ts +13 -4
- package/dist/cjs/Message/MessageLoading.js +19 -5
- package/dist/cjs/Message/MessageLoading.test.d.ts +1 -0
- package/dist/cjs/Message/MessageLoading.test.js +25 -0
- package/dist/cjs/Message/QuickResponse/QuickResponse.js +3 -2
- package/dist/cjs/Message/QuickResponse/QuickResponse.test.d.ts +1 -0
- package/dist/cjs/Message/QuickResponse/QuickResponse.test.js +109 -0
- package/dist/cjs/Message/QuickResponse/index.d.ts +1 -0
- package/dist/cjs/Message/QuickResponse/index.js +17 -0
- package/dist/cjs/Message/QuickStarts/QuickStartTile.d.ts +1 -1
- package/dist/cjs/Message/QuickStarts/QuickStartTile.js +3 -2
- package/dist/cjs/Message/QuickStarts/index.d.ts +2 -0
- package/dist/cjs/Message/QuickStarts/index.js +18 -0
- package/dist/cjs/Message/TableMessage/TableMessage.d.ts +6 -1
- package/dist/cjs/Message/TableMessage/TableMessage.js +3 -2
- package/dist/cjs/Message/TextMessage/TextMessage.d.ts +8 -1
- package/dist/cjs/Message/TextMessage/TextMessage.js +3 -2
- package/dist/cjs/Message/UserFeedback/UserFeedback.d.ts +3 -1
- package/dist/cjs/Message/UserFeedback/UserFeedback.js +8 -6
- package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.d.ts +1 -1
- package/dist/cjs/Message/UserFeedback/UserFeedbackComplete.js +3 -2
- package/dist/cjs/Message/UserFeedback/index.d.ts +2 -0
- package/dist/cjs/Message/UserFeedback/index.js +18 -0
- package/dist/cjs/Message/index.d.ts +8 -0
- package/dist/cjs/Message/index.js +8 -0
- package/dist/cjs/MessageBar/MessageBar.d.ts +10 -0
- package/dist/cjs/MessageBar/MessageBar.js +42 -10
- package/dist/cjs/MessageBar/MessageBar.test.js +20 -0
- package/dist/cjs/Onboarding/Onboarding.d.ts +36 -0
- package/dist/cjs/Onboarding/Onboarding.js +37 -0
- package/dist/cjs/Onboarding/Onboarding.test.d.ts +1 -0
- package/dist/cjs/Onboarding/Onboarding.test.js +80 -0
- package/dist/cjs/Onboarding/index.d.ts +2 -0
- package/dist/cjs/Onboarding/index.js +23 -0
- package/dist/cjs/ResponseActions/ResponseActions.d.ts +7 -0
- package/dist/cjs/ResponseActions/ResponseActions.js +28 -7
- package/dist/cjs/ResponseActions/ResponseActions.test.js +67 -12
- package/dist/cjs/ResponseActions/ResponseActionsGroups.d.ts +13 -0
- package/dist/cjs/ResponseActions/ResponseActionsGroups.js +22 -0
- package/dist/cjs/ResponseActions/ResponseActionsGroups.test.d.ts +1 -0
- package/dist/cjs/ResponseActions/ResponseActionsGroups.test.js +25 -0
- package/dist/cjs/ResponseActions/index.d.ts +1 -0
- package/dist/cjs/ResponseActions/index.js +1 -0
- package/dist/cjs/ToolCall/ToolCall.d.ts +11 -0
- package/dist/cjs/ToolCall/ToolCall.js +24 -3
- package/dist/cjs/ToolCall/ToolCall.test.js +57 -0
- package/dist/cjs/ToolResponse/ToolResponse.d.ts +17 -0
- package/dist/cjs/ToolResponse/ToolResponse.js +49 -3
- package/dist/cjs/ToolResponse/ToolResponse.test.js +100 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +7 -1
- package/dist/css/main.css +276 -30
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/MarkdownContent/package.json +1 -0
- package/dist/dynamic/Onboarding/package.json +1 -0
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +9 -1
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +10 -3
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +38 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +30 -3
- package/dist/esm/CodeModal/CodeModal.d.ts +2 -0
- package/dist/esm/CodeModal/CodeModal.js +54 -13
- package/dist/esm/DeepThinking/DeepThinking.d.ts +13 -0
- package/dist/esm/DeepThinking/DeepThinking.js +28 -3
- package/dist/esm/DeepThinking/DeepThinking.test.js +80 -0
- package/dist/esm/MarkdownContent/MarkdownContent.d.ts +44 -0
- package/dist/esm/MarkdownContent/MarkdownContent.js +174 -0
- package/dist/esm/MarkdownContent/MarkdownContent.test.d.ts +1 -0
- package/dist/esm/MarkdownContent/MarkdownContent.test.js +187 -0
- package/dist/esm/MarkdownContent/index.d.ts +2 -0
- package/dist/esm/MarkdownContent/index.js +2 -0
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.d.ts +3 -1
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +15 -4
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.test.d.ts +1 -0
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.test.js +126 -0
- package/dist/esm/Message/ErrorMessage/ErrorMessage.d.ts +15 -1
- package/dist/esm/Message/ErrorMessage/ErrorMessage.js +3 -3
- package/dist/esm/Message/ErrorMessage/ErrorMessage.test.d.ts +1 -0
- package/dist/esm/Message/ErrorMessage/ErrorMessage.test.js +25 -0
- package/dist/esm/Message/LinkMessage/LinkMessage.d.ts +5 -1
- package/dist/esm/Message/LinkMessage/LinkMessage.js +4 -3
- package/dist/esm/Message/ListMessage/OrderedListMessage.d.ts +9 -1
- package/dist/esm/Message/ListMessage/OrderedListMessage.js +2 -1
- package/dist/esm/Message/ListMessage/UnorderedListMessage.d.ts +7 -1
- package/dist/esm/Message/ListMessage/UnorderedListMessage.js +2 -1
- package/dist/esm/Message/Message.d.ts +20 -3
- package/dist/esm/Message/Message.js +8 -161
- package/dist/esm/Message/Message.test.js +129 -2
- package/dist/esm/Message/MessageAndActions/MessageAndActions.d.ts +14 -0
- package/dist/esm/Message/MessageAndActions/MessageAndActions.js +18 -0
- package/dist/esm/Message/MessageAndActions/MessageAndActions.test.d.ts +1 -0
- package/dist/esm/Message/MessageAndActions/MessageAndActions.test.js +20 -0
- package/dist/esm/Message/MessageAndActions/index.d.ts +1 -0
- package/dist/esm/Message/MessageAndActions/index.js +1 -0
- package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.d.ts +13 -0
- package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.js +18 -0
- package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.test.d.ts +1 -0
- package/dist/esm/Message/MessageAttachments/MessageAttachmentItem.test.js +20 -0
- package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.d.ts +13 -0
- package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.js +18 -0
- package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.test.d.ts +1 -0
- package/dist/esm/Message/MessageAttachments/MessageAttachmentsContainer.test.js +20 -0
- package/dist/esm/Message/MessageAttachments/index.d.ts +2 -0
- package/dist/esm/Message/MessageAttachments/index.js +2 -0
- package/dist/esm/Message/MessageInput.d.ts +1 -1
- package/dist/esm/Message/MessageInput.js +1 -1
- package/dist/esm/Message/MessageLoading.d.ts +13 -4
- package/dist/esm/Message/MessageLoading.js +16 -4
- package/dist/esm/Message/MessageLoading.test.d.ts +1 -0
- package/dist/esm/Message/MessageLoading.test.js +20 -0
- package/dist/esm/Message/QuickResponse/QuickResponse.js +3 -2
- package/dist/esm/Message/QuickResponse/QuickResponse.test.d.ts +1 -0
- package/dist/esm/Message/QuickResponse/QuickResponse.test.js +104 -0
- package/dist/esm/Message/QuickResponse/index.d.ts +1 -0
- package/dist/esm/Message/QuickResponse/index.js +1 -0
- package/dist/esm/Message/QuickStarts/QuickStartTile.d.ts +1 -1
- package/dist/esm/Message/QuickStarts/QuickStartTile.js +1 -1
- package/dist/esm/Message/QuickStarts/index.d.ts +2 -0
- package/dist/esm/Message/QuickStarts/index.js +2 -0
- package/dist/esm/Message/TableMessage/TableMessage.d.ts +6 -1
- package/dist/esm/Message/TableMessage/TableMessage.js +3 -2
- package/dist/esm/Message/TextMessage/TextMessage.d.ts +8 -1
- package/dist/esm/Message/TextMessage/TextMessage.js +3 -2
- package/dist/esm/Message/UserFeedback/UserFeedback.d.ts +3 -1
- package/dist/esm/Message/UserFeedback/UserFeedback.js +7 -7
- package/dist/esm/Message/UserFeedback/UserFeedbackComplete.d.ts +1 -1
- package/dist/esm/Message/UserFeedback/UserFeedbackComplete.js +1 -2
- package/dist/esm/Message/UserFeedback/index.d.ts +2 -0
- package/dist/esm/Message/UserFeedback/index.js +2 -0
- package/dist/esm/Message/index.d.ts +8 -0
- package/dist/esm/Message/index.js +8 -0
- package/dist/esm/MessageBar/MessageBar.d.ts +10 -0
- package/dist/esm/MessageBar/MessageBar.js +42 -10
- package/dist/esm/MessageBar/MessageBar.test.js +20 -0
- package/dist/esm/Onboarding/Onboarding.d.ts +36 -0
- package/dist/esm/Onboarding/Onboarding.js +30 -0
- package/dist/esm/Onboarding/Onboarding.test.d.ts +1 -0
- package/dist/esm/Onboarding/Onboarding.test.js +75 -0
- package/dist/esm/Onboarding/index.d.ts +2 -0
- package/dist/esm/Onboarding/index.js +2 -0
- package/dist/esm/ResponseActions/ResponseActions.d.ts +7 -0
- package/dist/esm/ResponseActions/ResponseActions.js +28 -7
- package/dist/esm/ResponseActions/ResponseActions.test.js +67 -12
- package/dist/esm/ResponseActions/ResponseActionsGroups.d.ts +13 -0
- package/dist/esm/ResponseActions/ResponseActionsGroups.js +18 -0
- package/dist/esm/ResponseActions/ResponseActionsGroups.test.d.ts +1 -0
- package/dist/esm/ResponseActions/ResponseActionsGroups.test.js +20 -0
- package/dist/esm/ResponseActions/index.d.ts +1 -0
- package/dist/esm/ResponseActions/index.js +1 -0
- package/dist/esm/ToolCall/ToolCall.d.ts +11 -0
- package/dist/esm/ToolCall/ToolCall.js +21 -3
- package/dist/esm/ToolCall/ToolCall.test.js +57 -0
- package/dist/esm/ToolResponse/ToolResponse.d.ts +17 -0
- package/dist/esm/ToolResponse/ToolResponse.js +46 -3
- package/dist/esm/ToolResponse/ToolResponse.test.js +100 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -3
- package/patternfly-docs/content/extensions/chatbot/chatbot.md +57 -0
- package/patternfly-docs/content/extensions/chatbot/design-guidelines.md +12 -12
- package/patternfly-docs/content/extensions/chatbot/examples/Analytics/Analytics.md +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Customizing Messages/Customizing Messages.md +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +1 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithCustomStructure.tsx +102 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithDeepThinking.tsx +25 -11
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithFeedback.tsx +14 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMarkdownDeepThinking.tsx +26 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMarkdownToolCall.tsx +29 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMarkdownToolResponse.tsx +200 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithMultipleActionGroups.tsx +61 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithPersistedActions.tsx +22 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickResponses.tsx +11 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithToolCall.tsx +14 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithToolResponse.tsx +222 -105
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +123 -14
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +1 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithSearchActions.tsx +198 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarCustomActions.tsx +190 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarIndicatorThinking.tsx +15 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/CompactOnboarding.tsx +141 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/Onboarding.tsx +151 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/RH-Hat-Image.svg +9 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +81 -30
- package/patternfly-docs/content/extensions/chatbot/examples/demos/AttachmentDemos.md +18 -18
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +33 -19
- package/patternfly-docs/patternfly-docs.config.js +1 -1
- package/patternfly-docs/patternfly-docs.source.js +1 -1
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +43 -0
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +95 -0
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +51 -15
- package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +56 -14
- package/src/ChatbotModal/ChatbotModal.scss +3 -0
- package/src/CodeModal/CodeModal.tsx +71 -26
- package/src/DeepThinking/DeepThinking.scss +1 -1
- package/src/DeepThinking/DeepThinking.test.tsx +109 -0
- package/src/DeepThinking/DeepThinking.tsx +54 -5
- package/src/MarkdownContent/MarkdownContent.test.tsx +207 -0
- package/src/MarkdownContent/MarkdownContent.tsx +269 -0
- package/src/MarkdownContent/index.ts +2 -0
- package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +13 -0
- package/src/Message/CodeBlockMessage/CodeBlockMessage.test.tsx +171 -0
- package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +17 -4
- package/src/Message/ErrorMessage/ErrorMessage.test.tsx +38 -0
- package/src/Message/ErrorMessage/ErrorMessage.tsx +17 -2
- package/src/Message/LinkMessage/LinkMessage.scss +5 -0
- package/src/Message/LinkMessage/LinkMessage.tsx +24 -2
- package/src/Message/ListMessage/ListMessage.scss +8 -0
- package/src/Message/ListMessage/OrderedListMessage.tsx +16 -2
- package/src/Message/ListMessage/UnorderedListMessage.tsx +12 -2
- package/src/Message/Message.scss +11 -7
- package/src/Message/Message.test.tsx +202 -2
- package/src/Message/Message.tsx +129 -241
- package/src/Message/MessageAndActions/MessageAndActions.test.tsx +23 -0
- package/src/Message/MessageAndActions/MessageAndActions.tsx +22 -0
- package/src/Message/MessageAndActions/index.ts +1 -0
- package/src/Message/MessageAttachments/MessageAttachmentItem.test.tsx +23 -0
- package/src/Message/MessageAttachments/MessageAttachmentItem.tsx +25 -0
- package/src/Message/MessageAttachments/MessageAttachmentsContainer.test.tsx +23 -0
- package/src/Message/MessageAttachments/MessageAttachmentsContainer.tsx +25 -0
- package/src/Message/MessageAttachments/index.ts +2 -0
- package/src/Message/MessageInput.tsx +1 -1
- package/src/Message/MessageLoading.test.tsx +23 -0
- package/src/Message/MessageLoading.tsx +17 -2
- package/src/Message/QuickResponse/QuickResponse.scss +3 -1
- package/src/Message/QuickResponse/QuickResponse.test.tsx +131 -0
- package/src/Message/QuickResponse/QuickResponse.tsx +3 -2
- package/src/Message/QuickResponse/index.ts +1 -0
- package/src/Message/QuickStarts/QuickStartTile.tsx +1 -1
- package/src/Message/QuickStarts/index.ts +2 -0
- package/src/Message/TableMessage/TableMessage.scss +13 -1
- package/src/Message/TableMessage/TableMessage.tsx +18 -2
- package/src/Message/TextMessage/TextMessage.scss +12 -0
- package/src/Message/TextMessage/TextMessage.tsx +29 -2
- package/src/Message/UserFeedback/UserFeedback.scss +28 -1
- package/src/Message/UserFeedback/UserFeedback.tsx +23 -13
- package/src/Message/UserFeedback/UserFeedbackComplete.tsx +1 -4
- package/src/Message/UserFeedback/index.ts +2 -0
- package/src/Message/index.ts +8 -0
- package/src/MessageBar/AttachButton.scss +0 -1
- package/src/MessageBar/MessageBar.scss +63 -7
- package/src/MessageBar/MessageBar.test.tsx +39 -0
- package/src/MessageBar/MessageBar.tsx +124 -48
- package/src/MessageBar/MicrophoneButton.scss +0 -1
- package/src/MessageBar/SendButton.scss +0 -1
- package/src/MessageBar/StopButton.scss +0 -1
- package/src/Onboarding/Onboarding.scss +101 -0
- package/src/Onboarding/Onboarding.test.tsx +148 -0
- package/src/Onboarding/Onboarding.tsx +126 -0
- package/src/Onboarding/index.ts +3 -0
- package/src/ResponseActions/ResponseActions.scss +12 -1
- package/src/ResponseActions/ResponseActions.test.tsx +111 -12
- package/src/ResponseActions/ResponseActions.tsx +44 -10
- package/src/ResponseActions/ResponseActionsGroups.test.tsx +23 -0
- package/src/ResponseActions/ResponseActionsGroups.tsx +28 -0
- package/src/ResponseActions/index.ts +1 -0
- package/src/ToolCall/ToolCall.scss +1 -1
- package/src/ToolCall/ToolCall.test.tsx +91 -0
- package/src/ToolCall/ToolCall.tsx +49 -4
- package/src/ToolResponse/ToolResponse.scss +13 -3
- package/src/ToolResponse/ToolResponse.test.tsx +119 -0
- package/src/ToolResponse/ToolResponse.tsx +82 -7
- package/src/index.ts +6 -0
- package/src/main.scss +2 -0
- package/tsconfig.json +1 -1
- package/patternfly-docs/content/extensions/chatbot/about-chatbot.md +0 -44
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.MarkdownContent = void 0;
|
|
18
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
19
|
+
const react_markdown_1 = __importDefault(require("react-markdown"));
|
|
20
|
+
const remark_gfm_1 = __importDefault(require("remark-gfm"));
|
|
21
|
+
const react_core_1 = require("@patternfly/react-core");
|
|
22
|
+
const CodeBlockMessage_1 = __importDefault(require("../Message/CodeBlockMessage/CodeBlockMessage"));
|
|
23
|
+
const TextMessage_1 = __importDefault(require("../Message/TextMessage/TextMessage"));
|
|
24
|
+
const ListItemMessage_1 = __importDefault(require("../Message/ListMessage/ListItemMessage"));
|
|
25
|
+
const UnorderedListMessage_1 = __importDefault(require("../Message/ListMessage/UnorderedListMessage"));
|
|
26
|
+
const OrderedListMessage_1 = __importDefault(require("../Message/ListMessage/OrderedListMessage"));
|
|
27
|
+
const TableMessage_1 = __importDefault(require("../Message/TableMessage/TableMessage"));
|
|
28
|
+
const TrMessage_1 = __importDefault(require("../Message/TableMessage/TrMessage"));
|
|
29
|
+
const TdMessage_1 = __importDefault(require("../Message/TableMessage/TdMessage"));
|
|
30
|
+
const TbodyMessage_1 = __importDefault(require("../Message/TableMessage/TbodyMessage"));
|
|
31
|
+
const TheadMessage_1 = __importDefault(require("../Message/TableMessage/TheadMessage"));
|
|
32
|
+
const ThMessage_1 = __importDefault(require("../Message/TableMessage/ThMessage"));
|
|
33
|
+
const ImageMessage_1 = __importDefault(require("../Message/ImageMessage/ImageMessage"));
|
|
34
|
+
const rehype_unwrap_images_1 = __importDefault(require("rehype-unwrap-images"));
|
|
35
|
+
const rehype_external_links_1 = __importDefault(require("rehype-external-links"));
|
|
36
|
+
const rehype_sanitize_1 = __importDefault(require("rehype-sanitize"));
|
|
37
|
+
const rehype_highlight_1 = __importDefault(require("rehype-highlight"));
|
|
38
|
+
require("highlight.js/styles/vs2015.css");
|
|
39
|
+
const LinkMessage_1 = __importDefault(require("../Message/LinkMessage/LinkMessage"));
|
|
40
|
+
const rehypeMoveImagesOutOfParagraphs_1 = require("../Message/Plugins/rehypeMoveImagesOutOfParagraphs");
|
|
41
|
+
const SuperscriptMessage_1 = __importDefault(require("../Message/SuperscriptMessage/SuperscriptMessage"));
|
|
42
|
+
const react_styles_1 = require("@patternfly/react-styles");
|
|
43
|
+
const MarkdownContent = ({ content, isMarkdownDisabled, codeBlockProps, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], additionalRemarkPlugins = [], linkProps, reactMarkdownProps, remarkGfmProps, hasNoImages = false, isPrimary, textComponent, shouldRetainStyles }) => {
|
|
44
|
+
let rehypePlugins = [rehype_unwrap_images_1.default, rehypeMoveImagesOutOfParagraphs_1.rehypeMoveImagesOutOfParagraphs, rehype_highlight_1.default];
|
|
45
|
+
if (openLinkInNewTab) {
|
|
46
|
+
rehypePlugins = rehypePlugins.concat([[rehype_external_links_1.default, { target: '_blank' }, rehype_sanitize_1.default]]);
|
|
47
|
+
}
|
|
48
|
+
if (additionalRehypePlugins) {
|
|
49
|
+
rehypePlugins.push(...additionalRehypePlugins);
|
|
50
|
+
}
|
|
51
|
+
const disallowedElements = hasNoImages ? ['img'] : [];
|
|
52
|
+
if (reactMarkdownProps && reactMarkdownProps.disallowedElements) {
|
|
53
|
+
disallowedElements.push(...reactMarkdownProps.disallowedElements);
|
|
54
|
+
}
|
|
55
|
+
if (isMarkdownDisabled) {
|
|
56
|
+
if (textComponent) {
|
|
57
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: textComponent });
|
|
58
|
+
}
|
|
59
|
+
return ((0, jsx_runtime_1.jsx)(TextMessage_1.default, { component: react_core_1.ContentVariants.p, isPrimary: isPrimary, children: content }));
|
|
60
|
+
}
|
|
61
|
+
return ((0, jsx_runtime_1.jsx)(react_markdown_1.default, Object.assign({ components: {
|
|
62
|
+
section: (props) => {
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
64
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
65
|
+
return ((0, jsx_runtime_1.jsx)("section", Object.assign({}, rest, { className: (0, react_styles_1.css)('pf-chatbot__message-text', shouldRetainStyles && 'pf-m-markdown', rest === null || rest === void 0 ? void 0 : rest.className) })));
|
|
66
|
+
},
|
|
67
|
+
p: (props) => {
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
69
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
70
|
+
return ((0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: react_core_1.ContentVariants.p }, rest, { isPrimary: isPrimary })));
|
|
71
|
+
},
|
|
72
|
+
code: (_a) => {
|
|
73
|
+
var { children } = _a, props = __rest(_a, ["children"]);
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
75
|
+
const { node } = props, codeProps = __rest(props, ["node"]);
|
|
76
|
+
return ((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, Object.assign({}, codeProps, codeBlockProps, { isPrimary: isPrimary, shouldRetainStyles: shouldRetainStyles, children: children })));
|
|
77
|
+
},
|
|
78
|
+
h1: (props) => {
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
80
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
81
|
+
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: react_core_1.ContentVariants.h1 }, rest));
|
|
82
|
+
},
|
|
83
|
+
h2: (props) => {
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
85
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
86
|
+
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: react_core_1.ContentVariants.h2 }, rest));
|
|
87
|
+
},
|
|
88
|
+
h3: (props) => {
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
90
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
91
|
+
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: react_core_1.ContentVariants.h3 }, rest));
|
|
92
|
+
},
|
|
93
|
+
h4: (props) => {
|
|
94
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
95
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
96
|
+
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: react_core_1.ContentVariants.h4 }, rest));
|
|
97
|
+
},
|
|
98
|
+
h5: (props) => {
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
100
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
101
|
+
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: react_core_1.ContentVariants.h5 }, rest));
|
|
102
|
+
},
|
|
103
|
+
h6: (props) => {
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
105
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
106
|
+
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: react_core_1.ContentVariants.h6 }, rest));
|
|
107
|
+
},
|
|
108
|
+
blockquote: (props) => {
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
110
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
111
|
+
return ((0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, component: react_core_1.ContentVariants.blockquote }, rest)));
|
|
112
|
+
},
|
|
113
|
+
ul: (props) => {
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
115
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
116
|
+
return (0, jsx_runtime_1.jsx)(UnorderedListMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles }, rest));
|
|
117
|
+
},
|
|
118
|
+
ol: (props) => {
|
|
119
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
120
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
121
|
+
return (0, jsx_runtime_1.jsx)(OrderedListMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles }, rest));
|
|
122
|
+
},
|
|
123
|
+
li: (props) => {
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
125
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
126
|
+
return (0, jsx_runtime_1.jsx)(ListItemMessage_1.default, Object.assign({}, rest));
|
|
127
|
+
},
|
|
128
|
+
// table requires node attribute for calculating headers for mobile breakpoint
|
|
129
|
+
table: (props) => ((0, jsx_runtime_1.jsx)(TableMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles }, props, tableProps, { isPrimary: isPrimary }))),
|
|
130
|
+
tbody: (props) => {
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
132
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
133
|
+
return (0, jsx_runtime_1.jsx)(TbodyMessage_1.default, Object.assign({}, rest));
|
|
134
|
+
},
|
|
135
|
+
thead: (props) => {
|
|
136
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
137
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
138
|
+
return (0, jsx_runtime_1.jsx)(TheadMessage_1.default, Object.assign({}, rest));
|
|
139
|
+
},
|
|
140
|
+
tr: (props) => {
|
|
141
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
142
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
143
|
+
return (0, jsx_runtime_1.jsx)(TrMessage_1.default, Object.assign({}, rest));
|
|
144
|
+
},
|
|
145
|
+
td: (props) => {
|
|
146
|
+
// Conflicts with Td type
|
|
147
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
148
|
+
const { node, width } = props, rest = __rest(props, ["node", "width"]);
|
|
149
|
+
return (0, jsx_runtime_1.jsx)(TdMessage_1.default, Object.assign({}, rest));
|
|
150
|
+
},
|
|
151
|
+
th: (props) => {
|
|
152
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
153
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
154
|
+
return (0, jsx_runtime_1.jsx)(ThMessage_1.default, Object.assign({}, rest));
|
|
155
|
+
},
|
|
156
|
+
img: (props) => {
|
|
157
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
158
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
159
|
+
return (0, jsx_runtime_1.jsx)(ImageMessage_1.default, Object.assign({}, rest));
|
|
160
|
+
},
|
|
161
|
+
a: (props) => {
|
|
162
|
+
// node is just the details of the document structure - not needed
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
164
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
165
|
+
return (
|
|
166
|
+
// some a types conflict with ButtonProps, but it's ok because we are using an a tag
|
|
167
|
+
// there are too many to handle manually
|
|
168
|
+
(0, jsx_runtime_1.jsx)(LinkMessage_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles }, rest, linkProps, { children: props.children })));
|
|
169
|
+
},
|
|
170
|
+
// used for footnotes
|
|
171
|
+
sup: (props) => {
|
|
172
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
173
|
+
const { node } = props, rest = __rest(props, ["node"]);
|
|
174
|
+
return (0, jsx_runtime_1.jsx)(SuperscriptMessage_1.default, Object.assign({}, rest));
|
|
175
|
+
}
|
|
176
|
+
}, remarkPlugins: [[remark_gfm_1.default, Object.assign({}, remarkGfmProps)], ...additionalRemarkPlugins], rehypePlugins: rehypePlugins }, reactMarkdownProps, { remarkRehypeOptions: Object.assign({
|
|
177
|
+
// removes sr-only class from footnote labels applied by default
|
|
178
|
+
footnoteLabelProperties: { className: [''] } }, reactMarkdownProps === null || reactMarkdownProps === void 0 ? void 0 : reactMarkdownProps.remarkRehypeOptions), disallowedElements: disallowedElements, children: content })));
|
|
179
|
+
};
|
|
180
|
+
exports.MarkdownContent = MarkdownContent;
|
|
181
|
+
exports.default = exports.MarkdownContent;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
16
|
+
const react_1 = require("@testing-library/react");
|
|
17
|
+
require("@testing-library/jest-dom");
|
|
18
|
+
const MarkdownContent_1 = __importDefault(require("./MarkdownContent"));
|
|
19
|
+
const rehype_external_links_1 = __importDefault(require("../__mocks__/rehype-external-links"));
|
|
20
|
+
const BOLD_TEXT = '**Bold text**';
|
|
21
|
+
const ITALIC_TEXT = '*Italic text*';
|
|
22
|
+
const INLINE_CODE = 'Here is inline code: `const x = 5`';
|
|
23
|
+
const CODE_BLOCK = `\`\`\`javascript
|
|
24
|
+
function hello() {
|
|
25
|
+
console.log('Hello, world!');
|
|
26
|
+
}
|
|
27
|
+
\`\`\``;
|
|
28
|
+
const HEADING = '# Heading 1';
|
|
29
|
+
const LINK = '[PatternFly](https://www.patternfly.org/)';
|
|
30
|
+
const UNORDERED_LIST = `
|
|
31
|
+
* Item 1
|
|
32
|
+
* Item 2
|
|
33
|
+
* Item 3
|
|
34
|
+
`;
|
|
35
|
+
const ORDERED_LIST = `
|
|
36
|
+
1. First item
|
|
37
|
+
2. Second item
|
|
38
|
+
3. Third item
|
|
39
|
+
`;
|
|
40
|
+
const TABLE = `
|
|
41
|
+
| Column 1 | Column 2 |
|
|
42
|
+
|----------|----------|
|
|
43
|
+
| Cell 1 | Cell 2 |
|
|
44
|
+
| Cell 3 | Cell 4 |
|
|
45
|
+
`;
|
|
46
|
+
const BLOCKQUOTE = '> This is a blockquote';
|
|
47
|
+
const IMAGE = '';
|
|
48
|
+
describe('MarkdownContent', () => {
|
|
49
|
+
beforeEach(() => {
|
|
50
|
+
jest.clearAllMocks();
|
|
51
|
+
});
|
|
52
|
+
it('should render bold text correctly', () => {
|
|
53
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: BOLD_TEXT }));
|
|
54
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
55
|
+
expect(react_1.screen.getByText('Bold text')).toBeTruthy();
|
|
56
|
+
});
|
|
57
|
+
it('should render italic text correctly', () => {
|
|
58
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: ITALIC_TEXT }));
|
|
59
|
+
expect(container.querySelector('em')).toBeTruthy();
|
|
60
|
+
expect(react_1.screen.getByText('Italic text')).toBeTruthy();
|
|
61
|
+
});
|
|
62
|
+
it('should render inline code correctly', () => {
|
|
63
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: INLINE_CODE }));
|
|
64
|
+
expect(react_1.screen.getByText(/const x = 5/)).toBeTruthy();
|
|
65
|
+
});
|
|
66
|
+
it('should render code blocks correctly', () => {
|
|
67
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: CODE_BLOCK }));
|
|
68
|
+
expect(react_1.screen.getByText(/function hello/)).toBeVisible();
|
|
69
|
+
expect(react_1.screen.getByText(/console.log/)).toBeVisible();
|
|
70
|
+
expect(react_1.screen.getByRole('button', { name: 'Copy code' })).toBeVisible();
|
|
71
|
+
});
|
|
72
|
+
it('should render headings correctly', () => {
|
|
73
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: HEADING }));
|
|
74
|
+
expect(react_1.screen.getByRole('heading', { name: /Heading 1/i })).toBeTruthy();
|
|
75
|
+
});
|
|
76
|
+
it('should render links correctly', () => {
|
|
77
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: LINK }));
|
|
78
|
+
expect(react_1.screen.getByRole('link', { name: /PatternFly/i })).toBeTruthy();
|
|
79
|
+
});
|
|
80
|
+
it('should render unordered lists correctly', () => {
|
|
81
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: UNORDERED_LIST }));
|
|
82
|
+
expect(react_1.screen.getByText('Item 1')).toBeTruthy();
|
|
83
|
+
expect(react_1.screen.getByText('Item 2')).toBeTruthy();
|
|
84
|
+
expect(react_1.screen.getByText('Item 3')).toBeTruthy();
|
|
85
|
+
expect(react_1.screen.getAllByRole('listitem')).toHaveLength(3);
|
|
86
|
+
});
|
|
87
|
+
it('should render ordered lists correctly', () => {
|
|
88
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: ORDERED_LIST }));
|
|
89
|
+
expect(react_1.screen.getByText('First item')).toBeTruthy();
|
|
90
|
+
expect(react_1.screen.getByText('Second item')).toBeTruthy();
|
|
91
|
+
expect(react_1.screen.getByText('Third item')).toBeTruthy();
|
|
92
|
+
expect(react_1.screen.getAllByRole('listitem')).toHaveLength(3);
|
|
93
|
+
});
|
|
94
|
+
it('should render tables correctly', () => {
|
|
95
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: TABLE, tableProps: { 'aria-label': 'Test table' } }));
|
|
96
|
+
expect(react_1.screen.getByRole('grid', { name: /Test table/i })).toBeTruthy();
|
|
97
|
+
expect(react_1.screen.getByRole('columnheader', { name: /Column 1/i })).toBeTruthy();
|
|
98
|
+
expect(react_1.screen.getByRole('columnheader', { name: /Column 2/i })).toBeTruthy();
|
|
99
|
+
expect(react_1.screen.getByRole('cell', { name: /Cell 1/i })).toBeTruthy();
|
|
100
|
+
expect(react_1.screen.getByRole('cell', { name: /Cell 2/i })).toBeTruthy();
|
|
101
|
+
});
|
|
102
|
+
it('should render blockquotes correctly', () => {
|
|
103
|
+
var _a;
|
|
104
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: BLOCKQUOTE }));
|
|
105
|
+
const quote = react_1.screen.getByText(/This is a blockquote/);
|
|
106
|
+
expect(quote).toBeVisible();
|
|
107
|
+
expect((_a = quote.closest('.pf-v6-c-content--blockquote')) === null || _a === void 0 ? void 0 : _a.tagName).toBe('BLOCKQUOTE');
|
|
108
|
+
});
|
|
109
|
+
it('should render images when hasNoImages is false', () => {
|
|
110
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: IMAGE, hasNoImages: false }));
|
|
111
|
+
expect(react_1.screen.getByRole('img', { name: /Alt text/i })).toBeTruthy();
|
|
112
|
+
});
|
|
113
|
+
it('should not render images when hasNoImages is true', () => {
|
|
114
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: IMAGE, hasNoImages: true }));
|
|
115
|
+
expect(react_1.screen.queryByRole('img', { name: /Alt text/i })).toBeFalsy();
|
|
116
|
+
});
|
|
117
|
+
it('should disable markdown rendering when isMarkdownDisabled is true', () => {
|
|
118
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: BOLD_TEXT, isMarkdownDisabled: true }));
|
|
119
|
+
expect(react_1.screen.getByText('**Bold text**')).toBeTruthy();
|
|
120
|
+
});
|
|
121
|
+
it('should render text component when isMarkdownDisabled is true and textComponent is provided', () => {
|
|
122
|
+
const textComponent = (0, jsx_runtime_1.jsx)("div", { "data-testid": "custom-text", children: "Custom text component" });
|
|
123
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: BOLD_TEXT, isMarkdownDisabled: true, textComponent: textComponent }));
|
|
124
|
+
expect(react_1.screen.getByTestId('custom-text')).toBeTruthy();
|
|
125
|
+
expect(react_1.screen.getByText('Custom text component')).toBeTruthy();
|
|
126
|
+
});
|
|
127
|
+
it('should apply isPrimary prop to elements', () => {
|
|
128
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: INLINE_CODE, isPrimary: true }));
|
|
129
|
+
expect(container.querySelector('.pf-m-primary')).toBeTruthy();
|
|
130
|
+
});
|
|
131
|
+
it('should apply shouldRetainStyles prop to elements', () => {
|
|
132
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: BOLD_TEXT, shouldRetainStyles: true }));
|
|
133
|
+
expect(container.querySelector('.pf-m-markdown')).toBeTruthy();
|
|
134
|
+
});
|
|
135
|
+
it('should pass codeBlockProps to code blocks', () => {
|
|
136
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: CODE_BLOCK, codeBlockProps: { 'aria-label': 'Custom code block' } }));
|
|
137
|
+
expect(react_1.screen.getByRole('button', { name: /Custom code block/i })).toBeTruthy();
|
|
138
|
+
});
|
|
139
|
+
it('should pass tableProps to tables', () => {
|
|
140
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: TABLE, tableProps: { 'aria-label': 'Custom table label' } }));
|
|
141
|
+
expect(react_1.screen.getByRole('grid', { name: /Custom table label/i })).toBeTruthy();
|
|
142
|
+
});
|
|
143
|
+
it('should open links in new tab when openLinkInNewTab is true', () => {
|
|
144
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: LINK, openLinkInNewTab: true }));
|
|
145
|
+
expect(rehype_external_links_1.default).toHaveBeenCalledTimes(1);
|
|
146
|
+
});
|
|
147
|
+
it('should not open links in new tab when openLinkInNewTab is false', () => {
|
|
148
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: LINK, openLinkInNewTab: false }));
|
|
149
|
+
expect(rehype_external_links_1.default).not.toHaveBeenCalled();
|
|
150
|
+
});
|
|
151
|
+
it('should pass linkProps to links', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
152
|
+
const onClick = jest.fn();
|
|
153
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: LINK, linkProps: { onClick } }));
|
|
154
|
+
const link = react_1.screen.getByRole('link', { name: /PatternFly/i });
|
|
155
|
+
link.click();
|
|
156
|
+
expect(onClick).toHaveBeenCalledTimes(1);
|
|
157
|
+
}));
|
|
158
|
+
it('should handle reactMarkdownProps.disallowedElements', () => {
|
|
159
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: CODE_BLOCK, reactMarkdownProps: { disallowedElements: ['code'] } }));
|
|
160
|
+
// Code block should not render when disallowed
|
|
161
|
+
expect(react_1.screen.queryByRole('button', { name: /Copy code/i })).toBeFalsy();
|
|
162
|
+
});
|
|
163
|
+
it('should render plain text when no markdown is present', () => {
|
|
164
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: "Plain text without markdown" }));
|
|
165
|
+
expect(react_1.screen.getByText('Plain text without markdown')).toBeTruthy();
|
|
166
|
+
});
|
|
167
|
+
it('should handle empty content', () => {
|
|
168
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: "" }));
|
|
169
|
+
expect(container.textContent).toBe('');
|
|
170
|
+
});
|
|
171
|
+
it('should handle undefined content', () => {
|
|
172
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, {}));
|
|
173
|
+
expect(container.textContent).toBe('');
|
|
174
|
+
});
|
|
175
|
+
it('should render multiple markdown elements together', () => {
|
|
176
|
+
const content = `# Heading
|
|
177
|
+
|
|
178
|
+
**Bold text** and *italic text*
|
|
179
|
+
|
|
180
|
+
\`\`\`javascript
|
|
181
|
+
const x = 5;
|
|
182
|
+
\`\`\`
|
|
183
|
+
|
|
184
|
+
[Link](https://example.com)`;
|
|
185
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: content }));
|
|
186
|
+
expect(react_1.screen.getByRole('heading', { name: /Heading/i })).toBeTruthy();
|
|
187
|
+
expect(react_1.screen.getByText('Bold text')).toBeTruthy();
|
|
188
|
+
expect(react_1.screen.getByText('italic text')).toBeTruthy();
|
|
189
|
+
expect(react_1.screen.getByText(/const x = 5/)).toBeTruthy();
|
|
190
|
+
expect(react_1.screen.getByRole('link', { name: /Link/i })).toBeTruthy();
|
|
191
|
+
});
|
|
192
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.default = void 0;
|
|
21
|
+
var MarkdownContent_1 = require("./MarkdownContent");
|
|
22
|
+
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(MarkdownContent_1).default; } });
|
|
23
|
+
__exportStar(require("./MarkdownContent"), exports);
|
|
@@ -20,6 +20,8 @@ export interface CodeBlockMessageProps {
|
|
|
20
20
|
customActions?: React.ReactNode;
|
|
21
21
|
/** Sets background colors to be appropriate on primary chatbot background */
|
|
22
22
|
isPrimary?: boolean;
|
|
23
|
+
/** Flag indicating that the content should retain message styles when using Markdown. */
|
|
24
|
+
shouldRetainStyles?: boolean;
|
|
23
25
|
}
|
|
24
|
-
declare const CodeBlockMessage: ({ children, className, "aria-label": ariaLabel, isExpandable, expandableSectionProps, expandableSectionToggleProps, expandedText, collapsedText, customActions, isPrimary, ...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;
|
|
25
27
|
export default CodeBlockMessage;
|
|
@@ -20,11 +20,12 @@ const react_1 = require("react");
|
|
|
20
20
|
const react_core_1 = require("@patternfly/react-core");
|
|
21
21
|
const check_icon_1 = require("@patternfly/react-icons/dist/esm/icons/check-icon");
|
|
22
22
|
const copy_icon_1 = require("@patternfly/react-icons/dist/esm/icons/copy-icon");
|
|
23
|
+
const react_styles_1 = require("@patternfly/react-styles");
|
|
23
24
|
const DEFAULT_EXPANDED_TEXT = 'Show less';
|
|
24
25
|
const DEFAULT_COLLAPSED_TEXT = 'Show more';
|
|
25
26
|
const CodeBlockMessage = (_a) => {
|
|
26
27
|
var _b;
|
|
27
|
-
var { children, className, 'aria-label': ariaLabel, isExpandable = false, expandableSectionProps, expandableSectionToggleProps, expandedText = DEFAULT_EXPANDED_TEXT, collapsedText = DEFAULT_COLLAPSED_TEXT, customActions, isPrimary } = _a, props = __rest(_a, ["children", "className", 'aria-label', "isExpandable", "expandableSectionProps", "expandableSectionToggleProps", "expandedText", "collapsedText", "customActions", "isPrimary"]);
|
|
28
|
+
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"]);
|
|
28
29
|
const [copied, setCopied] = (0, react_1.useState)(false);
|
|
29
30
|
const [isExpanded, setIsExpanded] = (0, react_1.useState)(false);
|
|
30
31
|
const buttonRef = (0, react_1.useRef)();
|
|
@@ -47,8 +48,18 @@ const CodeBlockMessage = (_a) => {
|
|
|
47
48
|
setIsExpanded(isExpanded);
|
|
48
49
|
};
|
|
49
50
|
// Handle clicking copy button
|
|
50
|
-
const handleCopy = (0, react_1.useCallback)((
|
|
51
|
-
|
|
51
|
+
const handleCopy = (0, react_1.useCallback)((_event, text) => {
|
|
52
|
+
let textToCopy = '';
|
|
53
|
+
if (typeof text === 'string') {
|
|
54
|
+
textToCopy = text;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
if (codeBlockRef.current) {
|
|
58
|
+
const codeElement = codeBlockRef.current.querySelector('code');
|
|
59
|
+
textToCopy = (codeElement === null || codeElement === void 0 ? void 0 : codeElement.textContent) || '';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
navigator.clipboard.writeText(textToCopy);
|
|
52
63
|
setCopied(true);
|
|
53
64
|
}, []);
|
|
54
65
|
// Reset copied state
|
|
@@ -65,6 +76,6 @@ const CodeBlockMessage = (_a) => {
|
|
|
65
76
|
}
|
|
66
77
|
// Setup code block header
|
|
67
78
|
const actions = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_core_1.CodeBlockAction, { className: "pf-chatbot__message-code-block-default-action", children: [language && (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-code-block-language", children: language }), (0, jsx_runtime_1.jsx)(react_core_1.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 ? (0, jsx_runtime_1.jsx)(check_icon_1.CheckIcon, {}) : (0, jsx_runtime_1.jsx)(copy_icon_1.CopyIcon, {}) }), (0, jsx_runtime_1.jsx)(react_core_1.Tooltip, { id: tooltipID, content: "Copy", position: "top", triggerRef: buttonRef })] }), customActions] }));
|
|
68
|
-
return ((0, jsx_runtime_1.jsx)("div", { className:
|
|
79
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-code-block', shouldRetainStyles && 'pf-m-markdown'), ref: codeBlockRef, children: (0, jsx_runtime_1.jsxs)(react_core_1.CodeBlock, { actions: actions, children: [(0, jsx_runtime_1.jsx)(react_core_1.CodeBlockCode, { children: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: isExpandable ? ((0, jsx_runtime_1.jsx)(react_core_1.ExpandableSection, Object.assign({ variant: react_core_1.ExpandableSectionVariant.truncate, isExpanded: isExpanded, isDetached: true, toggleId: toggleId, contentId: contentId }, expandableSectionProps, { children: children }))) : (children) }) }), isExpandable && ((0, jsx_runtime_1.jsx)(react_core_1.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 })))] }) }));
|
|
69
80
|
};
|
|
70
81
|
exports.default = CodeBlockMessage;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
16
|
+
require("@testing-library/jest-dom");
|
|
17
|
+
const react_1 = require("@testing-library/react");
|
|
18
|
+
const user_event_1 = __importDefault(require("@testing-library/user-event"));
|
|
19
|
+
const CodeBlockMessage_1 = __importDefault(require("./CodeBlockMessage"));
|
|
20
|
+
// Mock clipboard API
|
|
21
|
+
Object.assign(navigator, {
|
|
22
|
+
clipboard: {
|
|
23
|
+
writeText: jest.fn()
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
describe('CodeBlockMessage', () => {
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
jest.clearAllMocks();
|
|
29
|
+
});
|
|
30
|
+
it('should render inline code for single-line content', () => {
|
|
31
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { className: "language-javascript", children: "const x = 5;" }));
|
|
32
|
+
const code = react_1.screen.getByText('const x = 5;');
|
|
33
|
+
expect(code.tagName).toBe('CODE');
|
|
34
|
+
expect(code).toHaveClass('pf-chatbot__message-inline-code');
|
|
35
|
+
});
|
|
36
|
+
it('should render code block for multi-line content', () => {
|
|
37
|
+
const multilineCode = 'const x = 5;\nconst y = 10;';
|
|
38
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { className: "language-javascript", children: multilineCode }));
|
|
39
|
+
const codeElement = container.querySelector('code');
|
|
40
|
+
expect(codeElement === null || codeElement === void 0 ? void 0 : codeElement.textContent).toBe(multilineCode);
|
|
41
|
+
});
|
|
42
|
+
it('should display language label', () => {
|
|
43
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
44
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { className: "language-javascript", children: code }));
|
|
45
|
+
expect(react_1.screen.getByText('javascript')).toBeInTheDocument();
|
|
46
|
+
});
|
|
47
|
+
it('should render copy button', () => {
|
|
48
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
49
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { children: code }));
|
|
50
|
+
expect(react_1.screen.getByRole('button', { name: 'Copy code' })).toBeInTheDocument();
|
|
51
|
+
});
|
|
52
|
+
it('should copy plain string content to clipboard', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
53
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
54
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { children: code }));
|
|
55
|
+
const copyButton = react_1.screen.getByRole('button', { name: 'Copy code' });
|
|
56
|
+
yield user_event_1.default.click(copyButton);
|
|
57
|
+
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(code);
|
|
58
|
+
}));
|
|
59
|
+
it('should extract text content from React elements when copying', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
|
+
// Simulate what happens with syntax highlighting - children become React elements
|
|
61
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsxs)(CodeBlockMessage_1.default, { className: "language-javascript", children: [(0, jsx_runtime_1.jsx)("span", { className: "hljs-keyword", children: "const" }), " x = 5;", '\n', (0, jsx_runtime_1.jsx)("span", { className: "hljs-keyword", children: "const" }), " y = 10;"] }));
|
|
62
|
+
const copyButton = react_1.screen.getByRole('button', { name: 'Copy code' });
|
|
63
|
+
yield user_event_1.default.click(copyButton);
|
|
64
|
+
// Should extract actual text content from DOM, not "[object Object]"
|
|
65
|
+
const codeElement = container.querySelector('code');
|
|
66
|
+
const expectedText = (codeElement === null || codeElement === void 0 ? void 0 : codeElement.textContent) || '';
|
|
67
|
+
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(expectedText);
|
|
68
|
+
expect(expectedText).not.toContain('[object Object]');
|
|
69
|
+
}));
|
|
70
|
+
it('should show check icon after copying', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
72
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { children: code }));
|
|
73
|
+
const copyButton = react_1.screen.getByRole('button', { name: 'Copy code' });
|
|
74
|
+
yield user_event_1.default.click(copyButton);
|
|
75
|
+
// Check icon should be visible (we can verify by checking if CopyIcon is not present)
|
|
76
|
+
const svgElement = copyButton.querySelector('svg');
|
|
77
|
+
expect(svgElement).toBeInTheDocument();
|
|
78
|
+
}));
|
|
79
|
+
it('should render expandable section when isExpandable is true', () => {
|
|
80
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
81
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { isExpandable: true, children: code }));
|
|
82
|
+
expect(react_1.screen.getByRole('button', { name: 'Show more' })).toBeInTheDocument();
|
|
83
|
+
});
|
|
84
|
+
it('should toggle expandable section', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
85
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
86
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { isExpandable: true, children: code }));
|
|
87
|
+
const toggleButton = react_1.screen.getByRole('button', { name: 'Show more' });
|
|
88
|
+
yield user_event_1.default.click(toggleButton);
|
|
89
|
+
expect(react_1.screen.getByRole('button', { name: 'Show less' })).toBeInTheDocument();
|
|
90
|
+
}));
|
|
91
|
+
it('should use custom expanded/collapsed text', () => {
|
|
92
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
93
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { isExpandable: true, expandedText: "Hide", collapsedText: "Reveal", children: code }));
|
|
94
|
+
expect(react_1.screen.getByRole('button', { name: 'Reveal' })).toBeInTheDocument();
|
|
95
|
+
});
|
|
96
|
+
it('should pass through expandableSectionProps', () => {
|
|
97
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
98
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { isExpandable: true, expandableSectionProps: { className: 'custom-expandable-class' }, children: code }));
|
|
99
|
+
const expandableSection = container.querySelector('.pf-v6-c-expandable-section.custom-expandable-class');
|
|
100
|
+
expect(expandableSection).toBeInTheDocument();
|
|
101
|
+
});
|
|
102
|
+
it('should render custom actions', () => {
|
|
103
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
104
|
+
const customAction = (0, jsx_runtime_1.jsx)("button", { "aria-label": "Custom action", children: "Custom" });
|
|
105
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { customActions: customAction, children: code }));
|
|
106
|
+
expect(react_1.screen.getByRole('button', { name: 'Custom action' })).toBeInTheDocument();
|
|
107
|
+
});
|
|
108
|
+
it('should apply isPrimary class to inline code', () => {
|
|
109
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { isPrimary: true, children: "const x = 5;" }));
|
|
110
|
+
const code = react_1.screen.getByText('const x = 5;');
|
|
111
|
+
expect(code).toHaveClass('pf-m-primary');
|
|
112
|
+
});
|
|
113
|
+
it('should apply shouldRetainStyles class to code block', () => {
|
|
114
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
115
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { shouldRetainStyles: true, children: code }));
|
|
116
|
+
const codeBlockDiv = container.querySelector('.pf-chatbot__message-code-block');
|
|
117
|
+
expect(codeBlockDiv).toHaveClass('pf-m-markdown');
|
|
118
|
+
});
|
|
119
|
+
it('should use custom aria-label for copy button', () => {
|
|
120
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
121
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { "aria-label": "Copy this code", children: code }));
|
|
122
|
+
expect(react_1.screen.getByRole('button', { name: 'Copy this code' })).toBeInTheDocument();
|
|
123
|
+
});
|
|
124
|
+
it('should prioritize data-expanded-text over expandedText prop', () => {
|
|
125
|
+
const code = 'const x = 5;\nconst y = 10;';
|
|
126
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn());
|
|
127
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, { isExpandable: true, expandedText: "Custom Expanded", "data-expanded-text": "Data Expanded", children: code }));
|
|
128
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('Message:', expect.stringContaining('data-expanded-text or data-collapsed-text will override'));
|
|
129
|
+
consoleErrorSpy.mockRestore();
|
|
130
|
+
});
|
|
131
|
+
});
|
|
@@ -1,3 +1,17 @@
|
|
|
1
1
|
import { AlertProps } from '@patternfly/react-core';
|
|
2
|
-
|
|
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;
|