@patternfly/chatbot 6.5.0-prerelease.3 → 6.5.0-prerelease.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/AttachMenu/AttachMenu.d.ts +8 -2
- package/dist/cjs/AttachMenu/AttachMenu.js +2 -2
- 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/ChatbotFooter/ChatbotFooter.d.ts +5 -2
- package/dist/cjs/ChatbotFooter/ChatbotFooter.js +2 -2
- package/dist/cjs/ChatbotFooter/ChatbotFooter.test.js +5 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +29 -2
- package/dist/cjs/CodeModal/CodeModal.d.ts +2 -0
- package/dist/cjs/CodeModal/CodeModal.js +53 -8
- 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/FileDetailsLabel/FileDetailsLabel.d.ts +2 -1
- 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 +5 -1
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +16 -5
- 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 +22 -3
- package/dist/cjs/Message/Message.js +8 -161
- package/dist/cjs/Message/Message.test.js +161 -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 -3
- 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 +9 -1
- package/dist/cjs/Message/TableMessage/TableMessage.js +3 -2
- package/dist/cjs/Message/TextMessage/TextMessage.d.ts +11 -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/AttachButton.d.ts +2 -0
- package/dist/cjs/MessageBar/AttachButton.js +2 -2
- package/dist/cjs/MessageBar/AttachButton.test.js +4 -0
- package/dist/cjs/MessageBar/MessageBar.d.ts +22 -6
- package/dist/cjs/MessageBar/MessageBar.js +43 -11
- package/dist/cjs/MessageBar/MessageBar.test.js +74 -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/__mocks__/monaco-editor.d.ts +11 -0
- package/dist/cjs/__mocks__/monaco-editor.js +18 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +7 -1
- package/dist/css/main.css +336 -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/AttachMenu/AttachMenu.d.ts +8 -2
- package/dist/esm/AttachMenu/AttachMenu.js +2 -2
- 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/ChatbotFooter/ChatbotFooter.d.ts +5 -2
- package/dist/esm/ChatbotFooter/ChatbotFooter.js +2 -2
- package/dist/esm/ChatbotFooter/ChatbotFooter.test.js +5 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +30 -3
- package/dist/esm/CodeModal/CodeModal.d.ts +2 -0
- package/dist/esm/CodeModal/CodeModal.js +54 -9
- 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/FileDetailsLabel/FileDetailsLabel.d.ts +2 -1
- 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 +5 -1
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +16 -5
- 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 +22 -3
- package/dist/esm/Message/Message.js +9 -162
- package/dist/esm/Message/Message.test.js +161 -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 -3
- 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 +9 -1
- package/dist/esm/Message/TableMessage/TableMessage.js +3 -2
- package/dist/esm/Message/TextMessage/TextMessage.d.ts +11 -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/AttachButton.d.ts +2 -0
- package/dist/esm/MessageBar/AttachButton.js +2 -2
- package/dist/esm/MessageBar/AttachButton.test.js +4 -0
- package/dist/esm/MessageBar/MessageBar.d.ts +22 -6
- package/dist/esm/MessageBar/MessageBar.js +43 -11
- package/dist/esm/MessageBar/MessageBar.test.js +74 -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/__mocks__/monaco-editor.d.ts +11 -0
- package/dist/esm/__mocks__/monaco-editor.js +18 -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 -2
- 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/Messages/UserMessageWithExtraContent.tsx +3 -1
- 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/Settings.tsx +1 -1
- 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 +44 -22
- package/patternfly-docs/content/extensions/chatbot/examples/demos/WhiteEmbeddedChatbot.tsx +451 -0
- package/patternfly-docs/patternfly-docs.config.js +1 -1
- package/patternfly-docs/patternfly-docs.source.js +1 -1
- package/src/AttachMenu/AttachMenu.tsx +26 -11
- package/src/Chatbot/Chatbot.scss +23 -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/ChatbotFooter/ChatbotFooter.scss +21 -0
- package/src/ChatbotFooter/ChatbotFooter.test.tsx +10 -1
- package/src/ChatbotFooter/ChatbotFooter.tsx +10 -3
- package/src/ChatbotHeader/ChatbotHeader.scss +19 -0
- package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +56 -14
- package/src/ChatbotModal/ChatbotModal.scss +3 -0
- package/src/CodeModal/CodeModal.tsx +72 -23
- package/src/DeepThinking/DeepThinking.scss +1 -1
- package/src/DeepThinking/DeepThinking.test.tsx +109 -0
- package/src/DeepThinking/DeepThinking.tsx +54 -5
- package/src/FileDetailsLabel/FileDetailsLabel.tsx +2 -2
- 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 +17 -0
- package/src/Message/CodeBlockMessage/CodeBlockMessage.test.tsx +171 -0
- package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +21 -5
- 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 +239 -2
- package/src/Message/Message.tsx +133 -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.scss +7 -0
- 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 +17 -1
- package/src/Message/TableMessage/TableMessage.tsx +22 -2
- package/src/Message/TextMessage/TextMessage.scss +18 -0
- package/src/Message/TextMessage/TextMessage.tsx +39 -3
- package/src/Message/UserFeedback/UserFeedback.scss +30 -2
- 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/AttachButton.test.tsx +4 -0
- package/src/MessageBar/AttachButton.tsx +4 -1
- package/src/MessageBar/MessageBar.scss +66 -6
- package/src/MessageBar/MessageBar.test.tsx +129 -1
- package/src/MessageBar/MessageBar.tsx +150 -56
- 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/__mocks__/monaco-editor.ts +19 -0
- 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
|
@@ -42,6 +42,12 @@ export interface ActionProps extends Omit<ButtonProps, 'ref'> {
|
|
|
42
42
|
type ExtendedActionProps = ActionProps & {
|
|
43
43
|
[key: string]: any;
|
|
44
44
|
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The various actions that can be attached to a bot message for users to interact with.
|
|
48
|
+
* Use this component when passing children to Message to customize its structure.
|
|
49
|
+
*/
|
|
50
|
+
|
|
45
51
|
export interface ResponseActionProps {
|
|
46
52
|
/** Props for message actions, such as feedback (positive or negative), copy button, share, and listen */
|
|
47
53
|
actions: Record<string, ExtendedActionProps | undefined> & {
|
|
@@ -53,11 +59,20 @@ export interface ResponseActionProps {
|
|
|
53
59
|
listen?: ActionProps;
|
|
54
60
|
edit?: ActionProps;
|
|
55
61
|
};
|
|
62
|
+
/** When true, the selected action will persist even when clicking outside the component.
|
|
63
|
+
* When false (default), clicking outside or clicking another action will deselect the current selection. */
|
|
64
|
+
persistActionSelection?: boolean;
|
|
56
65
|
}
|
|
57
66
|
|
|
58
|
-
export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
67
|
+
export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
68
|
+
actions,
|
|
69
|
+
persistActionSelection = false
|
|
70
|
+
}) => {
|
|
59
71
|
const [activeButton, setActiveButton] = useState<string>();
|
|
60
72
|
const [clickStatePersisted, setClickStatePersisted] = useState<boolean>(false);
|
|
73
|
+
|
|
74
|
+
const { positive, negative, copy, edit, share, download, listen, ...additionalActions } = actions;
|
|
75
|
+
|
|
61
76
|
useEffect(() => {
|
|
62
77
|
// Define the order of precedence for checking initial `isClicked`
|
|
63
78
|
const actionPrecedence = ['positive', 'negative', 'copy', 'edit', 'share', 'download', 'listen'];
|
|
@@ -82,13 +97,21 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({ action
|
|
|
82
97
|
// Click state is explicitly controlled by consumer.
|
|
83
98
|
setClickStatePersisted(true);
|
|
84
99
|
}
|
|
100
|
+
// If persistActionSelection is true, all selections are persisted
|
|
101
|
+
if (persistActionSelection) {
|
|
102
|
+
setClickStatePersisted(true);
|
|
103
|
+
}
|
|
85
104
|
setActiveButton(initialActive);
|
|
86
|
-
}, [actions]);
|
|
105
|
+
}, [actions, persistActionSelection]);
|
|
87
106
|
|
|
88
|
-
const { positive, negative, copy, edit, share, download, listen, ...additionalActions } = actions;
|
|
89
107
|
const responseActions = useRef<HTMLDivElement>(null);
|
|
90
108
|
|
|
91
109
|
useEffect(() => {
|
|
110
|
+
// Only add click outside listener if not persisting selection
|
|
111
|
+
if (persistActionSelection) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
92
115
|
const handleClickOutside = (e) => {
|
|
93
116
|
if (responseActions.current && !responseActions.current.contains(e.target) && !clickStatePersisted) {
|
|
94
117
|
setActiveButton(undefined);
|
|
@@ -99,15 +122,26 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({ action
|
|
|
99
122
|
return () => {
|
|
100
123
|
window.removeEventListener('click', handleClickOutside);
|
|
101
124
|
};
|
|
102
|
-
}, [clickStatePersisted]);
|
|
125
|
+
}, [clickStatePersisted, persistActionSelection]);
|
|
103
126
|
|
|
104
127
|
const handleClick = (
|
|
105
128
|
e: MouseEvent | MouseEvent<Element, MouseEvent> | KeyboardEvent,
|
|
106
129
|
id: string,
|
|
107
130
|
onClick?: (event: MouseEvent | MouseEvent<Element, MouseEvent> | KeyboardEvent) => void
|
|
108
131
|
) => {
|
|
109
|
-
|
|
110
|
-
|
|
132
|
+
if (persistActionSelection) {
|
|
133
|
+
if (activeButton === id) {
|
|
134
|
+
// Toggle off if clicking the same button
|
|
135
|
+
setActiveButton(undefined);
|
|
136
|
+
} else {
|
|
137
|
+
// Set new active button
|
|
138
|
+
setActiveButton(id);
|
|
139
|
+
}
|
|
140
|
+
setClickStatePersisted(true);
|
|
141
|
+
} else {
|
|
142
|
+
setClickStatePersisted(false);
|
|
143
|
+
setActiveButton(id);
|
|
144
|
+
}
|
|
111
145
|
onClick && onClick(e);
|
|
112
146
|
};
|
|
113
147
|
|
|
@@ -117,12 +151,12 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({ action
|
|
|
117
151
|
<ResponseActionButton
|
|
118
152
|
{...positive}
|
|
119
153
|
ariaLabel={positive.ariaLabel ?? 'Good response'}
|
|
120
|
-
clickedAriaLabel={positive.ariaLabel ?? '
|
|
154
|
+
clickedAriaLabel={positive.ariaLabel ?? 'Good response recorded'}
|
|
121
155
|
onClick={(e) => handleClick(e, 'positive', positive.onClick)}
|
|
122
156
|
className={positive.className}
|
|
123
157
|
isDisabled={positive.isDisabled}
|
|
124
158
|
tooltipContent={positive.tooltipContent ?? 'Good response'}
|
|
125
|
-
clickedTooltipContent={positive.clickedTooltipContent ?? '
|
|
159
|
+
clickedTooltipContent={positive.clickedTooltipContent ?? 'Good response recorded'}
|
|
126
160
|
tooltipProps={positive.tooltipProps}
|
|
127
161
|
icon={<OutlinedThumbsUpIcon />}
|
|
128
162
|
isClicked={activeButton === 'positive'}
|
|
@@ -135,12 +169,12 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({ action
|
|
|
135
169
|
<ResponseActionButton
|
|
136
170
|
{...negative}
|
|
137
171
|
ariaLabel={negative.ariaLabel ?? 'Bad response'}
|
|
138
|
-
clickedAriaLabel={negative.ariaLabel ?? '
|
|
172
|
+
clickedAriaLabel={negative.ariaLabel ?? 'Bad response recorded'}
|
|
139
173
|
onClick={(e) => handleClick(e, 'negative', negative.onClick)}
|
|
140
174
|
className={negative.className}
|
|
141
175
|
isDisabled={negative.isDisabled}
|
|
142
176
|
tooltipContent={negative.tooltipContent ?? 'Bad response'}
|
|
143
|
-
clickedTooltipContent={negative.clickedTooltipContent ?? '
|
|
177
|
+
clickedTooltipContent={negative.clickedTooltipContent ?? 'Bad response recorded'}
|
|
144
178
|
tooltipProps={negative.tooltipProps}
|
|
145
179
|
icon={<OutlinedThumbsDownIcon />}
|
|
146
180
|
isClicked={activeButton === 'negative'}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import ResponseActionsGroups from './ResponseActionsGroups';
|
|
4
|
+
|
|
5
|
+
test('Renders with children', () => {
|
|
6
|
+
render(<ResponseActionsGroups>Test content</ResponseActionsGroups>);
|
|
7
|
+
expect(screen.getByText('Test content')).toBeInTheDocument();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('Renders with pf-chatbot__response-actions-groups class by default', () => {
|
|
11
|
+
render(<ResponseActionsGroups>Test content</ResponseActionsGroups>);
|
|
12
|
+
expect(screen.getByText('Test content')).toHaveClass('pf-chatbot__response-actions-groups', { exact: true });
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('Renders with custom className', () => {
|
|
16
|
+
render(<ResponseActionsGroups className="custom-class">Test content</ResponseActionsGroups>);
|
|
17
|
+
expect(screen.getByText('Test content')).toHaveClass('custom-class');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('Spreads additional props', () => {
|
|
21
|
+
render(<ResponseActionsGroups id="test-id">Test content</ResponseActionsGroups>);
|
|
22
|
+
expect(screen.getByText('Test content')).toHaveAttribute('id', 'test-id');
|
|
23
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Response Actions Groups - Container for multiple action groups
|
|
3
|
+
// ============================================================================
|
|
4
|
+
import { FunctionComponent, HTMLProps, ReactNode } from 'react';
|
|
5
|
+
import { css } from '@patternfly/react-styles';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The container for grouping multiple related ResponseActions components, typically used for having different persistence states amongst groups.
|
|
9
|
+
* Use this component when passing children to Message to customize its structure.
|
|
10
|
+
*/
|
|
11
|
+
export interface ResponseActionsGroupsProps extends HTMLProps<HTMLDivElement> {
|
|
12
|
+
/** Content to render inside the response actions groups container */
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
/** Additional classes applied to the response actions groups container. */
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const ResponseActionsGroups: FunctionComponent<ResponseActionsGroupsProps> = ({
|
|
19
|
+
children,
|
|
20
|
+
className,
|
|
21
|
+
...props
|
|
22
|
+
}) => (
|
|
23
|
+
<div className={css('pf-chatbot__response-actions-groups', className)} {...props}>
|
|
24
|
+
{children}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export default ResponseActionsGroups;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.pf-chatbot__tool-call {
|
|
2
|
-
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--control--read-only);
|
|
3
2
|
--pf-v6-c-card--BorderRadius: var(--pf-t--global--border--radius--small);
|
|
3
|
+
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--default);
|
|
4
4
|
|
|
5
5
|
overflow: unset;
|
|
6
6
|
row-gap: var(--pf-t--global--spacer--sm);
|
|
@@ -181,4 +181,95 @@ describe('ToolCall', () => {
|
|
|
181
181
|
render(<ToolCall {...defaultProps} cardFooterProps={{ id: 'card-footer-test-id' }} />);
|
|
182
182
|
expect(screen.getByRole('button', { name: 'Run tool' }).closest('#card-footer-test-id')).toBeVisible();
|
|
183
183
|
});
|
|
184
|
+
|
|
185
|
+
it('Renders collapsed by default when expandableContent is provided', () => {
|
|
186
|
+
render(<ToolCall {...defaultProps} expandableContent="Expandable Content" />);
|
|
187
|
+
|
|
188
|
+
expect(screen.getByRole('button', { name: defaultProps.titleText })).toHaveAttribute('aria-expanded', 'false');
|
|
189
|
+
expect(screen.queryByText('Expandable Content')).not.toBeVisible();
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('Renders expanded when isDefaultExpanded is true', () => {
|
|
193
|
+
render(<ToolCall {...defaultProps} isDefaultExpanded expandableContent="Expandable Content" />);
|
|
194
|
+
|
|
195
|
+
expect(screen.getByRole('button', { name: defaultProps.titleText })).toHaveAttribute('aria-expanded', 'true');
|
|
196
|
+
expect(screen.getByText('Expandable Content')).toBeVisible();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('expandableSectionProps.isExpanded overrides isDefaultExpanded', () => {
|
|
200
|
+
render(
|
|
201
|
+
<ToolCall
|
|
202
|
+
{...defaultProps}
|
|
203
|
+
isDefaultExpanded={false}
|
|
204
|
+
expandableContent="Expandable Content"
|
|
205
|
+
expandableSectionProps={{ isExpanded: true }}
|
|
206
|
+
/>
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
expect(screen.getByRole('button', { name: defaultProps.titleText })).toHaveAttribute('aria-expanded', 'true');
|
|
210
|
+
expect(screen.getByText('Expandable Content')).toBeVisible();
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('expandableSectionProps.onToggle overrides internal onToggle behavior', async () => {
|
|
214
|
+
const user = userEvent.setup();
|
|
215
|
+
const customOnToggle = jest.fn();
|
|
216
|
+
|
|
217
|
+
render(
|
|
218
|
+
<ToolCall
|
|
219
|
+
{...defaultProps}
|
|
220
|
+
isDefaultExpanded={false}
|
|
221
|
+
expandableContent="Expandable Content"
|
|
222
|
+
expandableSectionProps={{ onToggle: customOnToggle }}
|
|
223
|
+
/>
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
const toggleButton = screen.getByRole('button', { name: defaultProps.titleText });
|
|
227
|
+
expect(toggleButton).toHaveAttribute('aria-expanded', 'false');
|
|
228
|
+
|
|
229
|
+
await user.click(toggleButton);
|
|
230
|
+
|
|
231
|
+
expect(customOnToggle).toHaveBeenCalledTimes(1);
|
|
232
|
+
expect(toggleButton).toHaveAttribute('aria-expanded', 'false');
|
|
233
|
+
expect(screen.queryByText('Expandable Content')).not.toBeVisible();
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it('should render titleText as markdown when isTitleMarkdown is true', () => {
|
|
237
|
+
const titleText = '**Bold title**';
|
|
238
|
+
const { container } = render(<ToolCall titleText={titleText} isTitleMarkdown />);
|
|
239
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
240
|
+
expect(screen.getByText('Bold title')).toBeTruthy();
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('should not render titleText as markdown when isTitleMarkdown is false', () => {
|
|
244
|
+
const titleText = '**Bold title**';
|
|
245
|
+
render(<ToolCall titleText={titleText} />);
|
|
246
|
+
expect(screen.getByText('**Bold title**')).toBeTruthy();
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('should render expandableContent as markdown when isExpandableContentMarkdown is true', async () => {
|
|
250
|
+
const user = userEvent.setup();
|
|
251
|
+
const expandableContent = '**Bold expandable content**';
|
|
252
|
+
const { container } = render(
|
|
253
|
+
<ToolCall {...defaultProps} expandableContent={expandableContent} isExpandableContentMarkdown />
|
|
254
|
+
);
|
|
255
|
+
await user.click(screen.getByRole('button', { name: defaultProps.titleText }));
|
|
256
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
257
|
+
expect(screen.getByText('Bold expandable content')).toBeTruthy();
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('should not render expandableContent as markdown when isExpandableContentMarkdown is false', async () => {
|
|
261
|
+
const user = userEvent.setup();
|
|
262
|
+
const expandableContent = '**Bold expandable content**';
|
|
263
|
+
render(<ToolCall {...defaultProps} expandableContent={expandableContent} />);
|
|
264
|
+
await user.click(screen.getByRole('button', { name: defaultProps.titleText }));
|
|
265
|
+
expect(screen.getByText('**Bold expandable content**')).toBeTruthy();
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('should pass markdownContentProps to MarkdownContent component', () => {
|
|
269
|
+
const titleText = '**Bold title**';
|
|
270
|
+
const { container } = render(
|
|
271
|
+
<ToolCall titleText={titleText} isTitleMarkdown markdownContentProps={{ isPrimary: true }} />
|
|
272
|
+
);
|
|
273
|
+
expect(container.querySelector('.pf-m-primary')).toBeTruthy();
|
|
274
|
+
});
|
|
184
275
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type FunctionComponent } from 'react';
|
|
1
|
+
import { useState, type FunctionComponent } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
ActionList,
|
|
4
4
|
ActionListProps,
|
|
@@ -19,6 +19,8 @@ import {
|
|
|
19
19
|
Spinner,
|
|
20
20
|
SpinnerProps
|
|
21
21
|
} from '@patternfly/react-core';
|
|
22
|
+
import MarkdownContent from '../MarkdownContent';
|
|
23
|
+
import type { MarkdownContentProps } from '../MarkdownContent';
|
|
22
24
|
|
|
23
25
|
export interface ToolCallProps {
|
|
24
26
|
/** Title text for the tool call. */
|
|
@@ -31,6 +33,8 @@ export interface ToolCallProps {
|
|
|
31
33
|
spinnerProps?: SpinnerProps;
|
|
32
34
|
/** Content to render within an expandable section. */
|
|
33
35
|
expandableContent?: React.ReactNode;
|
|
36
|
+
/** Flag indicating whether the expandable content is expanded by default. */
|
|
37
|
+
isDefaultExpanded?: boolean;
|
|
34
38
|
/** Text content for the "run" action button. */
|
|
35
39
|
runButtonText?: string;
|
|
36
40
|
/** Additional props for the "run" action button. */
|
|
@@ -59,6 +63,14 @@ export interface ToolCallProps {
|
|
|
59
63
|
cardFooterProps?: CardFooterProps;
|
|
60
64
|
/** Additional props for the expandable section when expandableContent is passed. */
|
|
61
65
|
expandableSectionProps?: Omit<ExpandableSectionProps, 'ref'>;
|
|
66
|
+
/** Whether to enable markdown rendering for titleText. When true, titleText will be parsed as markdown. */
|
|
67
|
+
isTitleMarkdown?: boolean;
|
|
68
|
+
/** Whether to enable markdown rendering for expandableContent. When true and expandableContent is a string, it will be parsed as markdown. */
|
|
69
|
+
isExpandableContentMarkdown?: boolean;
|
|
70
|
+
/** Props passed to MarkdownContent component when markdown is enabled */
|
|
71
|
+
markdownContentProps?: Omit<MarkdownContentProps, 'content'>;
|
|
72
|
+
/** Whether to retain styles in the MarkdownContent component. Defaults to false. */
|
|
73
|
+
shouldRetainStyles?: boolean;
|
|
62
74
|
}
|
|
63
75
|
|
|
64
76
|
export const ToolCall: FunctionComponent<ToolCallProps> = ({
|
|
@@ -66,6 +78,7 @@ export const ToolCall: FunctionComponent<ToolCallProps> = ({
|
|
|
66
78
|
loadingText,
|
|
67
79
|
isLoading,
|
|
68
80
|
expandableContent,
|
|
81
|
+
isDefaultExpanded = false,
|
|
69
82
|
runButtonText = 'Run tool',
|
|
70
83
|
runButtonProps,
|
|
71
84
|
runActionItemProps,
|
|
@@ -80,8 +93,25 @@ export const ToolCall: FunctionComponent<ToolCallProps> = ({
|
|
|
80
93
|
cardBodyProps,
|
|
81
94
|
cardFooterProps,
|
|
82
95
|
expandableSectionProps,
|
|
83
|
-
spinnerProps
|
|
96
|
+
spinnerProps,
|
|
97
|
+
isTitleMarkdown,
|
|
98
|
+
isExpandableContentMarkdown,
|
|
99
|
+
markdownContentProps,
|
|
100
|
+
shouldRetainStyles = false
|
|
84
101
|
}: ToolCallProps) => {
|
|
102
|
+
const [isExpanded, setIsExpanded] = useState(isDefaultExpanded);
|
|
103
|
+
|
|
104
|
+
const onToggle = (_event: React.MouseEvent, isExpanded: boolean) => {
|
|
105
|
+
setIsExpanded(isExpanded);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const renderTitle = () => {
|
|
109
|
+
if (isTitleMarkdown) {
|
|
110
|
+
return <MarkdownContent shouldRetainStyles={shouldRetainStyles} content={titleText} {...markdownContentProps} />;
|
|
111
|
+
}
|
|
112
|
+
return titleText;
|
|
113
|
+
};
|
|
114
|
+
|
|
85
115
|
const titleContent = (
|
|
86
116
|
<span className={`pf-chatbot__tool-call-title-content`}>
|
|
87
117
|
{isLoading ? (
|
|
@@ -90,10 +120,23 @@ export const ToolCall: FunctionComponent<ToolCallProps> = ({
|
|
|
90
120
|
{<span className="pf-chatbot__tool-call-title-text">{loadingText}</span>}
|
|
91
121
|
</>
|
|
92
122
|
) : (
|
|
93
|
-
<span className="pf-chatbot__tool-call-title-text">{
|
|
123
|
+
<span className="pf-chatbot__tool-call-title-text">{renderTitle()}</span>
|
|
94
124
|
)}
|
|
95
125
|
</span>
|
|
96
126
|
);
|
|
127
|
+
|
|
128
|
+
const renderExpandableContent = () => {
|
|
129
|
+
if (isExpandableContentMarkdown && typeof expandableContent === 'string') {
|
|
130
|
+
return (
|
|
131
|
+
<MarkdownContent
|
|
132
|
+
shouldRetainStyles={shouldRetainStyles}
|
|
133
|
+
content={expandableContent}
|
|
134
|
+
{...markdownContentProps}
|
|
135
|
+
/>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
return expandableContent;
|
|
139
|
+
};
|
|
97
140
|
const defaultActions = (
|
|
98
141
|
<>
|
|
99
142
|
<ActionListItem {...actionListItemProps} {...cancelActionItemProps}>
|
|
@@ -124,10 +167,12 @@ export const ToolCall: FunctionComponent<ToolCallProps> = ({
|
|
|
124
167
|
<ExpandableSection
|
|
125
168
|
className="pf-chatbot__tool-call-expandable-section"
|
|
126
169
|
toggleContent={titleContent}
|
|
170
|
+
onToggle={onToggle}
|
|
171
|
+
isExpanded={isExpanded}
|
|
127
172
|
isIndented
|
|
128
173
|
{...expandableSectionProps}
|
|
129
174
|
>
|
|
130
|
-
{
|
|
175
|
+
{renderExpandableContent()}
|
|
131
176
|
</ExpandableSection>
|
|
132
177
|
) : (
|
|
133
178
|
titleContent
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
.pf-chatbot__tool-response {
|
|
2
|
-
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--
|
|
2
|
+
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--default);
|
|
3
3
|
overflow: unset;
|
|
4
4
|
}
|
|
5
5
|
|
|
@@ -25,12 +25,22 @@
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
.pf-chatbot__tool-response-card {
|
|
28
|
-
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--
|
|
28
|
+
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--default);
|
|
29
29
|
--pf-v6-c-card--first-child--PaddingBlockStart: var(--pf-t--global--spacer--sm);
|
|
30
30
|
--pf-v6-c-card__title--not--last-child--PaddingBlockEnd: var(--pf-t--global--spacer--sm);
|
|
31
31
|
--pf-v6-c-card--c-divider--child--PaddingBlockStart: var(--pf-t--global--spacer--sm);
|
|
32
32
|
|
|
33
33
|
.pf-v6-c-divider {
|
|
34
|
-
--pf-v6-c-divider--Color: var(--pf-t--global--border--color--
|
|
34
|
+
--pf-v6-c-divider--Color: var(--pf-t--global--border--color--default);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.pf-chatbot__tool-response-expandable-section .pf-v6-c-expandable-section__toggle .pf-m-markdown {
|
|
39
|
+
padding: inherit;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.pf-chatbot__tool-response {
|
|
43
|
+
.pf-chatbot__message-image {
|
|
44
|
+
max-width: 100%;
|
|
35
45
|
}
|
|
36
46
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
2
3
|
import '@testing-library/jest-dom';
|
|
3
4
|
import ToolResponse from './ToolResponse';
|
|
4
5
|
|
|
@@ -105,4 +106,122 @@ describe('ToolResponse', () => {
|
|
|
105
106
|
const { container } = render(<ToolResponse {...defaultProps} cardBody={undefined} />);
|
|
106
107
|
expect(container.querySelector('.pf-v6-c-divider')).toBeFalsy();
|
|
107
108
|
});
|
|
109
|
+
|
|
110
|
+
it('Renders expanded by default', () => {
|
|
111
|
+
render(<ToolResponse {...defaultProps} />);
|
|
112
|
+
|
|
113
|
+
expect(screen.getByRole('button', { name: defaultProps.toggleContent })).toHaveAttribute('aria-expanded', 'true');
|
|
114
|
+
expect(screen.getByText(defaultProps.cardTitle)).toBeVisible();
|
|
115
|
+
expect(screen.getByText(defaultProps.cardBody)).toBeVisible();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('Renders collapsed when isDefaultExpanded is false', () => {
|
|
119
|
+
render(<ToolResponse isDefaultExpanded={false} {...defaultProps} />);
|
|
120
|
+
|
|
121
|
+
expect(screen.getByRole('button', { name: defaultProps.toggleContent })).toHaveAttribute('aria-expanded', 'false');
|
|
122
|
+
expect(screen.getByText(defaultProps.cardTitle)).not.toBeVisible();
|
|
123
|
+
expect(screen.getByText(defaultProps.cardBody)).not.toBeVisible();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('expandableSectionProps.isExpanded overrides isDefaultExpanded', () => {
|
|
127
|
+
render(<ToolResponse {...defaultProps} isDefaultExpanded={false} expandableSectionProps={{ isExpanded: true }} />);
|
|
128
|
+
|
|
129
|
+
expect(screen.getByRole('button', { name: defaultProps.toggleContent })).toHaveAttribute('aria-expanded', 'true');
|
|
130
|
+
expect(screen.getByText(defaultProps.cardTitle)).toBeVisible();
|
|
131
|
+
expect(screen.getByText(defaultProps.cardBody)).toBeVisible();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('expandableSectionProps.onToggle overrides internal onToggle behavior', async () => {
|
|
135
|
+
const user = userEvent.setup();
|
|
136
|
+
const customOnToggle = jest.fn();
|
|
137
|
+
|
|
138
|
+
render(
|
|
139
|
+
<ToolResponse {...defaultProps} isDefaultExpanded={false} expandableSectionProps={{ onToggle: customOnToggle }} />
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
const toggleButton = screen.getByRole('button', { name: defaultProps.toggleContent });
|
|
143
|
+
expect(toggleButton).toHaveAttribute('aria-expanded', 'false');
|
|
144
|
+
|
|
145
|
+
await user.click(toggleButton);
|
|
146
|
+
|
|
147
|
+
expect(customOnToggle).toHaveBeenCalledTimes(1);
|
|
148
|
+
expect(toggleButton).toHaveAttribute('aria-expanded', 'false');
|
|
149
|
+
expect(screen.getByText(defaultProps.cardTitle)).not.toBeVisible();
|
|
150
|
+
expect(screen.getByText(defaultProps.cardBody)).not.toBeVisible();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('should render toggleContent as markdown when isToggleContentMarkdown is true', () => {
|
|
154
|
+
const toggleContent = '**Bold toggle**';
|
|
155
|
+
const { container } = render(
|
|
156
|
+
<ToolResponse {...defaultProps} toggleContent={toggleContent} isToggleContentMarkdown />
|
|
157
|
+
);
|
|
158
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
159
|
+
expect(screen.getByText('Bold toggle')).toBeTruthy();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should not render toggleContent as markdown when isToggleContentMarkdown is false', () => {
|
|
163
|
+
const toggleContent = '**Bold toggle**';
|
|
164
|
+
render(<ToolResponse {...defaultProps} toggleContent={toggleContent} />);
|
|
165
|
+
expect(screen.getByText('**Bold toggle**')).toBeTruthy();
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should render subheading as markdown when isSubheadingMarkdown is true', () => {
|
|
169
|
+
const subheading = '**Bold subheading**';
|
|
170
|
+
const { container } = render(<ToolResponse {...defaultProps} subheading={subheading} isSubheadingMarkdown />);
|
|
171
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
172
|
+
expect(screen.getByText('Bold subheading')).toBeTruthy();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('should not render subheading as markdown when isSubheadingMarkdown is false', () => {
|
|
176
|
+
const subheading = '**Bold subheading**';
|
|
177
|
+
render(<ToolResponse {...defaultProps} subheading={subheading} />);
|
|
178
|
+
expect(screen.getByText('**Bold subheading**')).toBeTruthy();
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('should render body as markdown when isBodyMarkdown is true', () => {
|
|
182
|
+
const body = '**Bold body**';
|
|
183
|
+
const { container } = render(<ToolResponse {...defaultProps} body={body} isBodyMarkdown />);
|
|
184
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
185
|
+
expect(screen.getByText('Bold body')).toBeTruthy();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('should not render body as markdown when isBodyMarkdown is false', () => {
|
|
189
|
+
const body = '**Bold body**';
|
|
190
|
+
render(<ToolResponse {...defaultProps} body={body} />);
|
|
191
|
+
expect(screen.getByText('**Bold body**')).toBeTruthy();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('should render cardTitle as markdown when isCardTitleMarkdown is true', () => {
|
|
195
|
+
const cardTitle = '**Bold card title**';
|
|
196
|
+
const { container } = render(<ToolResponse {...defaultProps} cardTitle={cardTitle} isCardTitleMarkdown />);
|
|
197
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
198
|
+
expect(screen.getByText('Bold card title')).toBeTruthy();
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('should not render cardTitle as markdown when isCardTitleMarkdown is false', () => {
|
|
202
|
+
const cardTitle = '**Bold card title**';
|
|
203
|
+
render(<ToolResponse {...defaultProps} cardTitle={cardTitle} />);
|
|
204
|
+
expect(screen.getByText('**Bold card title**')).toBeTruthy();
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('should render cardBody as markdown when isCardBodyMarkdown is true', () => {
|
|
208
|
+
const cardBody = '**Bold card body**';
|
|
209
|
+
const { container } = render(<ToolResponse {...defaultProps} cardBody={cardBody} isCardBodyMarkdown />);
|
|
210
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
211
|
+
expect(screen.getByText('Bold card body')).toBeTruthy();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should not render cardBody as markdown when isCardBodyMarkdown is false', () => {
|
|
215
|
+
const cardBody = '**Bold card body**';
|
|
216
|
+
render(<ToolResponse {...defaultProps} cardBody={cardBody} />);
|
|
217
|
+
expect(screen.getByText('**Bold card body**')).toBeTruthy();
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('should pass markdownContentProps to MarkdownContent component', () => {
|
|
221
|
+
const body = '**Bold body**';
|
|
222
|
+
const { container } = render(
|
|
223
|
+
<ToolResponse {...defaultProps} body={body} isBodyMarkdown markdownContentProps={{ isPrimary: true }} />
|
|
224
|
+
);
|
|
225
|
+
expect(container.querySelector('.pf-m-primary')).toBeTruthy();
|
|
226
|
+
});
|
|
108
227
|
});
|