@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FunctionComponent } from 'react';
|
|
2
|
-
import { ButtonProps, DrawerProps, DrawerPanelContentProps, DrawerContentProps, DrawerContentBodyProps, DrawerHeadProps, DrawerActionsProps, DrawerCloseButtonProps, DrawerPanelBodyProps, SkeletonProps,
|
|
2
|
+
import { ButtonProps, DrawerProps, DrawerPanelContentProps, DrawerContentProps, DrawerContentBodyProps, DrawerHeadProps, DrawerActionsProps, DrawerCloseButtonProps, DrawerPanelBodyProps, SkeletonProps, TitleProps, SearchInputProps, MenuProps, MenuListProps, MenuItemProps, MenuGroupProps, MenuContentProps } from '@patternfly/react-core';
|
|
3
3
|
import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
|
|
4
4
|
import { HistoryEmptyStateProps } from './EmptyState';
|
|
5
5
|
export interface Conversation {
|
|
@@ -84,6 +84,8 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
|
84
84
|
drawerCloseButtonProps?: DrawerCloseButtonProps;
|
|
85
85
|
/** Additional props appleid to drawer panel body */
|
|
86
86
|
drawerPanelBodyProps?: DrawerPanelBodyProps;
|
|
87
|
+
/** Flag indicating whether a divider should render between the drawer head and title. */
|
|
88
|
+
hasDrawerHeadDivider?: boolean;
|
|
87
89
|
/** Whether to show drawer loading state */
|
|
88
90
|
isLoading?: boolean;
|
|
89
91
|
/** Additional props for loading state */
|
|
@@ -104,6 +106,12 @@ export interface ChatbotConversationHistoryNavProps extends DrawerProps {
|
|
|
104
106
|
navTitleProps?: Partial<TitleProps>;
|
|
105
107
|
/** Visually hidden text that gets announced by assistive technologies. Should be used to convey the result count when the search input value changes. */
|
|
106
108
|
searchInputScreenReaderText?: string;
|
|
109
|
+
/** Custom action rendered before the search input. */
|
|
110
|
+
searchActionStart?: React.ReactNode;
|
|
111
|
+
/** Custom action rendered after the search input. */
|
|
112
|
+
searchActionEnd?: React.ReactNode;
|
|
113
|
+
/** A custom search toolbar to render below the title. This will override the default search actions and/or search input. */
|
|
114
|
+
searchToolbar?: React.ReactNode;
|
|
107
115
|
/** Additional props passed to MenuContent */
|
|
108
116
|
menuContentProps?: Omit<MenuContentProps, 'ref'>;
|
|
109
117
|
}
|
|
@@ -12,14 +12,14 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
13
|
import { useRef, Fragment } from 'react';
|
|
14
14
|
// Import PatternFly components
|
|
15
|
-
import { Button, Drawer, DrawerPanelContent, DrawerContent, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton, DrawerContentBody, SearchInput, Title, Icon, MenuList, MenuGroup, MenuItem, Menu, MenuContent } from '@patternfly/react-core';
|
|
15
|
+
import { Button, Divider, Drawer, DrawerPanelContent, DrawerContent, DrawerPanelBody, DrawerHead, DrawerActions, DrawerCloseButton, DrawerContentBody, InputGroup, InputGroupItem, SearchInput, Title, Icon, MenuList, MenuGroup, MenuItem, Menu, MenuContent } from '@patternfly/react-core';
|
|
16
16
|
import { OutlinedClockIcon, OutlinedCommentAltIcon, PenToSquareIcon } from '@patternfly/react-icons';
|
|
17
17
|
import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
|
|
18
18
|
import ConversationHistoryDropdown from './ChatbotConversationHistoryDropdown';
|
|
19
19
|
import LoadingState from './LoadingState';
|
|
20
20
|
import HistoryEmptyState from './EmptyState';
|
|
21
21
|
export const ChatbotConversationHistoryNav = (_a) => {
|
|
22
|
-
var { onDrawerToggle, isDrawerOpen, setIsDrawerOpen, activeItemId, onSelectActiveItem, conversations, menuListProps, newChatButtonText = 'New chat', drawerContent, onNewChat, newChatButtonProps, searchInputPlaceholder = 'Search previous conversations...', searchInputAriaLabel = 'Search previous conversations', searchInputProps, handleTextInputChange, displayMode, reverseButtonOrder = false, drawerActionsTestId = 'chatbot-nav-drawer-actions', drawerPanelContentProps, drawerContentProps, drawerContentBodyProps, drawerHeadProps, drawerActionsProps, drawerCloseButtonProps, drawerPanelBodyProps, isLoading, loadingState, errorState, emptyState, noResultsState, isCompact, title = 'Chat history', navTitleProps, navTitleIcon = _jsx(OutlinedClockIcon, {}), searchInputScreenReaderText, menuProps, menuGroupProps, menuContentProps } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "menuListProps", "newChatButtonText", "drawerContent", "onNewChat", "newChatButtonProps", "searchInputPlaceholder", "searchInputAriaLabel", "searchInputProps", "handleTextInputChange", "displayMode", "reverseButtonOrder", "drawerActionsTestId", "drawerPanelContentProps", "drawerContentProps", "drawerContentBodyProps", "drawerHeadProps", "drawerActionsProps", "drawerCloseButtonProps", "drawerPanelBodyProps", "isLoading", "loadingState", "errorState", "emptyState", "noResultsState", "isCompact", "title", "navTitleProps", "navTitleIcon", "searchInputScreenReaderText", "menuProps", "menuGroupProps", "menuContentProps"]);
|
|
22
|
+
var { onDrawerToggle, isDrawerOpen, setIsDrawerOpen, activeItemId, onSelectActiveItem, conversations, menuListProps, newChatButtonText = 'New chat', drawerContent, onNewChat, newChatButtonProps, searchInputPlaceholder = 'Search previous conversations...', searchInputAriaLabel = 'Search previous conversations', searchInputProps, handleTextInputChange, displayMode, reverseButtonOrder = false, drawerActionsTestId = 'chatbot-nav-drawer-actions', drawerPanelContentProps, drawerContentProps, drawerContentBodyProps, drawerHeadProps, drawerActionsProps, drawerCloseButtonProps, drawerPanelBodyProps, hasDrawerHeadDivider, isLoading, loadingState, errorState, emptyState, noResultsState, isCompact, title = 'Chat history', navTitleProps, navTitleIcon = _jsx(OutlinedClockIcon, {}), searchInputScreenReaderText, searchActionStart, searchActionEnd, searchToolbar, menuProps, menuGroupProps, menuContentProps } = _a, props = __rest(_a, ["onDrawerToggle", "isDrawerOpen", "setIsDrawerOpen", "activeItemId", "onSelectActiveItem", "conversations", "menuListProps", "newChatButtonText", "drawerContent", "onNewChat", "newChatButtonProps", "searchInputPlaceholder", "searchInputAriaLabel", "searchInputProps", "handleTextInputChange", "displayMode", "reverseButtonOrder", "drawerActionsTestId", "drawerPanelContentProps", "drawerContentProps", "drawerContentBodyProps", "drawerHeadProps", "drawerActionsProps", "drawerCloseButtonProps", "drawerPanelBodyProps", "hasDrawerHeadDivider", "isLoading", "loadingState", "errorState", "emptyState", "noResultsState", "isCompact", "title", "navTitleProps", "navTitleIcon", "searchInputScreenReaderText", "searchActionStart", "searchActionEnd", "searchToolbar", "menuProps", "menuGroupProps", "menuContentProps"]);
|
|
23
23
|
const drawerRef = useRef(null);
|
|
24
24
|
const onExpand = () => {
|
|
25
25
|
drawerRef.current && drawerRef.current.focus();
|
|
@@ -64,8 +64,15 @@ export const ChatbotConversationHistoryNav = (_a) => {
|
|
|
64
64
|
return (_jsx(Menu, Object.assign({ isPlain: true, onSelect: onSelectActiveItem, activeItemId: activeItemId }, menuProps, { children: _jsx(MenuContent, Object.assign({}, menuContentProps, { children: buildConversations() })) })));
|
|
65
65
|
};
|
|
66
66
|
const renderDrawerContent = () => (_jsx(_Fragment, { children: _jsx(DrawerPanelBody, Object.assign({}, drawerPanelBodyProps, { children: renderMenuContent() })) }));
|
|
67
|
+
const searchInputContainer = handleTextInputChange && (_jsxs("div", { className: "pf-chatbot__input", children: [_jsx(SearchInput, Object.assign({ "aria-label": searchInputAriaLabel, onChange: (_event, value) => handleTextInputChange(value), placeholder: searchInputPlaceholder }, searchInputProps)), searchInputScreenReaderText && (_jsx("div", { className: "pf-chatbot__filter-announcement pf-chatbot-m-hidden", children: searchInputScreenReaderText }))] }));
|
|
68
|
+
const renderSearchAndActions = () => {
|
|
69
|
+
if (searchToolbar) {
|
|
70
|
+
return searchToolbar;
|
|
71
|
+
}
|
|
72
|
+
return searchActionStart || searchActionEnd ? (_jsx("div", { className: "pf-chatbot__history-search-actions", children: _jsxs(InputGroup, { children: [searchActionStart && _jsx(InputGroupItem, { children: searchActionStart }), searchInputContainer && _jsx(InputGroupItem, { isFill: true, children: searchInputContainer }), searchActionEnd && _jsx(InputGroupItem, { children: searchActionEnd })] }) })) : (searchInputContainer);
|
|
73
|
+
};
|
|
67
74
|
const renderPanelContent = () => {
|
|
68
|
-
const drawer = (_jsxs(_Fragment, { children: [_jsx(DrawerHead, Object.assign({}, drawerHeadProps, { children: _jsxs(DrawerActions, Object.assign({ "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' }, drawerActionsProps, { children: [_jsx(DrawerCloseButton, Object.assign({ onClick: onDrawerToggle }, drawerCloseButtonProps)), onNewChat && (_jsx(Button, Object.assign({ size: isCompact ? 'sm' : undefined, onClick: onNewChat, icon: _jsx(PenToSquareIcon, {}) }, newChatButtonProps, { children: newChatButtonText })))] })) })), _jsxs("div", { className: "pf-chatbot__heading-container", children: [_jsxs("div", { className: "pf-chatbot__title-container", children: [_jsx(Icon, { size: "lg", className: "pf-chatbot__title-icon", children: navTitleIcon }), _jsx(Title, Object.assign({ className: "pf-chatbot__title", headingLevel: "h2" }, navTitleProps, { children: title }))] }), !isLoading &&
|
|
75
|
+
const drawer = (_jsxs(_Fragment, { children: [_jsx(DrawerHead, Object.assign({}, drawerHeadProps, { children: _jsxs(DrawerActions, Object.assign({ "data-testid": drawerActionsTestId, className: reverseButtonOrder ? 'pf-v6-c-drawer__actions--reversed' : '' }, drawerActionsProps, { children: [_jsx(DrawerCloseButton, Object.assign({ onClick: onDrawerToggle }, drawerCloseButtonProps)), onNewChat && (_jsx(Button, Object.assign({ size: isCompact ? 'sm' : undefined, onClick: onNewChat, icon: _jsx(PenToSquareIcon, {}) }, newChatButtonProps, { children: newChatButtonText })))] })) })), hasDrawerHeadDivider && _jsx(Divider, { className: "pf-chatbot__heading-divider" }), _jsxs("div", { className: "pf-chatbot__heading-container", children: [_jsxs("div", { className: "pf-chatbot__title-container", children: [_jsx(Icon, { size: "lg", className: "pf-chatbot__title-icon", children: navTitleIcon }), _jsx(Title, Object.assign({ className: "pf-chatbot__title", headingLevel: "h2" }, navTitleProps, { children: title }))] }), !isLoading && renderSearchAndActions()] }), isLoading ? _jsx(LoadingState, Object.assign({}, loadingState)) : renderDrawerContent()] }));
|
|
69
76
|
return (_jsx(DrawerPanelContent, Object.assign({ "aria-live": "polite", focusTrap: { enabled: true }, defaultSize: "384px" }, drawerPanelContentProps, { children: drawer })));
|
|
70
77
|
};
|
|
71
78
|
// An onKeyDown property must be passed to the Drawer component to handle closing
|
|
@@ -222,6 +222,44 @@ describe('ChatbotConversationHistoryNav', () => {
|
|
|
222
222
|
render(_jsx(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: initialConversations, handleTextInputChange: jest.fn(), searchInputProps: { value: 'I am a sample search' } }));
|
|
223
223
|
expect(screen.getByRole('dialog', { name: /Chat history I am a sample search/i })).toBeInTheDocument();
|
|
224
224
|
});
|
|
225
|
+
it('Does not render search actions by default', () => {
|
|
226
|
+
var _a, _b;
|
|
227
|
+
const handleSearch = jest.fn();
|
|
228
|
+
const groupedConversations = {
|
|
229
|
+
Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
|
|
230
|
+
};
|
|
231
|
+
render(_jsx(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, conversations: groupedConversations, handleTextInputChange: handleSearch }));
|
|
232
|
+
const searchInput = screen.getByPlaceholderText(/Search/i);
|
|
233
|
+
expect((_a = searchInput.parentElement) === null || _a === void 0 ? void 0 : _a.previousElementSibling).toBeNull();
|
|
234
|
+
expect((_b = searchInput.parentElement) === null || _b === void 0 ? void 0 : _b.nextElementSibling).toBeNull();
|
|
235
|
+
});
|
|
236
|
+
it('Renders with action at start when searchActionStart is passed', () => {
|
|
237
|
+
const handleSearch = jest.fn();
|
|
238
|
+
const groupedConversations = {
|
|
239
|
+
Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
|
|
240
|
+
};
|
|
241
|
+
render(_jsx(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, conversations: groupedConversations, handleTextInputChange: handleSearch, searchActionStart: _jsx("div", { children: "Search action start test" }) }));
|
|
242
|
+
expect(screen.getByText('Search action start test')).toBeVisible();
|
|
243
|
+
});
|
|
244
|
+
it('Renders with action at end when searchActionEnd is passed', () => {
|
|
245
|
+
const handleSearch = jest.fn();
|
|
246
|
+
const groupedConversations = {
|
|
247
|
+
Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
|
|
248
|
+
};
|
|
249
|
+
render(_jsx(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, handleTextInputChange: handleSearch, conversations: groupedConversations, searchActionEnd: _jsx("div", { children: "Search action end test" }) }));
|
|
250
|
+
expect(screen.getByText('Search action end test')).toBeVisible();
|
|
251
|
+
});
|
|
252
|
+
it('Overrides default search input and actions when searchToolbar is passed', () => {
|
|
253
|
+
const handleSearch = jest.fn();
|
|
254
|
+
const groupedConversations = {
|
|
255
|
+
Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
|
|
256
|
+
};
|
|
257
|
+
render(_jsx(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), reverseButtonOrder: false, conversations: groupedConversations, handleTextInputChange: handleSearch, searchActionStart: _jsx("div", { children: "Search action start test" }), searchActionEnd: _jsx("div", { children: "Search action end test" }), searchToolbar: _jsx("div", { children: "Custom toolbar" }) }));
|
|
258
|
+
expect(screen.queryByPlaceholderText(/Search/i)).not.toBeInTheDocument();
|
|
259
|
+
expect(screen.queryByText('Search action start test')).not.toBeInTheDocument();
|
|
260
|
+
expect(screen.queryByText('Search action end test')).not.toBeInTheDocument();
|
|
261
|
+
expect(screen.getByText('Custom toolbar')).toBeInTheDocument();
|
|
262
|
+
});
|
|
225
263
|
it('overrides nav title heading level when navTitleProps.headingLevel is passed', () => {
|
|
226
264
|
render(_jsx(ChatbotConversationHistoryNav, { onDrawerToggle: onDrawerToggle, isDrawerOpen: true, displayMode: ChatbotDisplayMode.fullscreen, setIsDrawerOpen: jest.fn(), conversations: { Today: initialConversations }, navTitleProps: { headingLevel: 'h1' } }));
|
|
227
265
|
expect(screen.queryByRole('heading', { name: /Chat history/i, level: 2 })).not.toBeInTheDocument();
|
|
@@ -10,13 +10,40 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
-
import { forwardRef } from 'react';
|
|
13
|
+
import { forwardRef, useEffect, useMemo, useRef, useState } from 'react';
|
|
14
14
|
import { Button, Icon, Tooltip } from '@patternfly/react-core';
|
|
15
15
|
import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';
|
|
16
16
|
const ChatbotHeaderMenuBase = (_a) => {
|
|
17
17
|
var { className, onMenuToggle, tooltipProps, menuAriaLabel = 'Chat history menu', innerRef, tooltipContent = 'Chat history menu', isCompact } = _a, props = __rest(_a, ["className", "onMenuToggle", "tooltipProps", "menuAriaLabel", "innerRef", "tooltipContent", "isCompact"]);
|
|
18
|
-
|
|
18
|
+
const [isDrawerAnimating, setIsDrawerAnimating] = useState(false);
|
|
19
|
+
// I'd like to use a prop here later if this works
|
|
20
|
+
const drawerState = props['aria-expanded'];
|
|
21
|
+
const isDrawerOpen = drawerState === true;
|
|
22
|
+
const prevDrawerStateRef = useRef(isDrawerOpen);
|
|
23
|
+
const buttonRef = useRef(null);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (drawerState !== undefined) {
|
|
26
|
+
const wasDrawerOpen = prevDrawerStateRef.current === true;
|
|
27
|
+
const isDrawerClosing = wasDrawerOpen && !isDrawerOpen;
|
|
28
|
+
setIsDrawerAnimating(true);
|
|
29
|
+
const timeout = setTimeout(() => {
|
|
30
|
+
setIsDrawerAnimating(false);
|
|
31
|
+
if (isDrawerClosing) {
|
|
32
|
+
requestAnimationFrame(() => {
|
|
33
|
+
var _a;
|
|
34
|
+
(_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}, 350);
|
|
38
|
+
prevDrawerStateRef.current = isDrawerOpen;
|
|
39
|
+
return () => clearTimeout(timeout);
|
|
40
|
+
}
|
|
41
|
+
}, [drawerState, isDrawerOpen]);
|
|
42
|
+
const button = useMemo(() => (_jsx(Button, Object.assign({ className: `pf-chatbot__button--toggle-menu ${isCompact ? 'pf-m-compact' : ''}`, variant: "plain", onClick: onMenuToggle, "aria-label": menuAriaLabel, ref: innerRef !== null && innerRef !== void 0 ? innerRef : buttonRef, icon: _jsx(Icon, { size: isCompact ? 'lg' : 'xl', isInline: true, children: _jsx(BarsIcon, {}) }), size: isCompact ? 'sm' : undefined }, props))),
|
|
43
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
44
|
+
[isCompact, menuAriaLabel, onMenuToggle, innerRef, buttonRef]);
|
|
45
|
+
return (_jsx("div", { className: `pf-chatbot__menu ${className}`, children: isDrawerAnimating ? (button) : (_jsx(Tooltip, Object.assign({ content: tooltipContent, position: "bottom",
|
|
19
46
|
// prevents VO announcements of both aria label and tooltip
|
|
20
|
-
aria: "none" }, tooltipProps, { children:
|
|
47
|
+
aria: "none" }, tooltipProps, { children: button }))) }));
|
|
21
48
|
};
|
|
22
49
|
export const ChatbotHeaderMenu = forwardRef((props, ref) => (_jsx(ChatbotHeaderMenuBase, Object.assign({ innerRef: ref }, props))));
|
|
@@ -37,6 +37,8 @@ export interface CodeModalProps {
|
|
|
37
37
|
modalBodyClassName?: string;
|
|
38
38
|
/** Class applied to modal footer */
|
|
39
39
|
modalFooterClassName?: string;
|
|
40
|
+
/** Aria label applied to spinner when loading Monaco */
|
|
41
|
+
spinnerAriaLabel?: string;
|
|
40
42
|
}
|
|
41
43
|
export declare const CodeModal: FunctionComponent<CodeModalProps>;
|
|
42
44
|
export default CodeModal;
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
11
|
var t = {};
|
|
3
12
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -12,22 +21,45 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
21
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
22
|
import { useState, useEffect, useRef } from 'react';
|
|
14
23
|
import path from 'path-browserify';
|
|
15
|
-
import * as monaco from 'monaco-editor';
|
|
16
|
-
import { loader } from '@monaco-editor/react';
|
|
17
24
|
// Import PatternFly components
|
|
18
25
|
import { CodeEditor } from '@patternfly/react-code-editor';
|
|
19
|
-
import { Button, getResizeObserver, ModalBody, ModalFooter, ModalHeader, Stack, StackItem } from '@patternfly/react-core';
|
|
26
|
+
import { Bullseye, Button, getResizeObserver, ModalBody, ModalFooter, ModalHeader, Spinner, Stack, StackItem } from '@patternfly/react-core';
|
|
20
27
|
import FileDetails, { extensionToLanguage } from '../FileDetails';
|
|
21
28
|
import { ChatbotDisplayMode } from '../Chatbot';
|
|
22
29
|
import ChatbotModal from '../ChatbotModal/ChatbotModal';
|
|
23
|
-
//
|
|
24
|
-
|
|
30
|
+
// Try to lazy load - some consumers need to be below a certain bundle size, but can't use the CDN and don't have webpack
|
|
31
|
+
let monacoInstance = null;
|
|
32
|
+
const loadMonaco = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
if (!monacoInstance) {
|
|
34
|
+
const [monaco, { loader }] = yield Promise.all([import('monaco-editor'), import('@monaco-editor/react')]);
|
|
35
|
+
monacoInstance = monaco;
|
|
36
|
+
loader.config({ monaco });
|
|
37
|
+
}
|
|
38
|
+
return monacoInstance;
|
|
39
|
+
});
|
|
25
40
|
export const CodeModal = (_a) => {
|
|
26
|
-
var { fileName, code, codeEditorControlClassName: codeEditorClassName, handleModalToggle, isCopyEnabled, isLineNumbersVisible, isModalOpen, isReadOnly, onPrimaryAction, onSecondaryAction, primaryActionBtn, secondaryActionBtn, title, displayMode = ChatbotDisplayMode.default, isCompact, modalHeaderClassName, modalBodyClassName, modalFooterClassName } = _a, props = __rest(_a, ["fileName", "code", "codeEditorControlClassName", "handleModalToggle", "isCopyEnabled", "isLineNumbersVisible", "isModalOpen", "isReadOnly", "onPrimaryAction", "onSecondaryAction", "primaryActionBtn", "secondaryActionBtn", "title", "displayMode", "isCompact", "modalHeaderClassName", "modalBodyClassName", "modalFooterClassName"]);
|
|
41
|
+
var { fileName, code, codeEditorControlClassName: codeEditorClassName, handleModalToggle, isCopyEnabled, isLineNumbersVisible, isModalOpen, isReadOnly, onPrimaryAction, onSecondaryAction, primaryActionBtn, secondaryActionBtn, title, displayMode = ChatbotDisplayMode.default, isCompact, modalHeaderClassName, modalBodyClassName, modalFooterClassName, spinnerAriaLabel = 'Loading' } = _a, props = __rest(_a, ["fileName", "code", "codeEditorControlClassName", "handleModalToggle", "isCopyEnabled", "isLineNumbersVisible", "isModalOpen", "isReadOnly", "onPrimaryAction", "onSecondaryAction", "primaryActionBtn", "secondaryActionBtn", "title", "displayMode", "isCompact", "modalHeaderClassName", "modalBodyClassName", "modalFooterClassName", "spinnerAriaLabel"]);
|
|
27
42
|
const [newCode, setNewCode] = useState(code);
|
|
28
43
|
const [editorInstance, setEditorInstance] = useState(null);
|
|
29
44
|
const [isEditorReady, setIsEditorReady] = useState(false);
|
|
45
|
+
const [isMonacoLoading, setIsMonacoLoading] = useState(false);
|
|
46
|
+
const [isMonacoLoaded, setIsMonacoLoaded] = useState(false);
|
|
30
47
|
const containerRef = useRef(null);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (isModalOpen && !isMonacoLoaded && !isMonacoLoading) {
|
|
50
|
+
setIsMonacoLoading(true);
|
|
51
|
+
loadMonaco()
|
|
52
|
+
.then(() => {
|
|
53
|
+
setIsMonacoLoaded(true);
|
|
54
|
+
setIsMonacoLoading(false);
|
|
55
|
+
})
|
|
56
|
+
.catch((error) => {
|
|
57
|
+
// eslint-disable-next-line no-console
|
|
58
|
+
console.error('Failed to load Monaco editor:', error);
|
|
59
|
+
setIsMonacoLoading(false);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}, [isModalOpen, isMonacoLoaded, isMonacoLoading]);
|
|
31
63
|
useEffect(() => {
|
|
32
64
|
if (!isModalOpen || !isEditorReady || !editorInstance || !containerRef.current) {
|
|
33
65
|
return;
|
|
@@ -77,13 +109,22 @@ export const CodeModal = (_a) => {
|
|
|
77
109
|
setNewCode(value);
|
|
78
110
|
}
|
|
79
111
|
};
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
112
|
+
const renderMonacoEditor = () => {
|
|
113
|
+
if (isMonacoLoading) {
|
|
114
|
+
return (_jsx(Bullseye, { children: _jsx(Spinner, { "aria-label": spinnerAriaLabel }) }));
|
|
115
|
+
}
|
|
116
|
+
if (isMonacoLoaded) {
|
|
117
|
+
return (_jsx(CodeEditor, Object.assign({ isDarkTheme: true, isLineNumbersVisible: isLineNumbersVisible, isLanguageLabelVisible: true, isCopyEnabled: isCopyEnabled, isReadOnly: isReadOnly, code: newCode, language: extensionToLanguage[path.extname(fileName).slice(1)], onEditorDidMount: onEditorDidMount, onCodeChange: onCodeChange, className: codeEditorClassName, isFullHeight: true, options: {
|
|
118
|
+
glyphMargin: false,
|
|
119
|
+
folding: false,
|
|
120
|
+
// prevents Monaco from handling resizing itself
|
|
121
|
+
// was causing ResizeObserver issues
|
|
122
|
+
automaticLayout: false
|
|
123
|
+
} }, props)));
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
};
|
|
127
|
+
const modal = (_jsxs(ChatbotModal, { isOpen: isModalOpen, onClose: handleModalToggle, ouiaId: "CodeModal", "aria-labelledby": "code-modal-title", "aria-describedby": "code-modal", className: `pf-chatbot__code-modal ${isCompact ? 'pf-m-compact' : ''} pf-chatbot__code-modal--${displayMode}`, displayMode: displayMode, isCompact: isCompact, children: [_jsx(ModalHeader, { className: modalHeaderClassName, title: title, labelId: "code-modal-title" }), _jsx(ModalBody, { className: modalBodyClassName, id: "code-modal-body", children: _jsxs(Stack, { className: "pf-chatbot__code-modal-body", children: [_jsx(StackItem, { className: "pf-chatbot__code-modal-file-details", children: _jsx(FileDetails, { fileName: fileName }) }), _jsx("div", { className: "pf-v6-l-stack__item pf-chatbot__code-modal-editor", ref: containerRef, children: renderMonacoEditor() })] }) }), _jsxs(ModalFooter, { className: modalFooterClassName, children: [_jsx(Button, { isBlock: true, variant: "primary", onClick: handlePrimaryAction, form: "code-modal-form", children: primaryActionBtn }, "code-modal-primary"), _jsx(Button, { isBlock: true, variant: "link", onClick: handleSecondaryAction, children: secondaryActionBtn }, "code-modal-secondary")] })] }));
|
|
87
128
|
return modal;
|
|
88
129
|
};
|
|
89
130
|
export default CodeModal;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { CardBodyProps, CardProps, ExpandableSectionProps } from '@patternfly/react-core';
|
|
2
2
|
import { type FunctionComponent } from 'react';
|
|
3
|
+
import type { MarkdownContentProps } from '../MarkdownContent';
|
|
3
4
|
export interface DeepThinkingProps {
|
|
4
5
|
/** Toggle content shown for expandable section */
|
|
5
6
|
toggleContent: React.ReactNode;
|
|
7
|
+
/** Flag indicating whether the expandable content is expanded by default. */
|
|
8
|
+
isDefaultExpanded?: boolean;
|
|
6
9
|
/** Additional props passed to expandable section */
|
|
7
10
|
expandableSectionProps?: Omit<ExpandableSectionProps, 'ref'>;
|
|
8
11
|
/** Subheading rendered inside expandable section */
|
|
@@ -13,6 +16,16 @@ export interface DeepThinkingProps {
|
|
|
13
16
|
cardProps?: CardProps;
|
|
14
17
|
/** Additional props passed to main card body */
|
|
15
18
|
cardBodyProps?: CardBodyProps;
|
|
19
|
+
/** Whether to enable markdown rendering for toggleContent. When true and toggleContent is a string, it will be parsed as markdown. */
|
|
20
|
+
isToggleContentMarkdown?: boolean;
|
|
21
|
+
/** Whether to enable markdown rendering for subheading. When true, subheading will be parsed as markdown. */
|
|
22
|
+
isSubheadingMarkdown?: boolean;
|
|
23
|
+
/** Whether to enable markdown rendering for body. When true and body is a string, it will be parsed as markdown. */
|
|
24
|
+
isBodyMarkdown?: boolean;
|
|
25
|
+
/** Props passed to MarkdownContent component when markdown is enabled */
|
|
26
|
+
markdownContentProps?: Omit<MarkdownContentProps, 'content'>;
|
|
27
|
+
/** Whether to retain styles in the MarkdownContent component. Defaults to false. */
|
|
28
|
+
shouldRetainStyles?: boolean;
|
|
16
29
|
}
|
|
17
30
|
export declare const DeepThinking: FunctionComponent<DeepThinkingProps>;
|
|
18
31
|
export default DeepThinking;
|
|
@@ -4,11 +4,36 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
4
4
|
// ============================================================================
|
|
5
5
|
import { Card, CardBody, ExpandableSection } from '@patternfly/react-core';
|
|
6
6
|
import { useState } from 'react';
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import MarkdownContent from '../MarkdownContent';
|
|
8
|
+
export const DeepThinking = ({ body, cardProps, expandableSectionProps, subheading, toggleContent, isDefaultExpanded = true, cardBodyProps, isToggleContentMarkdown, isSubheadingMarkdown, isBodyMarkdown, markdownContentProps, shouldRetainStyles = false }) => {
|
|
9
|
+
const [isExpanded, setIsExpanded] = useState(isDefaultExpanded);
|
|
9
10
|
const onToggle = (_event, isExpanded) => {
|
|
10
11
|
setIsExpanded(isExpanded);
|
|
11
12
|
};
|
|
12
|
-
|
|
13
|
+
const renderToggleContent = () => {
|
|
14
|
+
if (isToggleContentMarkdown && typeof toggleContent === 'string') {
|
|
15
|
+
return (_jsx(MarkdownContent, Object.assign({ shouldRetainStyles: shouldRetainStyles, content: toggleContent }, markdownContentProps)));
|
|
16
|
+
}
|
|
17
|
+
return toggleContent;
|
|
18
|
+
};
|
|
19
|
+
const renderSubheading = () => {
|
|
20
|
+
if (!subheading) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
if (isSubheadingMarkdown) {
|
|
24
|
+
return _jsx(MarkdownContent, Object.assign({ shouldRetainStyles: shouldRetainStyles, content: subheading }, markdownContentProps));
|
|
25
|
+
}
|
|
26
|
+
return subheading;
|
|
27
|
+
};
|
|
28
|
+
const renderBody = () => {
|
|
29
|
+
if (!body) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
if (isBodyMarkdown && typeof body === 'string') {
|
|
33
|
+
return _jsx(MarkdownContent, Object.assign({ shouldRetainStyles: shouldRetainStyles, content: body }, markdownContentProps));
|
|
34
|
+
}
|
|
35
|
+
return body;
|
|
36
|
+
};
|
|
37
|
+
return (_jsx(Card, Object.assign({ isCompact: true, className: "pf-chatbot__deep-thinking" }, cardProps, { children: _jsx(CardBody, Object.assign({}, cardBodyProps, { children: _jsx(ExpandableSection, Object.assign({ toggleContent: renderToggleContent(), onToggle: onToggle, isExpanded: isExpanded, isIndented: true, className: "pf-chatbot__deep-thinking-expandable-section" }, expandableSectionProps, { children: _jsxs("div", { className: "pf-chatbot__deep-thinking-section", children: [subheading && (_jsx("div", { className: "pf-chatbot__deep-thinking-subheading", children: _jsx("span", { children: renderSubheading() }) })), body && _jsx("div", { className: "pf-chatbot__deep-thinking-body", children: renderBody() })] }) })) })) })));
|
|
13
38
|
};
|
|
14
39
|
export default DeepThinking;
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
11
|
import { render, screen } from '@testing-library/react';
|
|
12
|
+
import userEvent from '@testing-library/user-event';
|
|
3
13
|
import '@testing-library/jest-dom';
|
|
4
14
|
import DeepThinking from './DeepThinking';
|
|
5
15
|
describe('DeepThinking', () => {
|
|
@@ -40,4 +50,74 @@ describe('DeepThinking', () => {
|
|
|
40
50
|
const subheadingContainer = container.querySelector('.pf-chatbot__tool-response-subheading');
|
|
41
51
|
expect(subheadingContainer).toBeFalsy();
|
|
42
52
|
});
|
|
53
|
+
it('should pass through cardBodyProps', () => {
|
|
54
|
+
render(_jsx(DeepThinking, Object.assign({}, defaultProps, { body: "Thinking content", cardBodyProps: { className: 'custom-card-body-class' } })));
|
|
55
|
+
const cardBody = screen.getByText('Thinking content').closest('.pf-v6-c-card__body');
|
|
56
|
+
expect(cardBody).toHaveClass('custom-card-body-class');
|
|
57
|
+
});
|
|
58
|
+
it('Renders expanded by default', () => {
|
|
59
|
+
render(_jsx(DeepThinking, Object.assign({}, defaultProps, { body: "Thinking content" })));
|
|
60
|
+
expect(screen.getByRole('button', { name: defaultProps.toggleContent })).toHaveAttribute('aria-expanded', 'true');
|
|
61
|
+
expect(screen.getByText('Thinking content')).toBeVisible();
|
|
62
|
+
});
|
|
63
|
+
it('Renders collapsed when isDefaultExpanded is false', () => {
|
|
64
|
+
render(_jsx(DeepThinking, Object.assign({ isDefaultExpanded: false }, defaultProps, { body: "Thinking content" })));
|
|
65
|
+
expect(screen.getByRole('button', { name: defaultProps.toggleContent })).toHaveAttribute('aria-expanded', 'false');
|
|
66
|
+
expect(screen.getByText('Thinking content')).not.toBeVisible();
|
|
67
|
+
});
|
|
68
|
+
it('expandableSectionProps.isExpanded overrides isDefaultExpanded', () => {
|
|
69
|
+
render(_jsx(DeepThinking, Object.assign({}, defaultProps, { isDefaultExpanded: false, body: "Thinking content", expandableSectionProps: { isExpanded: true } })));
|
|
70
|
+
expect(screen.getByRole('button', { name: defaultProps.toggleContent })).toHaveAttribute('aria-expanded', 'true');
|
|
71
|
+
expect(screen.getByText('Thinking content')).toBeVisible();
|
|
72
|
+
});
|
|
73
|
+
it('expandableSectionProps.onToggle overrides internal onToggle behavior', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
const user = userEvent.setup();
|
|
75
|
+
const customOnToggle = jest.fn();
|
|
76
|
+
render(_jsx(DeepThinking, Object.assign({}, defaultProps, { isDefaultExpanded: false, body: "Thinking content", expandableSectionProps: { onToggle: customOnToggle } })));
|
|
77
|
+
const toggleButton = screen.getByRole('button', { name: defaultProps.toggleContent });
|
|
78
|
+
expect(toggleButton).toHaveAttribute('aria-expanded', 'false');
|
|
79
|
+
yield user.click(toggleButton);
|
|
80
|
+
expect(customOnToggle).toHaveBeenCalled();
|
|
81
|
+
expect(toggleButton).toHaveAttribute('aria-expanded', 'false');
|
|
82
|
+
expect(screen.getByText('Thinking content')).not.toBeVisible();
|
|
83
|
+
}));
|
|
84
|
+
it('should render toggleContent as markdown when isToggleContentMarkdown is true', () => {
|
|
85
|
+
const toggleContent = '**Bold thinking**';
|
|
86
|
+
const { container } = render(_jsx(DeepThinking, { toggleContent: toggleContent, isToggleContentMarkdown: true }));
|
|
87
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
88
|
+
expect(screen.getByText('Bold thinking')).toBeTruthy();
|
|
89
|
+
});
|
|
90
|
+
it('should not render toggleContent as markdown when isToggleContentMarkdown is false', () => {
|
|
91
|
+
const toggleContent = '**Bold thinking**';
|
|
92
|
+
const { container } = render(_jsx(DeepThinking, { toggleContent: toggleContent }));
|
|
93
|
+
expect(container.querySelector('strong')).toBeFalsy();
|
|
94
|
+
expect(screen.getByText('**Bold thinking**')).toBeTruthy();
|
|
95
|
+
});
|
|
96
|
+
it('should render subheading as markdown when isSubheadingMarkdown is true', () => {
|
|
97
|
+
const subheading = '**Bold subheading**';
|
|
98
|
+
const { container } = render(_jsx(DeepThinking, Object.assign({}, defaultProps, { subheading: subheading, isSubheadingMarkdown: true })));
|
|
99
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
100
|
+
expect(screen.getByText('Bold subheading')).toBeTruthy();
|
|
101
|
+
});
|
|
102
|
+
it('should not render subheading as markdown when isSubheadingMarkdown is false', () => {
|
|
103
|
+
const subheading = '**Bold subheading**';
|
|
104
|
+
render(_jsx(DeepThinking, Object.assign({}, defaultProps, { subheading: subheading })));
|
|
105
|
+
expect(screen.getByText('**Bold subheading**')).toBeTruthy();
|
|
106
|
+
});
|
|
107
|
+
it('should render body as markdown when isBodyMarkdown is true', () => {
|
|
108
|
+
const body = '**Bold body**';
|
|
109
|
+
const { container } = render(_jsx(DeepThinking, Object.assign({}, defaultProps, { body: body, isBodyMarkdown: true })));
|
|
110
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
111
|
+
expect(screen.getByText('Bold body')).toBeTruthy();
|
|
112
|
+
});
|
|
113
|
+
it('should not render body as markdown when isBodyMarkdown is false', () => {
|
|
114
|
+
const body = '**Bold body**';
|
|
115
|
+
render(_jsx(DeepThinking, Object.assign({}, defaultProps, { body: body })));
|
|
116
|
+
expect(screen.getByText('**Bold body**')).toBeTruthy();
|
|
117
|
+
});
|
|
118
|
+
it('should pass markdownContentProps to MarkdownContent component', () => {
|
|
119
|
+
const body = '**Bold body**';
|
|
120
|
+
const { container } = render(_jsx(DeepThinking, Object.assign({}, defaultProps, { body: body, isBodyMarkdown: true, markdownContentProps: { isPrimary: true } })));
|
|
121
|
+
expect(container.querySelector('.pf-m-primary')).toBeTruthy();
|
|
122
|
+
});
|
|
43
123
|
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type FunctionComponent, ReactNode } from 'react';
|
|
2
|
+
import { Options } from 'react-markdown';
|
|
3
|
+
import { CodeBlockMessageProps } from '../Message/CodeBlockMessage/CodeBlockMessage';
|
|
4
|
+
import { TableProps } from '@patternfly/react-table';
|
|
5
|
+
import 'highlight.js/styles/vs2015.css';
|
|
6
|
+
import { PluggableList } from 'unified';
|
|
7
|
+
import { ButtonProps } from '@patternfly/react-core';
|
|
8
|
+
/**
|
|
9
|
+
* MarkdownContent renders content either as plain text or with content with markdown support.
|
|
10
|
+
*
|
|
11
|
+
* Use this component when passing children to Message to customize its structure.
|
|
12
|
+
*/
|
|
13
|
+
export interface MarkdownContentProps {
|
|
14
|
+
/** The content to render. Supports markdown formatting by default, or plain text when isMarkdownDisabled is true. */
|
|
15
|
+
content?: string;
|
|
16
|
+
/** Disables markdown parsing, allowing only plain text input */
|
|
17
|
+
isMarkdownDisabled?: boolean;
|
|
18
|
+
/** Props for code blocks */
|
|
19
|
+
codeBlockProps?: CodeBlockMessageProps;
|
|
20
|
+
/** Props for table message. It is important to include a detailed aria-label that describes the purpose of the table. */
|
|
21
|
+
tableProps?: Required<Pick<TableProps, 'aria-label'>> & TableProps;
|
|
22
|
+
/** Additional rehype plugins passed from the consumer */
|
|
23
|
+
additionalRehypePlugins?: PluggableList;
|
|
24
|
+
/** Additional remark plugins passed from the consumer */
|
|
25
|
+
additionalRemarkPlugins?: PluggableList;
|
|
26
|
+
/** Whether to open links in message in new tab. */
|
|
27
|
+
openLinkInNewTab?: boolean;
|
|
28
|
+
/** Props for links */
|
|
29
|
+
linkProps?: ButtonProps;
|
|
30
|
+
/** Allows passing additional props down to markdown parser react-markdown, such as allowedElements and disallowedElements. See https://github.com/remarkjs/react-markdown?tab=readme-ov-file#options for options */
|
|
31
|
+
reactMarkdownProps?: Options;
|
|
32
|
+
/** Allows passing additional props down to remark-gfm. See https://github.com/remarkjs/remark-gfm?tab=readme-ov-file#options for options */
|
|
33
|
+
remarkGfmProps?: Options;
|
|
34
|
+
/** Whether to strip out images in markdown */
|
|
35
|
+
hasNoImages?: boolean;
|
|
36
|
+
/** Sets background colors to be appropriate on primary chatbot background */
|
|
37
|
+
isPrimary?: boolean;
|
|
38
|
+
/** Custom component to render when markdown is disabled */
|
|
39
|
+
textComponent?: ReactNode;
|
|
40
|
+
/** Flag indicating whether content should retain various styles of its context (typically font-size and text color). */
|
|
41
|
+
shouldRetainStyles?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare const MarkdownContent: FunctionComponent<MarkdownContentProps>;
|
|
44
|
+
export default MarkdownContent;
|