@patternfly/chatbot 6.5.0-prerelease.22 → 6.5.0-prerelease.23
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/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 +48 -0
- 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/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/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/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/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
|
@@ -0,0 +1,187 @@
|
|
|
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
|
+
};
|
|
10
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import { render, screen } from '@testing-library/react';
|
|
12
|
+
import '@testing-library/jest-dom';
|
|
13
|
+
import MarkdownContent from './MarkdownContent';
|
|
14
|
+
import rehypeExternalLinks from '../__mocks__/rehype-external-links';
|
|
15
|
+
const BOLD_TEXT = '**Bold text**';
|
|
16
|
+
const ITALIC_TEXT = '*Italic text*';
|
|
17
|
+
const INLINE_CODE = 'Here is inline code: `const x = 5`';
|
|
18
|
+
const CODE_BLOCK = `\`\`\`javascript
|
|
19
|
+
function hello() {
|
|
20
|
+
console.log('Hello, world!');
|
|
21
|
+
}
|
|
22
|
+
\`\`\``;
|
|
23
|
+
const HEADING = '# Heading 1';
|
|
24
|
+
const LINK = '[PatternFly](https://www.patternfly.org/)';
|
|
25
|
+
const UNORDERED_LIST = `
|
|
26
|
+
* Item 1
|
|
27
|
+
* Item 2
|
|
28
|
+
* Item 3
|
|
29
|
+
`;
|
|
30
|
+
const ORDERED_LIST = `
|
|
31
|
+
1. First item
|
|
32
|
+
2. Second item
|
|
33
|
+
3. Third item
|
|
34
|
+
`;
|
|
35
|
+
const TABLE = `
|
|
36
|
+
| Column 1 | Column 2 |
|
|
37
|
+
|----------|----------|
|
|
38
|
+
| Cell 1 | Cell 2 |
|
|
39
|
+
| Cell 3 | Cell 4 |
|
|
40
|
+
`;
|
|
41
|
+
const BLOCKQUOTE = '> This is a blockquote';
|
|
42
|
+
const IMAGE = '';
|
|
43
|
+
describe('MarkdownContent', () => {
|
|
44
|
+
beforeEach(() => {
|
|
45
|
+
jest.clearAllMocks();
|
|
46
|
+
});
|
|
47
|
+
it('should render bold text correctly', () => {
|
|
48
|
+
const { container } = render(_jsx(MarkdownContent, { content: BOLD_TEXT }));
|
|
49
|
+
expect(container.querySelector('strong')).toBeTruthy();
|
|
50
|
+
expect(screen.getByText('Bold text')).toBeTruthy();
|
|
51
|
+
});
|
|
52
|
+
it('should render italic text correctly', () => {
|
|
53
|
+
const { container } = render(_jsx(MarkdownContent, { content: ITALIC_TEXT }));
|
|
54
|
+
expect(container.querySelector('em')).toBeTruthy();
|
|
55
|
+
expect(screen.getByText('Italic text')).toBeTruthy();
|
|
56
|
+
});
|
|
57
|
+
it('should render inline code correctly', () => {
|
|
58
|
+
render(_jsx(MarkdownContent, { content: INLINE_CODE }));
|
|
59
|
+
expect(screen.getByText(/const x = 5/)).toBeTruthy();
|
|
60
|
+
});
|
|
61
|
+
it('should render code blocks correctly', () => {
|
|
62
|
+
render(_jsx(MarkdownContent, { content: CODE_BLOCK }));
|
|
63
|
+
expect(screen.getByText(/function hello/)).toBeVisible();
|
|
64
|
+
expect(screen.getByText(/console.log/)).toBeVisible();
|
|
65
|
+
expect(screen.getByRole('button', { name: 'Copy code' })).toBeVisible();
|
|
66
|
+
});
|
|
67
|
+
it('should render headings correctly', () => {
|
|
68
|
+
render(_jsx(MarkdownContent, { content: HEADING }));
|
|
69
|
+
expect(screen.getByRole('heading', { name: /Heading 1/i })).toBeTruthy();
|
|
70
|
+
});
|
|
71
|
+
it('should render links correctly', () => {
|
|
72
|
+
render(_jsx(MarkdownContent, { content: LINK }));
|
|
73
|
+
expect(screen.getByRole('link', { name: /PatternFly/i })).toBeTruthy();
|
|
74
|
+
});
|
|
75
|
+
it('should render unordered lists correctly', () => {
|
|
76
|
+
render(_jsx(MarkdownContent, { content: UNORDERED_LIST }));
|
|
77
|
+
expect(screen.getByText('Item 1')).toBeTruthy();
|
|
78
|
+
expect(screen.getByText('Item 2')).toBeTruthy();
|
|
79
|
+
expect(screen.getByText('Item 3')).toBeTruthy();
|
|
80
|
+
expect(screen.getAllByRole('listitem')).toHaveLength(3);
|
|
81
|
+
});
|
|
82
|
+
it('should render ordered lists correctly', () => {
|
|
83
|
+
render(_jsx(MarkdownContent, { content: ORDERED_LIST }));
|
|
84
|
+
expect(screen.getByText('First item')).toBeTruthy();
|
|
85
|
+
expect(screen.getByText('Second item')).toBeTruthy();
|
|
86
|
+
expect(screen.getByText('Third item')).toBeTruthy();
|
|
87
|
+
expect(screen.getAllByRole('listitem')).toHaveLength(3);
|
|
88
|
+
});
|
|
89
|
+
it('should render tables correctly', () => {
|
|
90
|
+
render(_jsx(MarkdownContent, { content: TABLE, tableProps: { 'aria-label': 'Test table' } }));
|
|
91
|
+
expect(screen.getByRole('grid', { name: /Test table/i })).toBeTruthy();
|
|
92
|
+
expect(screen.getByRole('columnheader', { name: /Column 1/i })).toBeTruthy();
|
|
93
|
+
expect(screen.getByRole('columnheader', { name: /Column 2/i })).toBeTruthy();
|
|
94
|
+
expect(screen.getByRole('cell', { name: /Cell 1/i })).toBeTruthy();
|
|
95
|
+
expect(screen.getByRole('cell', { name: /Cell 2/i })).toBeTruthy();
|
|
96
|
+
});
|
|
97
|
+
it('should render blockquotes correctly', () => {
|
|
98
|
+
var _a;
|
|
99
|
+
render(_jsx(MarkdownContent, { content: BLOCKQUOTE }));
|
|
100
|
+
const quote = screen.getByText(/This is a blockquote/);
|
|
101
|
+
expect(quote).toBeVisible();
|
|
102
|
+
expect((_a = quote.closest('.pf-v6-c-content--blockquote')) === null || _a === void 0 ? void 0 : _a.tagName).toBe('BLOCKQUOTE');
|
|
103
|
+
});
|
|
104
|
+
it('should render images when hasNoImages is false', () => {
|
|
105
|
+
render(_jsx(MarkdownContent, { content: IMAGE, hasNoImages: false }));
|
|
106
|
+
expect(screen.getByRole('img', { name: /Alt text/i })).toBeTruthy();
|
|
107
|
+
});
|
|
108
|
+
it('should not render images when hasNoImages is true', () => {
|
|
109
|
+
render(_jsx(MarkdownContent, { content: IMAGE, hasNoImages: true }));
|
|
110
|
+
expect(screen.queryByRole('img', { name: /Alt text/i })).toBeFalsy();
|
|
111
|
+
});
|
|
112
|
+
it('should disable markdown rendering when isMarkdownDisabled is true', () => {
|
|
113
|
+
render(_jsx(MarkdownContent, { content: BOLD_TEXT, isMarkdownDisabled: true }));
|
|
114
|
+
expect(screen.getByText('**Bold text**')).toBeTruthy();
|
|
115
|
+
});
|
|
116
|
+
it('should render text component when isMarkdownDisabled is true and textComponent is provided', () => {
|
|
117
|
+
const textComponent = _jsx("div", { "data-testid": "custom-text", children: "Custom text component" });
|
|
118
|
+
render(_jsx(MarkdownContent, { content: BOLD_TEXT, isMarkdownDisabled: true, textComponent: textComponent }));
|
|
119
|
+
expect(screen.getByTestId('custom-text')).toBeTruthy();
|
|
120
|
+
expect(screen.getByText('Custom text component')).toBeTruthy();
|
|
121
|
+
});
|
|
122
|
+
it('should apply isPrimary prop to elements', () => {
|
|
123
|
+
const { container } = render(_jsx(MarkdownContent, { content: INLINE_CODE, isPrimary: true }));
|
|
124
|
+
expect(container.querySelector('.pf-m-primary')).toBeTruthy();
|
|
125
|
+
});
|
|
126
|
+
it('should apply shouldRetainStyles prop to elements', () => {
|
|
127
|
+
const { container } = render(_jsx(MarkdownContent, { content: BOLD_TEXT, shouldRetainStyles: true }));
|
|
128
|
+
expect(container.querySelector('.pf-m-markdown')).toBeTruthy();
|
|
129
|
+
});
|
|
130
|
+
it('should pass codeBlockProps to code blocks', () => {
|
|
131
|
+
render(_jsx(MarkdownContent, { content: CODE_BLOCK, codeBlockProps: { 'aria-label': 'Custom code block' } }));
|
|
132
|
+
expect(screen.getByRole('button', { name: /Custom code block/i })).toBeTruthy();
|
|
133
|
+
});
|
|
134
|
+
it('should pass tableProps to tables', () => {
|
|
135
|
+
render(_jsx(MarkdownContent, { content: TABLE, tableProps: { 'aria-label': 'Custom table label' } }));
|
|
136
|
+
expect(screen.getByRole('grid', { name: /Custom table label/i })).toBeTruthy();
|
|
137
|
+
});
|
|
138
|
+
it('should open links in new tab when openLinkInNewTab is true', () => {
|
|
139
|
+
render(_jsx(MarkdownContent, { content: LINK, openLinkInNewTab: true }));
|
|
140
|
+
expect(rehypeExternalLinks).toHaveBeenCalledTimes(1);
|
|
141
|
+
});
|
|
142
|
+
it('should not open links in new tab when openLinkInNewTab is false', () => {
|
|
143
|
+
render(_jsx(MarkdownContent, { content: LINK, openLinkInNewTab: false }));
|
|
144
|
+
expect(rehypeExternalLinks).not.toHaveBeenCalled();
|
|
145
|
+
});
|
|
146
|
+
it('should pass linkProps to links', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
147
|
+
const onClick = jest.fn();
|
|
148
|
+
render(_jsx(MarkdownContent, { content: LINK, linkProps: { onClick } }));
|
|
149
|
+
const link = screen.getByRole('link', { name: /PatternFly/i });
|
|
150
|
+
link.click();
|
|
151
|
+
expect(onClick).toHaveBeenCalledTimes(1);
|
|
152
|
+
}));
|
|
153
|
+
it('should handle reactMarkdownProps.disallowedElements', () => {
|
|
154
|
+
render(_jsx(MarkdownContent, { content: CODE_BLOCK, reactMarkdownProps: { disallowedElements: ['code'] } }));
|
|
155
|
+
// Code block should not render when disallowed
|
|
156
|
+
expect(screen.queryByRole('button', { name: /Copy code/i })).toBeFalsy();
|
|
157
|
+
});
|
|
158
|
+
it('should render plain text when no markdown is present', () => {
|
|
159
|
+
render(_jsx(MarkdownContent, { content: "Plain text without markdown" }));
|
|
160
|
+
expect(screen.getByText('Plain text without markdown')).toBeTruthy();
|
|
161
|
+
});
|
|
162
|
+
it('should handle empty content', () => {
|
|
163
|
+
const { container } = render(_jsx(MarkdownContent, { content: "" }));
|
|
164
|
+
expect(container.textContent).toBe('');
|
|
165
|
+
});
|
|
166
|
+
it('should handle undefined content', () => {
|
|
167
|
+
const { container } = render(_jsx(MarkdownContent, {}));
|
|
168
|
+
expect(container.textContent).toBe('');
|
|
169
|
+
});
|
|
170
|
+
it('should render multiple markdown elements together', () => {
|
|
171
|
+
const content = `# Heading
|
|
172
|
+
|
|
173
|
+
**Bold text** and *italic text*
|
|
174
|
+
|
|
175
|
+
\`\`\`javascript
|
|
176
|
+
const x = 5;
|
|
177
|
+
\`\`\`
|
|
178
|
+
|
|
179
|
+
[Link](https://example.com)`;
|
|
180
|
+
render(_jsx(MarkdownContent, { content: content }));
|
|
181
|
+
expect(screen.getByRole('heading', { name: /Heading/i })).toBeTruthy();
|
|
182
|
+
expect(screen.getByText('Bold text')).toBeTruthy();
|
|
183
|
+
expect(screen.getByText('italic text')).toBeTruthy();
|
|
184
|
+
expect(screen.getByText(/const x = 5/)).toBeTruthy();
|
|
185
|
+
expect(screen.getByRole('link', { name: /Link/i })).toBeTruthy();
|
|
186
|
+
});
|
|
187
|
+
});
|
|
@@ -20,6 +20,8 @@ export interface CodeBlockMessageProps {
|
|
|
20
20
|
customActions?: React.ReactNode;
|
|
21
21
|
/** Sets background colors to be appropriate on primary chatbot background */
|
|
22
22
|
isPrimary?: boolean;
|
|
23
|
+
/** Flag indicating that the content should retain message styles when using Markdown. */
|
|
24
|
+
shouldRetainStyles?: boolean;
|
|
23
25
|
}
|
|
24
|
-
declare const CodeBlockMessage: ({ children, className, "aria-label": ariaLabel, isExpandable, expandableSectionProps, expandableSectionToggleProps, expandedText, collapsedText, customActions, isPrimary, ...props }: CodeBlockMessageProps) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
declare const CodeBlockMessage: ({ children, className, "aria-label": ariaLabel, isExpandable, expandableSectionProps, expandableSectionToggleProps, expandedText, collapsedText, customActions, isPrimary, shouldRetainStyles, ...props }: CodeBlockMessageProps) => import("react/jsx-runtime").JSX.Element;
|
|
25
27
|
export default CodeBlockMessage;
|
|
@@ -18,11 +18,12 @@ import { useState, useRef, useCallback, useEffect } from 'react';
|
|
|
18
18
|
import { CodeBlock, CodeBlockAction, CodeBlockCode, Button, Tooltip, ExpandableSection, ExpandableSectionToggle, ExpandableSectionVariant, getUniqueId } from '@patternfly/react-core';
|
|
19
19
|
import { CheckIcon } from '@patternfly/react-icons/dist/esm/icons/check-icon';
|
|
20
20
|
import { CopyIcon } from '@patternfly/react-icons/dist/esm/icons/copy-icon';
|
|
21
|
+
import { css } from '@patternfly/react-styles';
|
|
21
22
|
const DEFAULT_EXPANDED_TEXT = 'Show less';
|
|
22
23
|
const DEFAULT_COLLAPSED_TEXT = 'Show more';
|
|
23
24
|
const CodeBlockMessage = (_a) => {
|
|
24
25
|
var _b;
|
|
25
|
-
var { children, className, 'aria-label': ariaLabel, isExpandable = false, expandableSectionProps, expandableSectionToggleProps, expandedText = DEFAULT_EXPANDED_TEXT, collapsedText = DEFAULT_COLLAPSED_TEXT, customActions, isPrimary } = _a, props = __rest(_a, ["children", "className", 'aria-label', "isExpandable", "expandableSectionProps", "expandableSectionToggleProps", "expandedText", "collapsedText", "customActions", "isPrimary"]);
|
|
26
|
+
var { children, className, 'aria-label': ariaLabel, isExpandable = false, expandableSectionProps, expandableSectionToggleProps, expandedText = DEFAULT_EXPANDED_TEXT, collapsedText = DEFAULT_COLLAPSED_TEXT, customActions, isPrimary, shouldRetainStyles } = _a, props = __rest(_a, ["children", "className", 'aria-label', "isExpandable", "expandableSectionProps", "expandableSectionToggleProps", "expandedText", "collapsedText", "customActions", "isPrimary", "shouldRetainStyles"]);
|
|
26
27
|
const [copied, setCopied] = useState(false);
|
|
27
28
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
28
29
|
const buttonRef = useRef();
|
|
@@ -63,6 +64,6 @@ const CodeBlockMessage = (_a) => {
|
|
|
63
64
|
}
|
|
64
65
|
// Setup code block header
|
|
65
66
|
const actions = (_jsxs(_Fragment, { children: [_jsxs(CodeBlockAction, { className: "pf-chatbot__message-code-block-default-action", children: [language && _jsx("div", { className: "pf-chatbot__message-code-block-language", children: language }), _jsx(Button, { ref: buttonRef, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : 'Copy code', variant: "plain", className: "pf-chatbot__button--copy", onClick: (event) => handleCopy(event, children), children: copied ? _jsx(CheckIcon, {}) : _jsx(CopyIcon, {}) }), _jsx(Tooltip, { id: tooltipID, content: "Copy", position: "top", triggerRef: buttonRef })] }), customActions] }));
|
|
66
|
-
return (_jsx("div", { className:
|
|
67
|
+
return (_jsx("div", { className: css('pf-chatbot__message-code-block', shouldRetainStyles && 'pf-m-markdown'), ref: codeBlockRef, children: _jsxs(CodeBlock, { actions: actions, children: [_jsx(CodeBlockCode, { children: _jsx(_Fragment, { children: isExpandable ? (_jsx(ExpandableSection, Object.assign({ variant: ExpandableSectionVariant.truncate, isExpanded: isExpanded, isDetached: true, toggleId: toggleId, contentId: contentId }, expandableSectionProps, { children: children }))) : (children) }) }), isExpandable && (_jsx(ExpandableSectionToggle, Object.assign({ isExpanded: isExpanded, onToggle: onToggle, direction: "up", toggleId: toggleId, contentId: contentId, hasTruncatedContent: true, className: "pf-chatbot__message-code-toggle" }, expandableSectionToggleProps, { children: isExpanded ? finalExpandedText : finalCollapsedText })))] }) }));
|
|
67
68
|
};
|
|
68
69
|
export default CodeBlockMessage;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { ButtonProps } from '@patternfly/react-core';
|
|
2
2
|
import { ExtraProps } from 'react-markdown';
|
|
3
|
-
|
|
3
|
+
export interface LinkMessageProps {
|
|
4
|
+
/** Flag indicating that the content should retain message styles when using Markdown. */
|
|
5
|
+
shouldRetainStyles?: boolean;
|
|
6
|
+
}
|
|
7
|
+
declare const LinkMessage: ({ children, target, href, id, shouldRetainStyles, ...props }: LinkMessageProps & ButtonProps & ExtraProps) => import("react/jsx-runtime").JSX.Element;
|
|
4
8
|
export default LinkMessage;
|
|
@@ -15,15 +15,16 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
15
15
|
// ============================================================================
|
|
16
16
|
import { Button } from '@patternfly/react-core';
|
|
17
17
|
import { ExternalLinkSquareAltIcon } from '@patternfly/react-icons';
|
|
18
|
+
import { css } from '@patternfly/react-styles';
|
|
18
19
|
const LinkMessage = (_a) => {
|
|
19
|
-
var { children, target, href, id } = _a, props = __rest(_a, ["children", "target", "href", "id"]);
|
|
20
|
+
var { children, target, href, id, shouldRetainStyles } = _a, props = __rest(_a, ["children", "target", "href", "id", "shouldRetainStyles"]);
|
|
20
21
|
if (target === '_blank') {
|
|
21
22
|
return (_jsx(Button, Object.assign({ component: "a", variant: "link", href: href, icon: _jsx(ExternalLinkSquareAltIcon, {}), iconPosition: "end", isInline: true, target: target,
|
|
22
23
|
// need to explicitly call this out or id doesn't seem to get passed - required for footnotes
|
|
23
|
-
id: id }, props, { children: children })));
|
|
24
|
+
id: id }, props, { className: css(shouldRetainStyles && 'pf-m-markdown', props === null || props === void 0 ? void 0 : props.className), children: children })));
|
|
24
25
|
}
|
|
25
26
|
return (
|
|
26
27
|
// need to explicitly call this out or id doesn't seem to get passed - required for footnotes
|
|
27
|
-
_jsx(Button, Object.assign({ isInline: true, component: "a", href: href, variant: "link", id: id }, props, { children: children })));
|
|
28
|
+
_jsx(Button, Object.assign({ isInline: true, component: "a", href: href, variant: "link", id: id }, props, { className: css(shouldRetainStyles && 'pf-m-markdown', props === null || props === void 0 ? void 0 : props.className), children: children })));
|
|
28
29
|
};
|
|
29
30
|
export 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;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { List, ListComponent, OrderType } from '@patternfly/react-core';
|
|
3
|
-
|
|
3
|
+
import { css } from '@patternfly/react-styles';
|
|
4
|
+
const OrderedListMessage = ({ children, start, shouldRetainStyles }) => (_jsx("div", { className: css('pf-chatbot__message-ordered-list', shouldRetainStyles && 'pf-m-markdown'), children: _jsx(List, { component: ListComponent.ol, type: OrderType.number, start: start, children: children }) }));
|
|
4
5
|
export 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;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { List } from '@patternfly/react-core';
|
|
3
|
-
|
|
3
|
+
import { css } from '@patternfly/react-styles';
|
|
4
|
+
const UnorderedListMessage = ({ children, shouldRetainStyles }) => (_jsx("div", { className: css('pf-chatbot__message-unordered-list', shouldRetainStyles && 'pf-m-markdown'), children: _jsx(List, { children: children }) }));
|
|
4
5
|
export default UnorderedListMessage;
|
|
@@ -14,43 +14,23 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
14
14
|
// Chatbot Main - Message
|
|
15
15
|
// ============================================================================
|
|
16
16
|
import { forwardRef, useEffect, useState } from 'react';
|
|
17
|
-
import
|
|
18
|
-
import remarkGfm from 'remark-gfm';
|
|
19
|
-
import { Avatar, ContentVariants, Label, Timestamp, Truncate } from '@patternfly/react-core';
|
|
17
|
+
import { Avatar, Label, Timestamp, Truncate } from '@patternfly/react-core';
|
|
20
18
|
import MessageLoading from './MessageLoading';
|
|
21
|
-
import CodeBlockMessage from './CodeBlockMessage/CodeBlockMessage';
|
|
22
|
-
import TextMessage from './TextMessage/TextMessage';
|
|
23
19
|
import FileDetailsLabel from '../FileDetailsLabel/FileDetailsLabel';
|
|
24
20
|
import ResponseActions from '../ResponseActions/ResponseActions';
|
|
25
21
|
import SourcesCard from '../SourcesCard';
|
|
26
|
-
import ListItemMessage from './ListMessage/ListItemMessage';
|
|
27
|
-
import UnorderedListMessage from './ListMessage/UnorderedListMessage';
|
|
28
|
-
import OrderedListMessage from './ListMessage/OrderedListMessage';
|
|
29
22
|
import QuickStartTile from './QuickStarts/QuickStartTile';
|
|
30
23
|
import QuickResponse from './QuickResponse/QuickResponse';
|
|
31
24
|
import UserFeedback from './UserFeedback/UserFeedback';
|
|
32
25
|
import UserFeedbackComplete from './UserFeedback/UserFeedbackComplete';
|
|
33
|
-
import TableMessage from './TableMessage/TableMessage';
|
|
34
|
-
import TrMessage from './TableMessage/TrMessage';
|
|
35
|
-
import TdMessage from './TableMessage/TdMessage';
|
|
36
|
-
import TbodyMessage from './TableMessage/TbodyMessage';
|
|
37
|
-
import TheadMessage from './TableMessage/TheadMessage';
|
|
38
|
-
import ThMessage from './TableMessage/ThMessage';
|
|
39
|
-
import ImageMessage from './ImageMessage/ImageMessage';
|
|
40
|
-
import rehypeUnwrapImages from 'rehype-unwrap-images';
|
|
41
|
-
import rehypeExternalLinks from 'rehype-external-links';
|
|
42
|
-
import rehypeSanitize from 'rehype-sanitize';
|
|
43
|
-
import rehypeHighlight from 'rehype-highlight';
|
|
44
26
|
// see the full list of styles here: https://highlightjs.org/examples
|
|
45
27
|
import 'highlight.js/styles/vs2015.css';
|
|
46
|
-
import LinkMessage from './LinkMessage/LinkMessage';
|
|
47
28
|
import ErrorMessage from './ErrorMessage/ErrorMessage';
|
|
48
29
|
import MessageInput from './MessageInput';
|
|
49
|
-
import { rehypeMoveImagesOutOfParagraphs } from './Plugins/rehypeMoveImagesOutOfParagraphs';
|
|
50
30
|
import ToolResponse from '../ToolResponse';
|
|
51
31
|
import DeepThinking from '../DeepThinking';
|
|
52
|
-
import SuperscriptMessage from './SuperscriptMessage/SuperscriptMessage';
|
|
53
32
|
import ToolCall from '../ToolCall';
|
|
33
|
+
import MarkdownContent from '../MarkdownContent';
|
|
54
34
|
export const MessageBase = (_a) => {
|
|
55
35
|
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"]);
|
|
56
36
|
const [messageText, setMessageText] = useState(content);
|
|
@@ -58,13 +38,6 @@ export const MessageBase = (_a) => {
|
|
|
58
38
|
setMessageText(content);
|
|
59
39
|
}, [content]);
|
|
60
40
|
const { beforeMainContent, afterMainContent, endContent } = extraContent || {};
|
|
61
|
-
let rehypePlugins = [rehypeUnwrapImages, rehypeMoveImagesOutOfParagraphs, rehypeHighlight];
|
|
62
|
-
if (openLinkInNewTab) {
|
|
63
|
-
rehypePlugins = rehypePlugins.concat([[rehypeExternalLinks, { target: '_blank' }, rehypeSanitize]]);
|
|
64
|
-
}
|
|
65
|
-
if (additionalRehypePlugins) {
|
|
66
|
-
rehypePlugins.push(...additionalRehypePlugins);
|
|
67
|
-
}
|
|
68
41
|
let avatarClassName;
|
|
69
42
|
if (avatarProps && 'className' in avatarProps) {
|
|
70
43
|
const { className } = avatarProps, rest = __rest(avatarProps, ["className"]);
|
|
@@ -74,133 +47,7 @@ export const MessageBase = (_a) => {
|
|
|
74
47
|
// Keep timestamps consistent between Timestamp component and aria-label
|
|
75
48
|
const date = new Date();
|
|
76
49
|
const dateString = timestamp !== null && timestamp !== void 0 ? timestamp : `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
|
|
77
|
-
const
|
|
78
|
-
if (reactMarkdownProps && reactMarkdownProps.disallowedElements) {
|
|
79
|
-
disallowedElements.push(...reactMarkdownProps.disallowedElements);
|
|
80
|
-
}
|
|
81
|
-
const handleMarkdown = () => {
|
|
82
|
-
if (isMarkdownDisabled) {
|
|
83
|
-
return (_jsx(TextMessage, Object.assign({ component: ContentVariants.p }, props, { children: messageText })));
|
|
84
|
-
}
|
|
85
|
-
return (_jsx(Markdown, Object.assign({ components: {
|
|
86
|
-
section: (props) => {
|
|
87
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
88
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
89
|
-
return _jsx("section", Object.assign({}, rest, { className: `pf-chatbot__message-text ${rest === null || rest === void 0 ? void 0 : rest.className}` }));
|
|
90
|
-
},
|
|
91
|
-
p: (props) => {
|
|
92
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
93
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
94
|
-
return _jsx(TextMessage, Object.assign({ component: ContentVariants.p }, rest, { isPrimary: isPrimary }));
|
|
95
|
-
},
|
|
96
|
-
code: (_a) => {
|
|
97
|
-
var { children } = _a, props = __rest(_a, ["children"]);
|
|
98
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
99
|
-
const { node } = props, codeProps = __rest(props, ["node"]);
|
|
100
|
-
return (_jsx(CodeBlockMessage, Object.assign({}, codeProps, codeBlockProps, { isPrimary: isPrimary, children: children })));
|
|
101
|
-
},
|
|
102
|
-
h1: (props) => {
|
|
103
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
104
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
105
|
-
return _jsx(TextMessage, Object.assign({ component: ContentVariants.h1 }, rest));
|
|
106
|
-
},
|
|
107
|
-
h2: (props) => {
|
|
108
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
109
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
110
|
-
return _jsx(TextMessage, Object.assign({ component: ContentVariants.h2 }, rest));
|
|
111
|
-
},
|
|
112
|
-
h3: (props) => {
|
|
113
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
114
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
115
|
-
return _jsx(TextMessage, Object.assign({ component: ContentVariants.h3 }, rest));
|
|
116
|
-
},
|
|
117
|
-
h4: (props) => {
|
|
118
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
119
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
120
|
-
return _jsx(TextMessage, Object.assign({ component: ContentVariants.h4 }, rest));
|
|
121
|
-
},
|
|
122
|
-
h5: (props) => {
|
|
123
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
124
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
125
|
-
return _jsx(TextMessage, Object.assign({ component: ContentVariants.h5 }, rest));
|
|
126
|
-
},
|
|
127
|
-
h6: (props) => {
|
|
128
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
129
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
130
|
-
return _jsx(TextMessage, Object.assign({ component: ContentVariants.h6 }, rest));
|
|
131
|
-
},
|
|
132
|
-
blockquote: (props) => {
|
|
133
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
134
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
135
|
-
return _jsx(TextMessage, Object.assign({ component: ContentVariants.blockquote }, rest));
|
|
136
|
-
},
|
|
137
|
-
ul: (props) => {
|
|
138
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
139
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
140
|
-
return _jsx(UnorderedListMessage, Object.assign({}, rest));
|
|
141
|
-
},
|
|
142
|
-
ol: (props) => {
|
|
143
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
144
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
145
|
-
return _jsx(OrderedListMessage, Object.assign({}, rest));
|
|
146
|
-
},
|
|
147
|
-
li: (props) => {
|
|
148
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
149
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
150
|
-
return _jsx(ListItemMessage, Object.assign({}, rest));
|
|
151
|
-
},
|
|
152
|
-
// table requires node attribute for calculating headers for mobile breakpoint
|
|
153
|
-
table: (props) => _jsx(TableMessage, Object.assign({}, props, tableProps, { isPrimary: isPrimary })),
|
|
154
|
-
tbody: (props) => {
|
|
155
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
156
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
157
|
-
return _jsx(TbodyMessage, Object.assign({}, rest));
|
|
158
|
-
},
|
|
159
|
-
thead: (props) => {
|
|
160
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
161
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
162
|
-
return _jsx(TheadMessage, Object.assign({}, rest));
|
|
163
|
-
},
|
|
164
|
-
tr: (props) => {
|
|
165
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
166
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
167
|
-
return _jsx(TrMessage, Object.assign({}, rest));
|
|
168
|
-
},
|
|
169
|
-
td: (props) => {
|
|
170
|
-
// Conflicts with Td type
|
|
171
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
172
|
-
const { node, width } = props, rest = __rest(props, ["node", "width"]);
|
|
173
|
-
return _jsx(TdMessage, Object.assign({}, rest));
|
|
174
|
-
},
|
|
175
|
-
th: (props) => {
|
|
176
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
177
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
178
|
-
return _jsx(ThMessage, Object.assign({}, rest));
|
|
179
|
-
},
|
|
180
|
-
img: (props) => {
|
|
181
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
182
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
183
|
-
return _jsx(ImageMessage, Object.assign({}, rest));
|
|
184
|
-
},
|
|
185
|
-
a: (props) => {
|
|
186
|
-
// node is just the details of the document structure - not needed
|
|
187
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
188
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
189
|
-
return (
|
|
190
|
-
// some a types conflict with ButtonProps, but it's ok because we are using an a tag
|
|
191
|
-
// there are too many to handle manually
|
|
192
|
-
_jsx(LinkMessage, Object.assign({}, rest, linkProps, { children: props.children })));
|
|
193
|
-
},
|
|
194
|
-
// used for footnotes
|
|
195
|
-
sup: (props) => {
|
|
196
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
197
|
-
const { node } = props, rest = __rest(props, ["node"]);
|
|
198
|
-
return _jsx(SuperscriptMessage, Object.assign({}, rest));
|
|
199
|
-
}
|
|
200
|
-
}, remarkPlugins: [[remarkGfm, Object.assign({}, remarkGfmProps)], ...additionalRemarkPlugins], rehypePlugins: rehypePlugins }, reactMarkdownProps, { remarkRehypeOptions: Object.assign({
|
|
201
|
-
// removes sr-only class from footnote labels applied by default
|
|
202
|
-
footnoteLabelProperties: { className: [''] } }, reactMarkdownProps === null || reactMarkdownProps === void 0 ? void 0 : reactMarkdownProps.remarkRehypeOptions), disallowedElements: disallowedElements, children: messageText })));
|
|
203
|
-
};
|
|
50
|
+
const handleMarkdown = () => (_jsx(MarkdownContent, { 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 }));
|
|
204
51
|
const renderMessage = () => {
|
|
205
52
|
if (isLoading) {
|
|
206
53
|
return _jsx(MessageLoading, { 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;
|
|
@@ -15,9 +15,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
15
15
|
// ============================================================================
|
|
16
16
|
import { Children, cloneElement } from 'react';
|
|
17
17
|
import { Table } from '@patternfly/react-table';
|
|
18
|
+
import { css } from '@patternfly/react-styles';
|
|
18
19
|
const TableMessage = (_a) => {
|
|
19
20
|
var _b;
|
|
20
|
-
var { children, isPrimary } = _a, props = __rest(_a, ["children", "isPrimary"]);
|
|
21
|
+
var { children, isPrimary, shouldRetainStyles } = _a, props = __rest(_a, ["children", "isPrimary", "shouldRetainStyles"]);
|
|
21
22
|
const { className } = props, rest = __rest(props, ["className"]);
|
|
22
23
|
// This allows us to parse the nested data we get back from the 3rd party Markdown parser
|
|
23
24
|
// Open to feedback here if there is a better way to do this
|
|
@@ -58,6 +59,6 @@ const TableMessage = (_a) => {
|
|
|
58
59
|
}
|
|
59
60
|
return (
|
|
60
61
|
// gridBreakPoint is so we show mobile-styled-PF table
|
|
61
|
-
_jsx(Table, Object.assign({ "aria-label": props['aria-label'], gridBreakPoint: "grid", className:
|
|
62
|
+
_jsx(Table, Object.assign({ "aria-label": props['aria-label'], gridBreakPoint: "grid", className: css('pf-chatbot__message-table', isPrimary && 'pf-m-primary', shouldRetainStyles && 'pf-m-markdown', className) }, rest, { children: modifyChildren(children) })));
|
|
62
63
|
};
|
|
63
64
|
export 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;
|
|
@@ -11,8 +11,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
13
|
import { Content } from '@patternfly/react-core';
|
|
14
|
+
import { css } from '@patternfly/react-styles';
|
|
14
15
|
const TextMessage = (_a) => {
|
|
15
|
-
var { component, children, isPrimary } = _a, props = __rest(_a, ["component", "children", "isPrimary"]);
|
|
16
|
-
return (_jsx("span", { className:
|
|
16
|
+
var { component, children, isPrimary, shouldRetainStyles } = _a, props = __rest(_a, ["component", "children", "isPrimary", "shouldRetainStyles"]);
|
|
17
|
+
return (_jsx("span", { className: css('pf-chatbot__message-text', isPrimary && 'pf-m-primary', shouldRetainStyles && 'pf-m-markdown'), children: _jsx(Content, Object.assign({ component: component }, props, { className: css(props === null || props === void 0 ? void 0 : props.className), children: children })) }));
|
|
17
18
|
};
|
|
18
19
|
export default TextMessage;
|
|
@@ -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;
|