@patternfly/chatbot 6.5.0-prerelease.22 → 6.5.0-prerelease.24
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/DeepThinking/DeepThinking.d.ts +11 -0
- package/dist/cjs/DeepThinking/DeepThinking.js +30 -2
- package/dist/cjs/DeepThinking/DeepThinking.test.js +39 -0
- package/dist/cjs/MarkdownContent/MarkdownContent.d.ts +39 -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 +3 -2
- 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.js +2 -155
- 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 +2 -0
- package/dist/cjs/Message/UserFeedback/UserFeedback.js +5 -5
- package/dist/cjs/MessageBar/MessageBar.js +18 -4
- package/dist/cjs/ToolCall/ToolCall.d.ts +9 -0
- package/dist/cjs/ToolCall/ToolCall.js +19 -3
- package/dist/cjs/ToolCall/ToolCall.test.js +31 -0
- package/dist/cjs/ToolResponse/ToolResponse.d.ts +15 -0
- package/dist/cjs/ToolResponse/ToolResponse.js +48 -2
- package/dist/cjs/ToolResponse/ToolResponse.test.js +60 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +4 -1
- package/dist/css/main.css +82 -9
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/MarkdownContent/package.json +1 -0
- package/dist/esm/DeepThinking/DeepThinking.d.ts +11 -0
- package/dist/esm/DeepThinking/DeepThinking.js +27 -2
- package/dist/esm/DeepThinking/DeepThinking.test.js +39 -0
- package/dist/esm/MarkdownContent/MarkdownContent.d.ts +39 -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 +3 -2
- 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.js +3 -156
- 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 +2 -0
- package/dist/esm/Message/UserFeedback/UserFeedback.js +6 -6
- package/dist/esm/MessageBar/MessageBar.js +18 -4
- package/dist/esm/ToolCall/ToolCall.d.ts +9 -0
- package/dist/esm/ToolCall/ToolCall.js +16 -3
- package/dist/esm/ToolCall/ToolCall.test.js +31 -0
- package/dist/esm/ToolResponse/ToolResponse.d.ts +15 -0
- package/dist/esm/ToolResponse/ToolResponse.js +45 -2
- package/dist/esm/ToolResponse/ToolResponse.test.js +60 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- 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/Messages.md +32 -0
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +15 -1
- package/src/DeepThinking/DeepThinking.test.tsx +48 -0
- package/src/DeepThinking/DeepThinking.tsx +50 -4
- package/src/MarkdownContent/MarkdownContent.test.tsx +207 -0
- package/src/MarkdownContent/MarkdownContent.tsx +264 -0
- package/src/MarkdownContent/index.ts +2 -0
- package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +4 -0
- package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +5 -1
- 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.tsx +21 -181
- package/src/Message/QuickResponse/QuickResponse.scss +3 -1
- package/src/Message/TableMessage/TableMessage.scss +11 -0
- package/src/Message/TableMessage/TableMessage.tsx +18 -2
- package/src/Message/TextMessage/TextMessage.scss +8 -0
- package/src/Message/TextMessage/TextMessage.tsx +29 -2
- package/src/Message/UserFeedback/UserFeedback.scss +28 -1
- package/src/Message/UserFeedback/UserFeedback.tsx +22 -12
- package/src/MessageBar/AttachButton.scss +0 -1
- package/src/MessageBar/MessageBar.scss +11 -2
- package/src/MessageBar/MessageBar.tsx +22 -3
- package/src/MessageBar/MicrophoneButton.scss +0 -1
- package/src/MessageBar/SendButton.scss +0 -1
- package/src/MessageBar/StopButton.scss +0 -1
- package/src/ToolCall/ToolCall.test.tsx +40 -0
- package/src/ToolCall/ToolCall.tsx +37 -3
- package/src/ToolResponse/ToolResponse.scss +10 -0
- package/src/ToolResponse/ToolResponse.test.tsx +75 -0
- package/src/ToolResponse/ToolResponse.tsx +78 -6
- package/src/index.ts +3 -0
- package/src/main.scss +1 -0
|
@@ -17,15 +17,16 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
17
17
|
// ============================================================================
|
|
18
18
|
const react_core_1 = require("@patternfly/react-core");
|
|
19
19
|
const react_icons_1 = require("@patternfly/react-icons");
|
|
20
|
+
const react_styles_1 = require("@patternfly/react-styles");
|
|
20
21
|
const LinkMessage = (_a) => {
|
|
21
|
-
var { children, target, href, id } = _a, props = __rest(_a, ["children", "target", "href", "id"]);
|
|
22
|
+
var { children, target, href, id, shouldRetainStyles } = _a, props = __rest(_a, ["children", "target", "href", "id", "shouldRetainStyles"]);
|
|
22
23
|
if (target === '_blank') {
|
|
23
24
|
return ((0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ component: "a", variant: "link", href: href, icon: (0, jsx_runtime_1.jsx)(react_icons_1.ExternalLinkSquareAltIcon, {}), iconPosition: "end", isInline: true, target: target,
|
|
24
25
|
// need to explicitly call this out or id doesn't seem to get passed - required for footnotes
|
|
25
|
-
id: id }, props, { children: children })));
|
|
26
|
+
id: id }, props, { className: (0, react_styles_1.css)(shouldRetainStyles && 'pf-m-markdown', props === null || props === void 0 ? void 0 : props.className), children: children })));
|
|
26
27
|
}
|
|
27
28
|
return (
|
|
28
29
|
// need to explicitly call this out or id doesn't seem to get passed - required for footnotes
|
|
29
|
-
(0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ isInline: true, component: "a", href: href, variant: "link", id: id }, props, { children: children })));
|
|
30
|
+
(0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ isInline: true, component: "a", href: href, variant: "link", id: id }, props, { className: (0, react_styles_1.css)(shouldRetainStyles && 'pf-m-markdown', props === null || props === void 0 ? void 0 : props.className), children: children })));
|
|
30
31
|
};
|
|
31
32
|
exports.default = LinkMessage;
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
import { ExtraProps } from 'react-markdown';
|
|
2
|
-
|
|
2
|
+
export interface OrderedListMessageProps {
|
|
3
|
+
/** The ordered list content */
|
|
4
|
+
children?: React.ReactNode;
|
|
5
|
+
/** The number to start the ordered list at. */
|
|
6
|
+
start?: number;
|
|
7
|
+
/** Flag indicating that the content should retain message styles when using Markdown. */
|
|
8
|
+
shouldRetainStyles?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare const OrderedListMessage: ({ children, start, shouldRetainStyles }: OrderedListMessageProps & JSX.IntrinsicElements["ol"] & ExtraProps) => import("react/jsx-runtime").JSX.Element;
|
|
3
11
|
export default OrderedListMessage;
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
4
4
|
const react_core_1 = require("@patternfly/react-core");
|
|
5
|
-
const
|
|
5
|
+
const react_styles_1 = require("@patternfly/react-styles");
|
|
6
|
+
const OrderedListMessage = ({ children, start, shouldRetainStyles }) => ((0, jsx_runtime_1.jsx)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-ordered-list', shouldRetainStyles && 'pf-m-markdown'), children: (0, jsx_runtime_1.jsx)(react_core_1.List, { component: react_core_1.ListComponent.ol, type: react_core_1.OrderType.number, start: start, children: children }) }));
|
|
6
7
|
exports.default = OrderedListMessage;
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import { ExtraProps } from 'react-markdown';
|
|
2
|
-
|
|
2
|
+
export interface UnrderedListMessageProps {
|
|
3
|
+
/** The ordered list content */
|
|
4
|
+
children?: React.ReactNode;
|
|
5
|
+
/** Flag indicating that the content should retain message styles when using Markdown. */
|
|
6
|
+
shouldRetainStyles?: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare const UnorderedListMessage: ({ children, shouldRetainStyles }: UnrderedListMessageProps & JSX.IntrinsicElements["ul"] & ExtraProps) => import("react/jsx-runtime").JSX.Element;
|
|
3
9
|
export default UnorderedListMessage;
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
4
4
|
const react_core_1 = require("@patternfly/react-core");
|
|
5
|
-
const
|
|
5
|
+
const react_styles_1 = require("@patternfly/react-styles");
|
|
6
|
+
const UnorderedListMessage = ({ children, shouldRetainStyles }) => ((0, jsx_runtime_1.jsx)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-unordered-list', shouldRetainStyles && 'pf-m-markdown'), children: (0, jsx_runtime_1.jsx)(react_core_1.List, { children: children }) }));
|
|
6
7
|
exports.default = UnorderedListMessage;
|
|
@@ -20,43 +20,23 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
20
20
|
// Chatbot Main - Message
|
|
21
21
|
// ============================================================================
|
|
22
22
|
const react_1 = require("react");
|
|
23
|
-
const react_markdown_1 = __importDefault(require("react-markdown"));
|
|
24
|
-
const remark_gfm_1 = __importDefault(require("remark-gfm"));
|
|
25
23
|
const react_core_1 = require("@patternfly/react-core");
|
|
26
24
|
const MessageLoading_1 = __importDefault(require("./MessageLoading"));
|
|
27
|
-
const CodeBlockMessage_1 = __importDefault(require("./CodeBlockMessage/CodeBlockMessage"));
|
|
28
|
-
const TextMessage_1 = __importDefault(require("./TextMessage/TextMessage"));
|
|
29
25
|
const FileDetailsLabel_1 = __importDefault(require("../FileDetailsLabel/FileDetailsLabel"));
|
|
30
26
|
const ResponseActions_1 = __importDefault(require("../ResponseActions/ResponseActions"));
|
|
31
27
|
const SourcesCard_1 = __importDefault(require("../SourcesCard"));
|
|
32
|
-
const ListItemMessage_1 = __importDefault(require("./ListMessage/ListItemMessage"));
|
|
33
|
-
const UnorderedListMessage_1 = __importDefault(require("./ListMessage/UnorderedListMessage"));
|
|
34
|
-
const OrderedListMessage_1 = __importDefault(require("./ListMessage/OrderedListMessage"));
|
|
35
28
|
const QuickStartTile_1 = __importDefault(require("./QuickStarts/QuickStartTile"));
|
|
36
29
|
const QuickResponse_1 = __importDefault(require("./QuickResponse/QuickResponse"));
|
|
37
30
|
const UserFeedback_1 = __importDefault(require("./UserFeedback/UserFeedback"));
|
|
38
31
|
const UserFeedbackComplete_1 = __importDefault(require("./UserFeedback/UserFeedbackComplete"));
|
|
39
|
-
const TableMessage_1 = __importDefault(require("./TableMessage/TableMessage"));
|
|
40
|
-
const TrMessage_1 = __importDefault(require("./TableMessage/TrMessage"));
|
|
41
|
-
const TdMessage_1 = __importDefault(require("./TableMessage/TdMessage"));
|
|
42
|
-
const TbodyMessage_1 = __importDefault(require("./TableMessage/TbodyMessage"));
|
|
43
|
-
const TheadMessage_1 = __importDefault(require("./TableMessage/TheadMessage"));
|
|
44
|
-
const ThMessage_1 = __importDefault(require("./TableMessage/ThMessage"));
|
|
45
|
-
const ImageMessage_1 = __importDefault(require("./ImageMessage/ImageMessage"));
|
|
46
|
-
const rehype_unwrap_images_1 = __importDefault(require("rehype-unwrap-images"));
|
|
47
|
-
const rehype_external_links_1 = __importDefault(require("rehype-external-links"));
|
|
48
|
-
const rehype_sanitize_1 = __importDefault(require("rehype-sanitize"));
|
|
49
|
-
const rehype_highlight_1 = __importDefault(require("rehype-highlight"));
|
|
50
32
|
// see the full list of styles here: https://highlightjs.org/examples
|
|
51
33
|
require("highlight.js/styles/vs2015.css");
|
|
52
|
-
const LinkMessage_1 = __importDefault(require("./LinkMessage/LinkMessage"));
|
|
53
34
|
const ErrorMessage_1 = __importDefault(require("./ErrorMessage/ErrorMessage"));
|
|
54
35
|
const MessageInput_1 = __importDefault(require("./MessageInput"));
|
|
55
|
-
const rehypeMoveImagesOutOfParagraphs_1 = require("./Plugins/rehypeMoveImagesOutOfParagraphs");
|
|
56
36
|
const ToolResponse_1 = __importDefault(require("../ToolResponse"));
|
|
57
37
|
const DeepThinking_1 = __importDefault(require("../DeepThinking"));
|
|
58
|
-
const SuperscriptMessage_1 = __importDefault(require("./SuperscriptMessage/SuperscriptMessage"));
|
|
59
38
|
const ToolCall_1 = __importDefault(require("../ToolCall"));
|
|
39
|
+
const MarkdownContent_1 = __importDefault(require("../MarkdownContent"));
|
|
60
40
|
const MessageBase = (_a) => {
|
|
61
41
|
var { role, content, extraContent, name, avatar, timestamp, isLoading, actions, persistActionSelection, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts, userFeedbackForm, userFeedbackComplete, isLiveRegion = true, innerRef, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], additionalRemarkPlugins = [], linkProps, error, isEditable, editPlaceholder = 'Edit prompt message...', updateWord = 'Update', cancelWord = 'Cancel', onEditUpdate, onEditCancel, inputRef, editFormProps, isCompact, isMarkdownDisabled, reactMarkdownProps, toolResponse, deepThinking, remarkGfmProps, toolCall, hasNoImagesInUserMessages = true, isPrimary } = _a, props = __rest(_a, ["role", "content", "extraContent", "name", "avatar", "timestamp", "isLoading", "actions", "persistActionSelection", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts", "userFeedbackForm", "userFeedbackComplete", "isLiveRegion", "innerRef", "tableProps", "openLinkInNewTab", "additionalRehypePlugins", "additionalRemarkPlugins", "linkProps", "error", "isEditable", "editPlaceholder", "updateWord", "cancelWord", "onEditUpdate", "onEditCancel", "inputRef", "editFormProps", "isCompact", "isMarkdownDisabled", "reactMarkdownProps", "toolResponse", "deepThinking", "remarkGfmProps", "toolCall", "hasNoImagesInUserMessages", "isPrimary"]);
|
|
62
42
|
const [messageText, setMessageText] = (0, react_1.useState)(content);
|
|
@@ -64,13 +44,6 @@ const MessageBase = (_a) => {
|
|
|
64
44
|
setMessageText(content);
|
|
65
45
|
}, [content]);
|
|
66
46
|
const { beforeMainContent, afterMainContent, endContent } = extraContent || {};
|
|
67
|
-
let rehypePlugins = [rehype_unwrap_images_1.default, rehypeMoveImagesOutOfParagraphs_1.rehypeMoveImagesOutOfParagraphs, rehype_highlight_1.default];
|
|
68
|
-
if (openLinkInNewTab) {
|
|
69
|
-
rehypePlugins = rehypePlugins.concat([[rehype_external_links_1.default, { target: '_blank' }, rehype_sanitize_1.default]]);
|
|
70
|
-
}
|
|
71
|
-
if (additionalRehypePlugins) {
|
|
72
|
-
rehypePlugins.push(...additionalRehypePlugins);
|
|
73
|
-
}
|
|
74
47
|
let avatarClassName;
|
|
75
48
|
if (avatarProps && 'className' in avatarProps) {
|
|
76
49
|
const { className } = avatarProps, rest = __rest(avatarProps, ["className"]);
|
|
@@ -80,133 +53,7 @@ const MessageBase = (_a) => {
|
|
|
80
53
|
// Keep timestamps consistent between Timestamp component and aria-label
|
|
81
54
|
const date = new Date();
|
|
82
55
|
const dateString = timestamp !== null && timestamp !== void 0 ? timestamp : `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
|
|
83
|
-
const
|
|
84
|
-
if (reactMarkdownProps && reactMarkdownProps.disallowedElements) {
|
|
85
|
-
disallowedElements.push(...reactMarkdownProps.disallowedElements);
|
|
86
|
-
}
|
|
87
|
-
const handleMarkdown = () => {
|
|
88
|
-
if (isMarkdownDisabled) {
|
|
89
|
-
return ((0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.p }, props, { children: messageText })));
|
|
90
|
-
}
|
|
91
|
-
return ((0, jsx_runtime_1.jsx)(react_markdown_1.default, Object.assign({ components: {
|
|
92
|
-
section: (props) => {
|
|
93
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
94
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
95
|
-
return (0, jsx_runtime_1.jsx)("section", Object.assign({}, rest, { className: `pf-chatbot__message-text ${rest === null || rest === void 0 ? void 0 : rest.className}` }));
|
|
96
|
-
},
|
|
97
|
-
p: (props) => {
|
|
98
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
99
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
100
|
-
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.p }, rest, { isPrimary: isPrimary }));
|
|
101
|
-
},
|
|
102
|
-
code: (_a) => {
|
|
103
|
-
var { children } = _a, props = __rest(_a, ["children"]);
|
|
104
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
105
|
-
const { node } = props, codeProps = __rest(props, ["node"]);
|
|
106
|
-
return ((0, jsx_runtime_1.jsx)(CodeBlockMessage_1.default, Object.assign({}, codeProps, codeBlockProps, { isPrimary: isPrimary, children: children })));
|
|
107
|
-
},
|
|
108
|
-
h1: (props) => {
|
|
109
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
110
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
111
|
-
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h1 }, rest));
|
|
112
|
-
},
|
|
113
|
-
h2: (props) => {
|
|
114
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
115
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
116
|
-
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h2 }, rest));
|
|
117
|
-
},
|
|
118
|
-
h3: (props) => {
|
|
119
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
120
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
121
|
-
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h3 }, rest));
|
|
122
|
-
},
|
|
123
|
-
h4: (props) => {
|
|
124
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
125
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
126
|
-
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h4 }, rest));
|
|
127
|
-
},
|
|
128
|
-
h5: (props) => {
|
|
129
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
130
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
131
|
-
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h5 }, rest));
|
|
132
|
-
},
|
|
133
|
-
h6: (props) => {
|
|
134
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
135
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
136
|
-
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.h6 }, rest));
|
|
137
|
-
},
|
|
138
|
-
blockquote: (props) => {
|
|
139
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
140
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
141
|
-
return (0, jsx_runtime_1.jsx)(TextMessage_1.default, Object.assign({ component: react_core_1.ContentVariants.blockquote }, rest));
|
|
142
|
-
},
|
|
143
|
-
ul: (props) => {
|
|
144
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
145
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
146
|
-
return (0, jsx_runtime_1.jsx)(UnorderedListMessage_1.default, Object.assign({}, rest));
|
|
147
|
-
},
|
|
148
|
-
ol: (props) => {
|
|
149
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
150
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
151
|
-
return (0, jsx_runtime_1.jsx)(OrderedListMessage_1.default, Object.assign({}, rest));
|
|
152
|
-
},
|
|
153
|
-
li: (props) => {
|
|
154
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
155
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
156
|
-
return (0, jsx_runtime_1.jsx)(ListItemMessage_1.default, Object.assign({}, rest));
|
|
157
|
-
},
|
|
158
|
-
// table requires node attribute for calculating headers for mobile breakpoint
|
|
159
|
-
table: (props) => (0, jsx_runtime_1.jsx)(TableMessage_1.default, Object.assign({}, props, tableProps, { isPrimary: isPrimary })),
|
|
160
|
-
tbody: (props) => {
|
|
161
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
162
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
163
|
-
return (0, jsx_runtime_1.jsx)(TbodyMessage_1.default, Object.assign({}, rest));
|
|
164
|
-
},
|
|
165
|
-
thead: (props) => {
|
|
166
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
167
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
168
|
-
return (0, jsx_runtime_1.jsx)(TheadMessage_1.default, Object.assign({}, rest));
|
|
169
|
-
},
|
|
170
|
-
tr: (props) => {
|
|
171
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
172
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
173
|
-
return (0, jsx_runtime_1.jsx)(TrMessage_1.default, Object.assign({}, rest));
|
|
174
|
-
},
|
|
175
|
-
td: (props) => {
|
|
176
|
-
// Conflicts with Td type
|
|
177
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
178
|
-
const { node, width } = props, rest = __rest(props, ["node", "width"]);
|
|
179
|
-
return (0, jsx_runtime_1.jsx)(TdMessage_1.default, Object.assign({}, rest));
|
|
180
|
-
},
|
|
181
|
-
th: (props) => {
|
|
182
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
183
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
184
|
-
return (0, jsx_runtime_1.jsx)(ThMessage_1.default, Object.assign({}, rest));
|
|
185
|
-
},
|
|
186
|
-
img: (props) => {
|
|
187
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
188
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
189
|
-
return (0, jsx_runtime_1.jsx)(ImageMessage_1.default, Object.assign({}, rest));
|
|
190
|
-
},
|
|
191
|
-
a: (props) => {
|
|
192
|
-
// node is just the details of the document structure - not needed
|
|
193
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
194
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
195
|
-
return (
|
|
196
|
-
// some a types conflict with ButtonProps, but it's ok because we are using an a tag
|
|
197
|
-
// there are too many to handle manually
|
|
198
|
-
(0, jsx_runtime_1.jsx)(LinkMessage_1.default, Object.assign({}, rest, linkProps, { children: props.children })));
|
|
199
|
-
},
|
|
200
|
-
// used for footnotes
|
|
201
|
-
sup: (props) => {
|
|
202
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
203
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
204
|
-
return (0, jsx_runtime_1.jsx)(SuperscriptMessage_1.default, Object.assign({}, rest));
|
|
205
|
-
}
|
|
206
|
-
}, remarkPlugins: [[remark_gfm_1.default, Object.assign({}, remarkGfmProps)], ...additionalRemarkPlugins], rehypePlugins: rehypePlugins }, reactMarkdownProps, { remarkRehypeOptions: Object.assign({
|
|
207
|
-
// removes sr-only class from footnote labels applied by default
|
|
208
|
-
footnoteLabelProperties: { className: [''] } }, reactMarkdownProps === null || reactMarkdownProps === void 0 ? void 0 : reactMarkdownProps.remarkRehypeOptions), disallowedElements: disallowedElements, children: messageText })));
|
|
209
|
-
};
|
|
56
|
+
const handleMarkdown = () => ((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, { content: messageText, isMarkdownDisabled: isMarkdownDisabled, codeBlockProps: codeBlockProps, tableProps: tableProps, openLinkInNewTab: openLinkInNewTab, additionalRehypePlugins: additionalRehypePlugins, additionalRemarkPlugins: additionalRemarkPlugins, linkProps: linkProps, reactMarkdownProps: reactMarkdownProps, remarkGfmProps: remarkGfmProps, hasNoImages: role === 'user' && hasNoImagesInUserMessages, isPrimary: isPrimary }));
|
|
210
57
|
const renderMessage = () => {
|
|
211
58
|
if (isLoading) {
|
|
212
59
|
return (0, jsx_runtime_1.jsx)(MessageLoading_1.default, { loadingWord: loadingWord, isPrimary: isPrimary });
|
|
@@ -16,7 +16,12 @@ export interface TableNode {
|
|
|
16
16
|
type: string;
|
|
17
17
|
}
|
|
18
18
|
export interface TableMessageProps {
|
|
19
|
+
/** Content of the table */
|
|
20
|
+
children?: React.ReactNode;
|
|
21
|
+
/** Flag indicating whether primary styles should be applied. */
|
|
19
22
|
isPrimary?: boolean;
|
|
23
|
+
/** Flag indicating that the content should retain message styles when using Markdown. */
|
|
24
|
+
shouldRetainStyles?: boolean;
|
|
20
25
|
}
|
|
21
|
-
declare const TableMessage: ({ children, isPrimary, ...props }: Omit<TableProps, "ref"> & ExtraProps & TableMessageProps) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
declare const TableMessage: ({ children, isPrimary, shouldRetainStyles, ...props }: Omit<TableProps, "ref"> & ExtraProps & TableMessageProps) => import("react/jsx-runtime").JSX.Element;
|
|
22
27
|
export default TableMessage;
|
|
@@ -17,9 +17,10 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
17
17
|
// ============================================================================
|
|
18
18
|
const react_1 = require("react");
|
|
19
19
|
const react_table_1 = require("@patternfly/react-table");
|
|
20
|
+
const react_styles_1 = require("@patternfly/react-styles");
|
|
20
21
|
const TableMessage = (_a) => {
|
|
21
22
|
var _b;
|
|
22
|
-
var { children, isPrimary } = _a, props = __rest(_a, ["children", "isPrimary"]);
|
|
23
|
+
var { children, isPrimary, shouldRetainStyles } = _a, props = __rest(_a, ["children", "isPrimary", "shouldRetainStyles"]);
|
|
23
24
|
const { className } = props, rest = __rest(props, ["className"]);
|
|
24
25
|
// This allows us to parse the nested data we get back from the 3rd party Markdown parser
|
|
25
26
|
// Open to feedback here if there is a better way to do this
|
|
@@ -60,6 +61,6 @@ const TableMessage = (_a) => {
|
|
|
60
61
|
}
|
|
61
62
|
return (
|
|
62
63
|
// gridBreakPoint is so we show mobile-styled-PF table
|
|
63
|
-
(0, jsx_runtime_1.jsx)(react_table_1.Table, Object.assign({ "aria-label": props['aria-label'], gridBreakPoint: "grid", className:
|
|
64
|
+
(0, jsx_runtime_1.jsx)(react_table_1.Table, Object.assign({ "aria-label": props['aria-label'], gridBreakPoint: "grid", className: (0, react_styles_1.css)('pf-chatbot__message-table', isPrimary && 'pf-m-primary', shouldRetainStyles && 'pf-m-markdown', className) }, rest, { children: modifyChildren(children) })));
|
|
64
65
|
};
|
|
65
66
|
exports.default = TableMessage;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { ExtraProps } from 'react-markdown';
|
|
2
2
|
import { ContentProps } from '@patternfly/react-core';
|
|
3
3
|
export interface TextMessageProps {
|
|
4
|
+
/** The text message content */
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
/** Flag indicating whether primary styling is applied. */
|
|
4
7
|
isPrimary?: boolean;
|
|
8
|
+
/** The wrapper component to use for the PatternFly Content component. Defaults to a div. */
|
|
9
|
+
component?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'a' | 'small' | 'blockquote' | 'pre' | 'hr' | 'ul' | 'ol' | 'dl' | 'li' | 'dt' | 'dd';
|
|
10
|
+
/** Flag indicating that the content should retain message styles when using Markdown. */
|
|
11
|
+
shouldRetainStyles?: boolean;
|
|
5
12
|
}
|
|
6
|
-
declare const TextMessage: ({ component, children, isPrimary, ...props }: Omit<ContentProps, "ref"> & ExtraProps & TextMessageProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
declare const TextMessage: ({ component, children, isPrimary, shouldRetainStyles, ...props }: Omit<ContentProps, "ref"> & ExtraProps & TextMessageProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
14
|
export default TextMessage;
|
|
@@ -13,8 +13,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
15
15
|
const react_core_1 = require("@patternfly/react-core");
|
|
16
|
+
const react_styles_1 = require("@patternfly/react-styles");
|
|
16
17
|
const TextMessage = (_a) => {
|
|
17
|
-
var { component, children, isPrimary } = _a, props = __rest(_a, ["component", "children", "isPrimary"]);
|
|
18
|
-
return ((0, jsx_runtime_1.jsx)("span", { className:
|
|
18
|
+
var { component, children, isPrimary, shouldRetainStyles } = _a, props = __rest(_a, ["component", "children", "isPrimary", "shouldRetainStyles"]);
|
|
19
|
+
return ((0, jsx_runtime_1.jsx)("span", { className: (0, react_styles_1.css)('pf-chatbot__message-text', isPrimary && 'pf-m-primary', shouldRetainStyles && 'pf-m-markdown'), children: (0, jsx_runtime_1.jsx)(react_core_1.Content, Object.assign({ component: component }, props, { className: (0, react_styles_1.css)(props === null || props === void 0 ? void 0 : props.className), children: children })) }));
|
|
19
20
|
};
|
|
20
21
|
exports.default = TextMessage;
|
|
@@ -48,6 +48,8 @@ export interface UserFeedbackProps extends Omit<CardProps, 'onSubmit'>, OUIAProp
|
|
|
48
48
|
textAreaProps?: TextAreaProps;
|
|
49
49
|
/** Additional props passed to action group */
|
|
50
50
|
actionGroupProps?: ActionGroupProps;
|
|
51
|
+
/** Optional privacy statement text displayed under text area */
|
|
52
|
+
privacyStatement?: string;
|
|
51
53
|
}
|
|
52
54
|
declare const UserFeedback: FunctionComponent<UserFeedbackProps>;
|
|
53
55
|
export default UserFeedback;
|
|
@@ -21,7 +21,7 @@ const react_core_1 = require("@patternfly/react-core");
|
|
|
21
21
|
const QuickResponse_1 = __importDefault(require("../QuickResponse/QuickResponse"));
|
|
22
22
|
const CloseButton_1 = __importDefault(require("./CloseButton"));
|
|
23
23
|
const UserFeedback = (_a) => {
|
|
24
|
-
var { className, timestamp, title = 'Why did you choose this rating?', hasTextArea, textAreaAriaLabel = `Provide optional additional feedback for message received at ${timestamp}`, textAreaPlaceholder = 'Provide optional additional feedback', onTextAreaChange, submitWord = 'Submit', quickResponses, quickResponseContainerProps = { 'aria-label': `Quick feedback for message received at ${timestamp}` }, onSubmit, onClose, closeButtonAriaLabel = `Close feedback for message received at ${timestamp}`, id, headingLevel: HeadingLevel = 'h1', focusOnLoad = true, isCompact, children, cardHeaderProps, cardBodyProps, headingLevelProps, formProps, textAreaProps, actionGroupProps, submitButtonProps } = _a, props = __rest(_a, ["className", "timestamp", "title", "hasTextArea", "textAreaAriaLabel", "textAreaPlaceholder", "onTextAreaChange", "submitWord", "quickResponses", "quickResponseContainerProps", "onSubmit", "onClose", "closeButtonAriaLabel", "id", "headingLevel", "focusOnLoad", "isCompact", "children", "cardHeaderProps", "cardBodyProps", "headingLevelProps", "formProps", "textAreaProps", "actionGroupProps", "submitButtonProps"]);
|
|
24
|
+
var { className, timestamp, title = 'Why did you choose this rating?', hasTextArea, textAreaAriaLabel = `Provide optional additional feedback for message received at ${timestamp}`, textAreaPlaceholder = 'Provide optional additional feedback', onTextAreaChange, submitWord = 'Submit', quickResponses, quickResponseContainerProps = { 'aria-label': `Quick feedback for message received at ${timestamp}` }, onSubmit, onClose, closeButtonAriaLabel = `Close feedback for message received at ${timestamp}`, id, headingLevel: HeadingLevel = 'h1', focusOnLoad = true, isCompact, children, cardHeaderProps, cardBodyProps, headingLevelProps, formProps, textAreaProps, actionGroupProps, submitButtonProps, privacyStatement } = _a, props = __rest(_a, ["className", "timestamp", "title", "hasTextArea", "textAreaAriaLabel", "textAreaPlaceholder", "onTextAreaChange", "submitWord", "quickResponses", "quickResponseContainerProps", "onSubmit", "onClose", "closeButtonAriaLabel", "id", "headingLevel", "focusOnLoad", "isCompact", "children", "cardHeaderProps", "cardBodyProps", "headingLevelProps", "formProps", "textAreaProps", "actionGroupProps", "submitButtonProps", "privacyStatement"]);
|
|
25
25
|
const [selectedResponse, setSelectedResponse] = (0, react_1.useState)();
|
|
26
26
|
const [value, setValue] = (0, react_1.useState)('');
|
|
27
27
|
const divRef = (0, react_1.useRef)(null);
|
|
@@ -35,9 +35,9 @@ const UserFeedback = (_a) => {
|
|
|
35
35
|
/* card does not have ref forwarding; hence wrapper div */
|
|
36
36
|
(0, jsx_runtime_1.jsx)("div", { ref: divRef, id: id, tabIndex: 0, "aria-label": title, children: (0, jsx_runtime_1.jsxs)(react_core_1.Card, Object.assign({ isCompact: isCompact, className: `pf-chatbot__feedback-card ${className ? className : ''}` }, props, { children: [(0, jsx_runtime_1.jsx)(react_core_1.CardHeader, Object.assign({ actions: {
|
|
37
37
|
actions: (0, jsx_runtime_1.jsx)(CloseButton_1.default, { onClose: onClose, ariaLabel: closeButtonAriaLabel })
|
|
38
|
-
} }, cardHeaderProps, { children: (0, jsx_runtime_1.jsx)(HeadingLevel, Object.assign({ className: "pf-chatbot__feedback-card-title" }, headingLevelProps, { children: title })) })), (0, jsx_runtime_1.jsx)(react_core_1.CardBody, Object.assign({}, cardBodyProps, { children: (0, jsx_runtime_1.jsxs)(react_core_1.Form, Object.assign({ className: `pf-chatbot__feedback-card-form ${isCompact ? 'pf-m-compact' : ''}` }, formProps, { children: [quickResponses && ((0, jsx_runtime_1.jsx)(QuickResponse_1.default, { quickResponses: quickResponses, quickResponseContainerProps: quickResponseContainerProps, onSelect: (id) => setSelectedResponse(id), isCompact: isCompact })), hasTextArea && ((0, jsx_runtime_1.jsx)(react_core_1.TextArea, Object.assign({ value: value, onChange: (_event, value) => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
} }, cardHeaderProps, { children: (0, jsx_runtime_1.jsx)(HeadingLevel, Object.assign({ className: "pf-chatbot__feedback-card-title" }, headingLevelProps, { children: title })) })), (0, jsx_runtime_1.jsx)(react_core_1.CardBody, Object.assign({}, cardBodyProps, { children: (0, jsx_runtime_1.jsxs)(react_core_1.Form, Object.assign({ className: `pf-chatbot__feedback-card-form ${isCompact ? 'pf-m-compact' : ''}` }, formProps, { children: [quickResponses && ((0, jsx_runtime_1.jsx)(QuickResponse_1.default, { quickResponses: quickResponses, quickResponseContainerProps: quickResponseContainerProps, onSelect: (id) => setSelectedResponse(id), isCompact: isCompact })), hasTextArea && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(react_core_1.TextArea, Object.assign({ value: value, onChange: (_event, value) => {
|
|
39
|
+
setValue(value);
|
|
40
|
+
onTextAreaChange && onTextAreaChange(_event, value);
|
|
41
|
+
}, placeholder: textAreaPlaceholder, "aria-label": textAreaAriaLabel, resizeOrientation: "vertical" }, textAreaProps)) })), privacyStatement && (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__feedback-card-privacy", children: privacyStatement }), children, (0, jsx_runtime_1.jsx)(react_core_1.ActionGroup, Object.assign({}, actionGroupProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ onClick: () => onSubmit(selectedResponse, value), size: isCompact ? 'sm' : undefined }, submitButtonProps, { children: submitWord })) }))] })) }))] })) }));
|
|
42
42
|
};
|
|
43
43
|
exports.default = UserFeedback;
|
|
@@ -34,6 +34,7 @@ const MessageBarBase = (_a) => {
|
|
|
34
34
|
const [isListeningMessage, setIsListeningMessage] = (0, react_1.useState)(false);
|
|
35
35
|
const [hasSentMessage, setHasSentMessage] = (0, react_1.useState)(false);
|
|
36
36
|
const [isComposing, setIsComposing] = (0, react_1.useState)(false);
|
|
37
|
+
const [isMultiline, setIsMultiline] = (0, react_1.useState)(false);
|
|
37
38
|
const inputRef = (0, react_1.useRef)(null);
|
|
38
39
|
const textareaRef = (_b = innerRef) !== null && _b !== void 0 ? _b : inputRef;
|
|
39
40
|
const attachButtonRef = (0, react_1.useRef)(null);
|
|
@@ -74,6 +75,15 @@ const MessageBarBase = (_a) => {
|
|
|
74
75
|
const lines = field.scrollHeight / lineHeight;
|
|
75
76
|
return lines > 2;
|
|
76
77
|
};
|
|
78
|
+
const checkIfMultiline = (0, react_1.useCallback)((field) => {
|
|
79
|
+
const parent = field.parentElement;
|
|
80
|
+
const grandparent = parent === null || parent === void 0 ? void 0 : parent.parentElement;
|
|
81
|
+
if (grandparent) {
|
|
82
|
+
const containerHeight = grandparent.offsetHeight;
|
|
83
|
+
const threshold = isCompact ? 56 : 70;
|
|
84
|
+
setIsMultiline(containerHeight > threshold);
|
|
85
|
+
}
|
|
86
|
+
}, [isCompact]);
|
|
77
87
|
const setAutoWidth = (0, react_1.useCallback)((field) => {
|
|
78
88
|
const parent = field.parentElement;
|
|
79
89
|
if (parent) {
|
|
@@ -126,13 +136,15 @@ const MessageBarBase = (_a) => {
|
|
|
126
136
|
if (field) {
|
|
127
137
|
if (field.value === '') {
|
|
128
138
|
setInitialLineHeight(field);
|
|
139
|
+
setIsMultiline(false);
|
|
129
140
|
}
|
|
130
141
|
else {
|
|
131
142
|
setAutoHeight(field);
|
|
132
143
|
setAutoWidth(field);
|
|
144
|
+
checkIfMultiline(field);
|
|
133
145
|
}
|
|
134
146
|
}
|
|
135
|
-
}, [displayMode, message, setAutoWidth]);
|
|
147
|
+
}, [displayMode, message, setAutoWidth, checkIfMultiline]);
|
|
136
148
|
(0, react_1.useEffect)(() => {
|
|
137
149
|
const field = textareaRef.current;
|
|
138
150
|
if (field) {
|
|
@@ -145,13 +157,15 @@ const MessageBarBase = (_a) => {
|
|
|
145
157
|
if (textareaRef.current) {
|
|
146
158
|
if (event.target.value === '') {
|
|
147
159
|
setInitialLineHeight(textareaRef.current);
|
|
160
|
+
setIsMultiline(false);
|
|
148
161
|
}
|
|
149
162
|
else {
|
|
150
163
|
setAutoHeight(textareaRef.current);
|
|
164
|
+
checkIfMultiline(textareaRef.current);
|
|
151
165
|
}
|
|
152
166
|
}
|
|
153
167
|
setMessage(event.target.value);
|
|
154
|
-
}, [onChange]);
|
|
168
|
+
}, [onChange, checkIfMultiline]);
|
|
155
169
|
// Handle sending message
|
|
156
170
|
const handleSend = (0, react_1.useCallback)((newMessage) => {
|
|
157
171
|
onSendMessage(newMessage);
|
|
@@ -202,14 +216,14 @@ const MessageBarBase = (_a) => {
|
|
|
202
216
|
};
|
|
203
217
|
const messageBarContents = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `pf-chatbot__message-bar-input ${isCompact ? 'pf-m-compact' : ''}`, children: (0, jsx_runtime_1.jsx)(react_core_1.TextArea, Object.assign({ className: "pf-chatbot__message-textarea", value: message, onChange: handleChange, "aria-label": isListeningMessage ? listeningText : placeholder, placeholder: isListeningMessage ? listeningText : placeholder, ref: textareaRef, onKeyDown: handleKeyDown, onCompositionStart: handleCompositionStart, onCompositionEnd: handleCompositionEnd }, props)) }), (0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-bar-actions", children: renderButtons() })] }));
|
|
204
218
|
if (attachMenuProps) {
|
|
205
|
-
return ((0, jsx_runtime_1.jsx)(AttachMenu_1.default, Object.assign({ toggle: (toggleRef) => ((0, jsx_runtime_1.jsx)("div", { ref: toggleRef, className:
|
|
219
|
+
return ((0, jsx_runtime_1.jsx)(AttachMenu_1.default, Object.assign({ toggle: (toggleRef) => ((0, jsx_runtime_1.jsx)("div", { ref: toggleRef, className: (0, react_styles_1.css)('pf-chatbot__message-bar', isMultiline && 'pf-m-multiline', className), children: messageBarContents })), filteredItems: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.attachMenuItems }, (attachMenuProps && { isOpen: attachMenuProps.isAttachMenuOpen }), { onOpenChange: (isAttachMenuOpen) => {
|
|
206
220
|
var _a;
|
|
207
221
|
(_a = attachButtonRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
208
222
|
attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.setIsAttachMenuOpen(isAttachMenuOpen);
|
|
209
223
|
(attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.onAttachMenuOpenChange) && (attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.onAttachMenuOpenChange(isAttachMenuOpen));
|
|
210
224
|
}, onOpenChangeKeys: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.onAttachMenuOnOpenChangeKeys, onSelect: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.onAttachMenuSelect }, (attachMenuProps && { handleTextInputChange: attachMenuProps.onAttachMenuInputChange }), { popperProps: { direction: 'up', distance: 8 }, searchInputPlaceholder: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.attachMenuInputPlaceholder }, attachMenuProps)));
|
|
211
225
|
}
|
|
212
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-bar', isPrimary && 'pf-m-primary', hasAiIndicator && 'pf-v6-m-ai-indicator', isThinking && 'pf-v6-m-thinking', className), children: messageBarContents }));
|
|
226
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-bar', isPrimary && 'pf-m-primary', hasAiIndicator && 'pf-v6-m-ai-indicator', isThinking && 'pf-v6-m-thinking', isMultiline && 'pf-m-multiline', className), children: messageBarContents }));
|
|
213
227
|
};
|
|
214
228
|
exports.MessageBarBase = MessageBarBase;
|
|
215
229
|
const MessageBar = (0, react_1.forwardRef)((props, ref) => ((0, jsx_runtime_1.jsx)(exports.MessageBarBase, Object.assign({ innerRef: ref }, props))));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'react';
|
|
2
2
|
import { ActionListProps, ActionListGroupProps, ActionListItemProps, ButtonProps, CardProps, CardBodyProps, CardFooterProps, ExpandableSectionProps, SpinnerProps } from '@patternfly/react-core';
|
|
3
|
+
import type { MarkdownContentProps } from '../MarkdownContent';
|
|
3
4
|
export interface ToolCallProps {
|
|
4
5
|
/** Title text for the tool call. */
|
|
5
6
|
titleText: string;
|
|
@@ -41,6 +42,14 @@ export interface ToolCallProps {
|
|
|
41
42
|
cardFooterProps?: CardFooterProps;
|
|
42
43
|
/** Additional props for the expandable section when expandableContent is passed. */
|
|
43
44
|
expandableSectionProps?: Omit<ExpandableSectionProps, 'ref'>;
|
|
45
|
+
/** Whether to enable markdown rendering for titleText. When true, titleText will be parsed as markdown. */
|
|
46
|
+
isTitleMarkdown?: boolean;
|
|
47
|
+
/** Whether to enable markdown rendering for expandableContent. When true and expandableContent is a string, it will be parsed as markdown. */
|
|
48
|
+
isExpandableContentMarkdown?: boolean;
|
|
49
|
+
/** Props passed to MarkdownContent component when markdown is enabled */
|
|
50
|
+
markdownContentProps?: Omit<MarkdownContentProps, 'content'>;
|
|
51
|
+
/** Whether to retain styles in the MarkdownContent component. Defaults to false. */
|
|
52
|
+
shouldRetainStyles?: boolean;
|
|
44
53
|
}
|
|
45
54
|
export declare const ToolCall: FunctionComponent<ToolCallProps>;
|
|
46
55
|
export default ToolCall;
|
|
@@ -1,19 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.ToolCall = void 0;
|
|
4
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
8
|
const react_1 = require("react");
|
|
6
9
|
const react_core_1 = require("@patternfly/react-core");
|
|
7
|
-
const
|
|
10
|
+
const MarkdownContent_1 = __importDefault(require("../MarkdownContent"));
|
|
11
|
+
const ToolCall = ({ titleText, loadingText, isLoading, expandableContent, isDefaultExpanded = false, runButtonText = 'Run tool', runButtonProps, runActionItemProps, cancelButtonText = 'Cancel', cancelButtonProps, cancelActionItemProps, actions, actionListProps, actionListGroupProps, actionListItemProps, cardProps, cardBodyProps, cardFooterProps, expandableSectionProps, spinnerProps, isTitleMarkdown, isExpandableContentMarkdown, markdownContentProps, shouldRetainStyles = false }) => {
|
|
8
12
|
const [isExpanded, setIsExpanded] = (0, react_1.useState)(isDefaultExpanded);
|
|
9
13
|
const onToggle = (_event, isExpanded) => {
|
|
10
14
|
setIsExpanded(isExpanded);
|
|
11
15
|
};
|
|
12
|
-
const
|
|
16
|
+
const renderTitle = () => {
|
|
17
|
+
if (isTitleMarkdown) {
|
|
18
|
+
return (0, jsx_runtime_1.jsx)(MarkdownContent_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, content: titleText }, markdownContentProps));
|
|
19
|
+
}
|
|
20
|
+
return titleText;
|
|
21
|
+
};
|
|
22
|
+
const titleContent = ((0, jsx_runtime_1.jsx)("span", { className: `pf-chatbot__tool-call-title-content`, children: isLoading ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.Spinner, Object.assign({ diameter: "1em" }, spinnerProps)), ' ', (0, jsx_runtime_1.jsx)("span", { className: "pf-chatbot__tool-call-title-text", children: loadingText })] })) : ((0, jsx_runtime_1.jsx)("span", { className: "pf-chatbot__tool-call-title-text", children: renderTitle() })) }));
|
|
23
|
+
const renderExpandableContent = () => {
|
|
24
|
+
if (isExpandableContentMarkdown && typeof expandableContent === 'string') {
|
|
25
|
+
return ((0, jsx_runtime_1.jsx)(MarkdownContent_1.default, Object.assign({ shouldRetainStyles: shouldRetainStyles, content: expandableContent }, markdownContentProps)));
|
|
26
|
+
}
|
|
27
|
+
return expandableContent;
|
|
28
|
+
};
|
|
13
29
|
const defaultActions = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_core_1.ActionListItem, Object.assign({}, actionListItemProps, cancelActionItemProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ variant: "link" }, cancelButtonProps, { children: cancelButtonText })) })), (0, jsx_runtime_1.jsx)(react_core_1.ActionListItem, Object.assign({}, actionListItemProps, runActionItemProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.Button, Object.assign({ variant: "secondary" }, runButtonProps, { children: runButtonText })) }))] }));
|
|
14
30
|
const customActions = actions &&
|
|
15
31
|
actions.map((action, index) => ((0, jsx_runtime_1.jsx)(react_core_1.ActionListItem, Object.assign({}, actionListItemProps, { children: action }), index)));
|
|
16
|
-
return ((0, jsx_runtime_1.jsxs)(react_core_1.Card, Object.assign({ isCompact: true, className: "pf-chatbot__tool-call" }, cardProps, { children: [(0, jsx_runtime_1.jsx)(react_core_1.CardBody, Object.assign({ className: "pf-chatbot__tool-call-title" }, cardBodyProps, { children: expandableContent && !isLoading ? ((0, jsx_runtime_1.jsx)(react_core_1.ExpandableSection, Object.assign({ className: "pf-chatbot__tool-call-expandable-section", toggleContent: titleContent, onToggle: onToggle, isExpanded: isExpanded, isIndented: true }, expandableSectionProps, { children:
|
|
32
|
+
return ((0, jsx_runtime_1.jsxs)(react_core_1.Card, Object.assign({ isCompact: true, className: "pf-chatbot__tool-call" }, cardProps, { children: [(0, jsx_runtime_1.jsx)(react_core_1.CardBody, Object.assign({ className: "pf-chatbot__tool-call-title" }, cardBodyProps, { children: expandableContent && !isLoading ? ((0, jsx_runtime_1.jsx)(react_core_1.ExpandableSection, Object.assign({ className: "pf-chatbot__tool-call-expandable-section", toggleContent: titleContent, onToggle: onToggle, isExpanded: isExpanded, isIndented: true }, expandableSectionProps, { children: renderExpandableContent() }))) : (titleContent) })), !isLoading && ((0, jsx_runtime_1.jsx)(react_core_1.CardFooter, Object.assign({}, cardFooterProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.ActionList, Object.assign({ className: "pf-chatbot__tool-call-action-list" }, actionListProps, { children: (0, jsx_runtime_1.jsx)(react_core_1.ActionListGroup, Object.assign({}, actionListGroupProps, { children: customActions || defaultActions })) })) })))] })));
|
|
17
33
|
};
|
|
18
34
|
exports.ToolCall = ToolCall;
|
|
19
35
|
exports.default = exports.ToolCall;
|
|
@@ -167,4 +167,35 @@ describe('ToolCall', () => {
|
|
|
167
167
|
expect(toggleButton).toHaveAttribute('aria-expanded', 'false');
|
|
168
168
|
expect(react_1.screen.queryByText('Expandable Content')).not.toBeVisible();
|
|
169
169
|
}));
|
|
170
|
+
it('should render titleText as markdown when isTitleMarkdown is true', () => {
|
|
171
|
+
const titleText = '**Bold title**';
|
|
172
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(ToolCall_1.default, { titleText: titleText, isTitleMarkdown: true }));
|
|
173
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
174
|
+
expect(react_1.screen.getByText('Bold title')).toBeTruthy();
|
|
175
|
+
});
|
|
176
|
+
it('should not render titleText as markdown when isTitleMarkdown is false', () => {
|
|
177
|
+
const titleText = '**Bold title**';
|
|
178
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ToolCall_1.default, { titleText: titleText }));
|
|
179
|
+
expect(react_1.screen.getByText('**Bold title**')).toBeTruthy();
|
|
180
|
+
});
|
|
181
|
+
it('should render expandableContent as markdown when isExpandableContentMarkdown is true', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
182
|
+
const user = user_event_1.default.setup();
|
|
183
|
+
const expandableContent = '**Bold expandable content**';
|
|
184
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(ToolCall_1.default, Object.assign({}, defaultProps, { expandableContent: expandableContent, isExpandableContentMarkdown: true })));
|
|
185
|
+
yield user.click(react_1.screen.getByRole('button', { name: defaultProps.titleText }));
|
|
186
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
187
|
+
expect(react_1.screen.getByText('Bold expandable content')).toBeTruthy();
|
|
188
|
+
}));
|
|
189
|
+
it('should not render expandableContent as markdown when isExpandableContentMarkdown is false', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
190
|
+
const user = user_event_1.default.setup();
|
|
191
|
+
const expandableContent = '**Bold expandable content**';
|
|
192
|
+
(0, react_1.render)((0, jsx_runtime_1.jsx)(ToolCall_1.default, Object.assign({}, defaultProps, { expandableContent: expandableContent })));
|
|
193
|
+
yield user.click(react_1.screen.getByRole('button', { name: defaultProps.titleText }));
|
|
194
|
+
expect(react_1.screen.getByText('**Bold expandable content**')).toBeTruthy();
|
|
195
|
+
}));
|
|
196
|
+
it('should pass markdownContentProps to MarkdownContent component', () => {
|
|
197
|
+
const titleText = '**Bold title**';
|
|
198
|
+
const { container } = (0, react_1.render)((0, jsx_runtime_1.jsx)(ToolCall_1.default, { titleText: titleText, isTitleMarkdown: true, markdownContentProps: { isPrimary: true } }));
|
|
199
|
+
expect(container.querySelector('.pf-m-primary')).toBeTruthy();
|
|
200
|
+
});
|
|
170
201
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CardBodyProps, CardProps, CardTitleProps, DividerProps, ExpandableSectionProps } from '@patternfly/react-core';
|
|
2
2
|
import { type FunctionComponent } from 'react';
|
|
3
|
+
import type { MarkdownContentProps } from '../MarkdownContent';
|
|
3
4
|
export interface ToolResponseProps {
|
|
4
5
|
/** Toggle content shown for expandable section */
|
|
5
6
|
toggleContent: React.ReactNode;
|
|
@@ -27,6 +28,20 @@ export interface ToolResponseProps {
|
|
|
27
28
|
toolResponseCardDividerProps?: DividerProps;
|
|
28
29
|
/** Additional props passed to tool response card title */
|
|
29
30
|
toolResponseCardTitleProps?: CardTitleProps;
|
|
31
|
+
/** Whether to enable markdown rendering for toggleContent. When true and toggleContent is a string, it will be parsed as markdown. */
|
|
32
|
+
isToggleContentMarkdown?: boolean;
|
|
33
|
+
/** Whether to enable markdown rendering for subheading. When true, subheading will be parsed as markdown. */
|
|
34
|
+
isSubheadingMarkdown?: boolean;
|
|
35
|
+
/** Whether to enable markdown rendering for body. When true and body is a string, it will be parsed as markdown. */
|
|
36
|
+
isBodyMarkdown?: boolean;
|
|
37
|
+
/** Whether to enable markdown rendering for cardBody. When true and cardBody is a string, it will be parsed as markdown. */
|
|
38
|
+
isCardBodyMarkdown?: boolean;
|
|
39
|
+
/** Whether to enable markdown rendering for cardTitle. When true and cardTitle is a string, it will be parsed as markdown. */
|
|
40
|
+
isCardTitleMarkdown?: boolean;
|
|
41
|
+
/** Props passed to MarkdownContent component when markdown is enabled */
|
|
42
|
+
markdownContentProps?: Omit<MarkdownContentProps, 'content'>;
|
|
43
|
+
/** Whether to retain styles in the MarkdownContent component. Defaults to false. */
|
|
44
|
+
shouldRetainStyles?: boolean;
|
|
30
45
|
}
|
|
31
46
|
export declare const ToolResponse: FunctionComponent<ToolResponseProps>;
|
|
32
47
|
export default ToolResponse;
|