@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
|
@@ -4,9 +4,23 @@
|
|
|
4
4
|
|
|
5
5
|
import { ExtraProps } from 'react-markdown';
|
|
6
6
|
import { List, ListComponent, OrderType } from '@patternfly/react-core';
|
|
7
|
+
import { css } from '@patternfly/react-styles';
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
export interface OrderedListMessageProps {
|
|
10
|
+
/** The ordered list content */
|
|
11
|
+
children?: React.ReactNode;
|
|
12
|
+
/** The number to start the ordered list at. */
|
|
13
|
+
start?: number;
|
|
14
|
+
/** Flag indicating that the content should retain message styles when using Markdown. */
|
|
15
|
+
shouldRetainStyles?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const OrderedListMessage = ({
|
|
19
|
+
children,
|
|
20
|
+
start,
|
|
21
|
+
shouldRetainStyles
|
|
22
|
+
}: OrderedListMessageProps & JSX.IntrinsicElements['ol'] & ExtraProps) => (
|
|
23
|
+
<div className={css('pf-chatbot__message-ordered-list', shouldRetainStyles && 'pf-m-markdown')}>
|
|
10
24
|
<List component={ListComponent.ol} type={OrderType.number} start={start}>
|
|
11
25
|
{children}
|
|
12
26
|
</List>
|
|
@@ -4,9 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
import { ExtraProps } from 'react-markdown';
|
|
6
6
|
import { List } from '@patternfly/react-core';
|
|
7
|
+
import { css } from '@patternfly/react-styles';
|
|
8
|
+
export interface UnrderedListMessageProps {
|
|
9
|
+
/** The ordered list content */
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
/** Flag indicating that the content should retain message styles when using Markdown. */
|
|
12
|
+
shouldRetainStyles?: boolean;
|
|
13
|
+
}
|
|
7
14
|
|
|
8
|
-
const UnorderedListMessage = ({
|
|
9
|
-
|
|
15
|
+
const UnorderedListMessage = ({
|
|
16
|
+
children,
|
|
17
|
+
shouldRetainStyles
|
|
18
|
+
}: UnrderedListMessageProps & JSX.IntrinsicElements['ul'] & ExtraProps) => (
|
|
19
|
+
<div className={css('pf-chatbot__message-unordered-list', shouldRetainStyles && 'pf-m-markdown')}>
|
|
10
20
|
<List>{children}</List>
|
|
11
21
|
</div>
|
|
12
22
|
);
|
package/src/Message/Message.tsx
CHANGED
|
@@ -3,14 +3,12 @@
|
|
|
3
3
|
// ============================================================================
|
|
4
4
|
import { forwardRef, ReactNode, useEffect, useState } from 'react';
|
|
5
5
|
import type { FunctionComponent, HTMLProps, MouseEvent as ReactMouseEvent, Ref } from 'react';
|
|
6
|
-
import
|
|
7
|
-
import remarkGfm from 'remark-gfm';
|
|
6
|
+
import { Options } from 'react-markdown';
|
|
8
7
|
import {
|
|
9
8
|
AlertProps,
|
|
10
9
|
Avatar,
|
|
11
10
|
AvatarProps,
|
|
12
11
|
ButtonProps,
|
|
13
|
-
ContentVariants,
|
|
14
12
|
FormProps,
|
|
15
13
|
Label,
|
|
16
14
|
LabelGroupProps,
|
|
@@ -18,42 +16,25 @@ import {
|
|
|
18
16
|
Truncate
|
|
19
17
|
} from '@patternfly/react-core';
|
|
20
18
|
import MessageLoading from './MessageLoading';
|
|
21
|
-
import
|
|
22
|
-
import TextMessage from './TextMessage/TextMessage';
|
|
19
|
+
import { CodeBlockMessageProps } from './CodeBlockMessage/CodeBlockMessage';
|
|
23
20
|
import FileDetailsLabel from '../FileDetailsLabel/FileDetailsLabel';
|
|
24
21
|
import ResponseActions, { ActionProps } from '../ResponseActions/ResponseActions';
|
|
25
22
|
import SourcesCard, { SourcesCardProps } from '../SourcesCard';
|
|
26
|
-
import ListItemMessage from './ListMessage/ListItemMessage';
|
|
27
|
-
import UnorderedListMessage from './ListMessage/UnorderedListMessage';
|
|
28
|
-
import OrderedListMessage from './ListMessage/OrderedListMessage';
|
|
29
23
|
import QuickStartTile from './QuickStarts/QuickStartTile';
|
|
30
24
|
import { QuickStart, QuickstartAction } from './QuickStarts/types';
|
|
31
25
|
import QuickResponse from './QuickResponse/QuickResponse';
|
|
32
26
|
import UserFeedback, { UserFeedbackProps } from './UserFeedback/UserFeedback';
|
|
33
27
|
import UserFeedbackComplete, { UserFeedbackCompleteProps } from './UserFeedback/UserFeedbackComplete';
|
|
34
|
-
import TableMessage from './TableMessage/TableMessage';
|
|
35
|
-
import TrMessage from './TableMessage/TrMessage';
|
|
36
|
-
import TdMessage from './TableMessage/TdMessage';
|
|
37
|
-
import TbodyMessage from './TableMessage/TbodyMessage';
|
|
38
|
-
import TheadMessage from './TableMessage/TheadMessage';
|
|
39
|
-
import ThMessage from './TableMessage/ThMessage';
|
|
40
28
|
import { TableProps } from '@patternfly/react-table';
|
|
41
|
-
import ImageMessage from './ImageMessage/ImageMessage';
|
|
42
|
-
import rehypeUnwrapImages from 'rehype-unwrap-images';
|
|
43
|
-
import rehypeExternalLinks from 'rehype-external-links';
|
|
44
|
-
import rehypeSanitize from 'rehype-sanitize';
|
|
45
|
-
import rehypeHighlight from 'rehype-highlight';
|
|
46
29
|
// see the full list of styles here: https://highlightjs.org/examples
|
|
47
30
|
import 'highlight.js/styles/vs2015.css';
|
|
48
31
|
import { PluggableList } from 'unified';
|
|
49
|
-
import LinkMessage from './LinkMessage/LinkMessage';
|
|
50
32
|
import ErrorMessage from './ErrorMessage/ErrorMessage';
|
|
51
33
|
import MessageInput from './MessageInput';
|
|
52
|
-
import { rehypeMoveImagesOutOfParagraphs } from './Plugins/rehypeMoveImagesOutOfParagraphs';
|
|
53
34
|
import ToolResponse, { ToolResponseProps } from '../ToolResponse';
|
|
54
35
|
import DeepThinking, { DeepThinkingProps } from '../DeepThinking';
|
|
55
|
-
import SuperscriptMessage from './SuperscriptMessage/SuperscriptMessage';
|
|
56
36
|
import ToolCall, { ToolCallProps } from '../ToolCall';
|
|
37
|
+
import MarkdownContent from '../MarkdownContent';
|
|
57
38
|
|
|
58
39
|
export interface MessageAttachment {
|
|
59
40
|
/** Name of file attached to the message */
|
|
@@ -267,14 +248,8 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
|
|
|
267
248
|
}, [content]);
|
|
268
249
|
|
|
269
250
|
const { beforeMainContent, afterMainContent, endContent } = extraContent || {};
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
rehypePlugins = rehypePlugins.concat([[rehypeExternalLinks, { target: '_blank' }, rehypeSanitize]]);
|
|
273
|
-
}
|
|
274
|
-
if (additionalRehypePlugins) {
|
|
275
|
-
rehypePlugins.push(...additionalRehypePlugins);
|
|
276
|
-
}
|
|
277
|
-
let avatarClassName;
|
|
251
|
+
|
|
252
|
+
let avatarClassName: string | undefined;
|
|
278
253
|
if (avatarProps && 'className' in avatarProps) {
|
|
279
254
|
const { className, ...rest } = avatarProps;
|
|
280
255
|
avatarClassName = className;
|
|
@@ -284,157 +259,22 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
|
|
|
284
259
|
const date = new Date();
|
|
285
260
|
const dateString = timestamp ?? `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
|
|
286
261
|
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
section: (props) => {
|
|
304
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
305
|
-
const { node, ...rest } = props;
|
|
306
|
-
return <section {...rest} className={`pf-chatbot__message-text ${rest?.className}`} />;
|
|
307
|
-
},
|
|
308
|
-
p: (props) => {
|
|
309
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
310
|
-
const { node, ...rest } = props;
|
|
311
|
-
return <TextMessage component={ContentVariants.p} {...rest} isPrimary={isPrimary} />;
|
|
312
|
-
},
|
|
313
|
-
code: ({ children, ...props }) => {
|
|
314
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
315
|
-
const { node, ...codeProps } = props;
|
|
316
|
-
return (
|
|
317
|
-
<CodeBlockMessage {...codeProps} {...codeBlockProps} isPrimary={isPrimary}>
|
|
318
|
-
{children}
|
|
319
|
-
</CodeBlockMessage>
|
|
320
|
-
);
|
|
321
|
-
},
|
|
322
|
-
h1: (props) => {
|
|
323
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
324
|
-
const { node, ...rest } = props;
|
|
325
|
-
return <TextMessage component={ContentVariants.h1} {...rest} />;
|
|
326
|
-
},
|
|
327
|
-
h2: (props) => {
|
|
328
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
329
|
-
const { node, ...rest } = props;
|
|
330
|
-
return <TextMessage component={ContentVariants.h2} {...rest} />;
|
|
331
|
-
},
|
|
332
|
-
h3: (props) => {
|
|
333
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
334
|
-
const { node, ...rest } = props;
|
|
335
|
-
return <TextMessage component={ContentVariants.h3} {...rest} />;
|
|
336
|
-
},
|
|
337
|
-
h4: (props) => {
|
|
338
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
339
|
-
const { node, ...rest } = props;
|
|
340
|
-
return <TextMessage component={ContentVariants.h4} {...rest} />;
|
|
341
|
-
},
|
|
342
|
-
h5: (props) => {
|
|
343
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
344
|
-
const { node, ...rest } = props;
|
|
345
|
-
return <TextMessage component={ContentVariants.h5} {...rest} />;
|
|
346
|
-
},
|
|
347
|
-
h6: (props) => {
|
|
348
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
349
|
-
const { node, ...rest } = props;
|
|
350
|
-
return <TextMessage component={ContentVariants.h6} {...rest} />;
|
|
351
|
-
},
|
|
352
|
-
blockquote: (props) => {
|
|
353
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
354
|
-
const { node, ...rest } = props;
|
|
355
|
-
return <TextMessage component={ContentVariants.blockquote} {...rest} />;
|
|
356
|
-
},
|
|
357
|
-
ul: (props) => {
|
|
358
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
359
|
-
const { node, ...rest } = props;
|
|
360
|
-
return <UnorderedListMessage {...rest} />;
|
|
361
|
-
},
|
|
362
|
-
ol: (props) => {
|
|
363
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
364
|
-
const { node, ...rest } = props;
|
|
365
|
-
return <OrderedListMessage {...rest} />;
|
|
366
|
-
},
|
|
367
|
-
li: (props) => {
|
|
368
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
369
|
-
const { node, ...rest } = props;
|
|
370
|
-
return <ListItemMessage {...rest} />;
|
|
371
|
-
},
|
|
372
|
-
// table requires node attribute for calculating headers for mobile breakpoint
|
|
373
|
-
table: (props) => <TableMessage {...props} {...tableProps} isPrimary={isPrimary} />,
|
|
374
|
-
tbody: (props) => {
|
|
375
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
376
|
-
const { node, ...rest } = props;
|
|
377
|
-
return <TbodyMessage {...rest} />;
|
|
378
|
-
},
|
|
379
|
-
thead: (props) => {
|
|
380
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
381
|
-
const { node, ...rest } = props;
|
|
382
|
-
return <TheadMessage {...rest} />;
|
|
383
|
-
},
|
|
384
|
-
tr: (props) => {
|
|
385
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
386
|
-
const { node, ...rest } = props;
|
|
387
|
-
return <TrMessage {...rest} />;
|
|
388
|
-
},
|
|
389
|
-
td: (props) => {
|
|
390
|
-
// Conflicts with Td type
|
|
391
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
392
|
-
const { node, width, ...rest } = props;
|
|
393
|
-
return <TdMessage {...rest} />;
|
|
394
|
-
},
|
|
395
|
-
th: (props) => {
|
|
396
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
397
|
-
const { node, ...rest } = props;
|
|
398
|
-
return <ThMessage {...rest} />;
|
|
399
|
-
},
|
|
400
|
-
img: (props) => {
|
|
401
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
402
|
-
const { node, ...rest } = props;
|
|
403
|
-
return <ImageMessage {...rest} />;
|
|
404
|
-
},
|
|
405
|
-
a: (props) => {
|
|
406
|
-
// node is just the details of the document structure - not needed
|
|
407
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
408
|
-
const { node, ...rest } = props;
|
|
409
|
-
return (
|
|
410
|
-
// some a types conflict with ButtonProps, but it's ok because we are using an a tag
|
|
411
|
-
// there are too many to handle manually
|
|
412
|
-
<LinkMessage {...(rest as any)} {...linkProps}>
|
|
413
|
-
{props.children}
|
|
414
|
-
</LinkMessage>
|
|
415
|
-
);
|
|
416
|
-
},
|
|
417
|
-
// used for footnotes
|
|
418
|
-
sup: (props) => {
|
|
419
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
420
|
-
const { node, ...rest } = props;
|
|
421
|
-
return <SuperscriptMessage {...rest} />;
|
|
422
|
-
}
|
|
423
|
-
}}
|
|
424
|
-
remarkPlugins={[[remarkGfm, { ...remarkGfmProps }], ...additionalRemarkPlugins]}
|
|
425
|
-
rehypePlugins={rehypePlugins}
|
|
426
|
-
{...reactMarkdownProps}
|
|
427
|
-
remarkRehypeOptions={{
|
|
428
|
-
// removes sr-only class from footnote labels applied by default
|
|
429
|
-
footnoteLabelProperties: { className: [''] },
|
|
430
|
-
...reactMarkdownProps?.remarkRehypeOptions
|
|
431
|
-
}}
|
|
432
|
-
disallowedElements={disallowedElements}
|
|
433
|
-
>
|
|
434
|
-
{messageText}
|
|
435
|
-
</Markdown>
|
|
436
|
-
);
|
|
437
|
-
};
|
|
262
|
+
const handleMarkdown = () => (
|
|
263
|
+
<MarkdownContent
|
|
264
|
+
content={messageText}
|
|
265
|
+
isMarkdownDisabled={isMarkdownDisabled}
|
|
266
|
+
codeBlockProps={codeBlockProps}
|
|
267
|
+
tableProps={tableProps}
|
|
268
|
+
openLinkInNewTab={openLinkInNewTab}
|
|
269
|
+
additionalRehypePlugins={additionalRehypePlugins}
|
|
270
|
+
additionalRemarkPlugins={additionalRemarkPlugins}
|
|
271
|
+
linkProps={linkProps}
|
|
272
|
+
reactMarkdownProps={reactMarkdownProps}
|
|
273
|
+
remarkGfmProps={remarkGfmProps}
|
|
274
|
+
hasNoImages={role === 'user' && hasNoImagesInUserMessages}
|
|
275
|
+
isPrimary={isPrimary}
|
|
276
|
+
/>
|
|
277
|
+
);
|
|
438
278
|
|
|
439
279
|
const renderMessage = () => {
|
|
440
280
|
if (isLoading) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
.pf-chatbot__message-quick-response {
|
|
2
2
|
.pf-v6-c-label {
|
|
3
|
-
|
|
3
|
+
&:not(.pf-m-compact) {
|
|
4
|
+
--pf-v6-c-label--FontSize: var(--pf-t--global--font--size--md);
|
|
5
|
+
}
|
|
4
6
|
|
|
5
7
|
@media screen and (min-width: 401px) and (max-width: 600px) {
|
|
6
8
|
--pf-v6-c-label__text--MaxWidth: 20ch;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { Children, cloneElement } from 'react';
|
|
6
6
|
import { ExtraProps } from 'react-markdown';
|
|
7
7
|
import { Table, TableProps } from '@patternfly/react-table';
|
|
8
|
+
import { css } from '@patternfly/react-styles';
|
|
8
9
|
|
|
9
10
|
interface Properties {
|
|
10
11
|
line: number;
|
|
@@ -20,10 +21,20 @@ export interface TableNode {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export interface TableMessageProps {
|
|
24
|
+
/** Content of the table */
|
|
25
|
+
children?: React.ReactNode;
|
|
26
|
+
/** Flag indicating whether primary styles should be applied. */
|
|
23
27
|
isPrimary?: boolean;
|
|
28
|
+
/** Flag indicating that the content should retain message styles when using Markdown. */
|
|
29
|
+
shouldRetainStyles?: boolean;
|
|
24
30
|
}
|
|
25
31
|
|
|
26
|
-
const TableMessage = ({
|
|
32
|
+
const TableMessage = ({
|
|
33
|
+
children,
|
|
34
|
+
isPrimary,
|
|
35
|
+
shouldRetainStyles,
|
|
36
|
+
...props
|
|
37
|
+
}: Omit<TableProps, 'ref'> & ExtraProps & TableMessageProps) => {
|
|
27
38
|
const { className, ...rest } = props;
|
|
28
39
|
|
|
29
40
|
// This allows us to parse the nested data we get back from the 3rd party Markdown parser
|
|
@@ -76,7 +87,12 @@ const TableMessage = ({ children, isPrimary, ...props }: Omit<TableProps, 'ref'>
|
|
|
76
87
|
<Table
|
|
77
88
|
aria-label={props['aria-label']}
|
|
78
89
|
gridBreakPoint="grid"
|
|
79
|
-
className={
|
|
90
|
+
className={css(
|
|
91
|
+
'pf-chatbot__message-table',
|
|
92
|
+
isPrimary && 'pf-m-primary',
|
|
93
|
+
shouldRetainStyles && 'pf-m-markdown',
|
|
94
|
+
className
|
|
95
|
+
)}
|
|
80
96
|
{...rest}
|
|
81
97
|
>
|
|
82
98
|
{modifyChildren(children)}
|
|
@@ -53,6 +53,14 @@
|
|
|
53
53
|
background-color: var(--pf-t--global--background--color--secondary--default);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
+
|
|
57
|
+
&.pf-m-markdown {
|
|
58
|
+
display: block;
|
|
59
|
+
}
|
|
60
|
+
&.pf-m-markdown > [class^='pf-v6-c-content'] {
|
|
61
|
+
font-size: inherit;
|
|
62
|
+
color: inherit;
|
|
63
|
+
}
|
|
56
64
|
}
|
|
57
65
|
|
|
58
66
|
// ============================================================================
|
|
@@ -4,19 +4,46 @@
|
|
|
4
4
|
|
|
5
5
|
import { ExtraProps } from 'react-markdown';
|
|
6
6
|
import { Content, ContentProps } from '@patternfly/react-core';
|
|
7
|
+
import { css } from '@patternfly/react-styles';
|
|
7
8
|
|
|
8
9
|
export interface TextMessageProps {
|
|
10
|
+
/** The text message content */
|
|
11
|
+
children?: React.ReactNode;
|
|
12
|
+
/** Flag indicating whether primary styling is applied. */
|
|
9
13
|
isPrimary?: boolean;
|
|
14
|
+
/** The wrapper component to use for the PatternFly Content component. Defaults to a div. */
|
|
15
|
+
component?:
|
|
16
|
+
| 'h1'
|
|
17
|
+
| 'h2'
|
|
18
|
+
| 'h3'
|
|
19
|
+
| 'h4'
|
|
20
|
+
| 'h5'
|
|
21
|
+
| 'h6'
|
|
22
|
+
| 'p'
|
|
23
|
+
| 'a'
|
|
24
|
+
| 'small'
|
|
25
|
+
| 'blockquote'
|
|
26
|
+
| 'pre'
|
|
27
|
+
| 'hr'
|
|
28
|
+
| 'ul'
|
|
29
|
+
| 'ol'
|
|
30
|
+
| 'dl'
|
|
31
|
+
| 'li'
|
|
32
|
+
| 'dt'
|
|
33
|
+
| 'dd';
|
|
34
|
+
/** Flag indicating that the content should retain message styles when using Markdown. */
|
|
35
|
+
shouldRetainStyles?: boolean;
|
|
10
36
|
}
|
|
11
37
|
|
|
12
38
|
const TextMessage = ({
|
|
13
39
|
component,
|
|
14
40
|
children,
|
|
15
41
|
isPrimary,
|
|
42
|
+
shouldRetainStyles,
|
|
16
43
|
...props
|
|
17
44
|
}: Omit<ContentProps, 'ref'> & ExtraProps & TextMessageProps) => (
|
|
18
|
-
<span className={
|
|
19
|
-
<Content component={component} {...props}>
|
|
45
|
+
<span className={css('pf-chatbot__message-text', isPrimary && 'pf-m-primary', shouldRetainStyles && 'pf-m-markdown')}>
|
|
46
|
+
<Content component={component} {...props} className={css(props?.className)}>
|
|
20
47
|
{children}
|
|
21
48
|
</Content>
|
|
22
49
|
</span>
|
|
@@ -36,6 +36,11 @@
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// feedback card
|
|
39
|
+
.pf-chatbot__feedback-card-complete-header {
|
|
40
|
+
.pf-v6-c-card__actions {
|
|
41
|
+
--pf-v6-c-card__actions--MarginBlockEnd: calc(var(--pf-t--global--spacer--xl) * -1);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
39
44
|
.pf-chatbot__feedback-card-title {
|
|
40
45
|
font-family: var(--pf-t--global--font--family--heading);
|
|
41
46
|
font-size: var(--pf-t--global--font--size--md);
|
|
@@ -51,10 +56,32 @@
|
|
|
51
56
|
font-weight: initial;
|
|
52
57
|
}
|
|
53
58
|
|
|
59
|
+
// Privacy statement
|
|
60
|
+
.pf-chatbot__feedback-card-privacy {
|
|
61
|
+
font-size: var(--pf-t--global--font--size--body--sm);
|
|
62
|
+
font-weight: var(--pf-t--global--font--weight--body--default);
|
|
63
|
+
line-height: var(--pf-t--global--font--line-height--body);
|
|
64
|
+
color: var(--pf-t--global--text--color--subtle);
|
|
65
|
+
}
|
|
66
|
+
|
|
54
67
|
// Compact styles
|
|
55
68
|
.pf-v6-c-card.pf-m-compact.pf-chatbot__feedback-card {
|
|
69
|
+
--pf-v6-c-card--first-child--PaddingBlockStart: var(--pf-t--global--spacer--md);
|
|
70
|
+
--pf-v6-c-card--child--PaddingInlineEnd: var(--pf-t--global--spacer--md);
|
|
71
|
+
--pf-v6-c-card--child--PaddingInlineStart: var(--pf-t--global--spacer--md);
|
|
72
|
+
--pf-v6-c-card--last-child--PaddingBlockEnd: var(--pf-t--global--spacer--md);
|
|
73
|
+
--pf-v6-c-card__title--not--last-child--PaddingBlockEnd: var(--pf-t--global--spacer--md);
|
|
74
|
+
|
|
56
75
|
.pf-chatbot__feedback-card-form.pf-m-compact {
|
|
57
|
-
--pf-v6-c-form--GridGap: var(--pf-t--global--spacer--
|
|
76
|
+
--pf-v6-c-form--GridGap: var(--pf-t--global--spacer--sm);
|
|
77
|
+
|
|
78
|
+
.pf-v6-c-form__group.pf-m-action {
|
|
79
|
+
margin-block-start: var(--pf-t--global--spacer--sm);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.pf-v6-c-form-control {
|
|
83
|
+
font-size: var(--pf-t--global--font--size--body--sm);
|
|
84
|
+
}
|
|
58
85
|
}
|
|
59
86
|
}
|
|
60
87
|
|
|
@@ -74,6 +74,8 @@ export interface UserFeedbackProps extends Omit<CardProps, 'onSubmit'>, OUIAProp
|
|
|
74
74
|
textAreaProps?: TextAreaProps;
|
|
75
75
|
/** Additional props passed to action group */
|
|
76
76
|
actionGroupProps?: ActionGroupProps;
|
|
77
|
+
/** Optional privacy statement text displayed under text area */
|
|
78
|
+
privacyStatement?: string;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
const UserFeedback: FunctionComponent<UserFeedbackProps> = ({
|
|
@@ -102,6 +104,7 @@ const UserFeedback: FunctionComponent<UserFeedbackProps> = ({
|
|
|
102
104
|
textAreaProps,
|
|
103
105
|
actionGroupProps,
|
|
104
106
|
submitButtonProps,
|
|
107
|
+
privacyStatement,
|
|
105
108
|
...props
|
|
106
109
|
}: UserFeedbackProps) => {
|
|
107
110
|
const [selectedResponse, setSelectedResponse] = useState<string>();
|
|
@@ -139,21 +142,28 @@ const UserFeedback: FunctionComponent<UserFeedbackProps> = ({
|
|
|
139
142
|
/>
|
|
140
143
|
)}
|
|
141
144
|
{hasTextArea && (
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
145
|
+
<>
|
|
146
|
+
<TextArea
|
|
147
|
+
value={value}
|
|
148
|
+
onChange={(_event, value) => {
|
|
149
|
+
setValue(value);
|
|
150
|
+
onTextAreaChange && onTextAreaChange(_event, value);
|
|
151
|
+
}}
|
|
152
|
+
placeholder={textAreaPlaceholder}
|
|
153
|
+
aria-label={textAreaAriaLabel}
|
|
154
|
+
resizeOrientation="vertical"
|
|
155
|
+
{...textAreaProps}
|
|
156
|
+
/>
|
|
157
|
+
</>
|
|
153
158
|
)}
|
|
159
|
+
{privacyStatement && <div className="pf-chatbot__feedback-card-privacy">{privacyStatement}</div>}
|
|
154
160
|
{children}
|
|
155
161
|
<ActionGroup {...actionGroupProps}>
|
|
156
|
-
<Button
|
|
162
|
+
<Button
|
|
163
|
+
onClick={() => onSubmit(selectedResponse, value)}
|
|
164
|
+
size={isCompact ? 'sm' : undefined}
|
|
165
|
+
{...submitButtonProps}
|
|
166
|
+
>
|
|
157
167
|
{submitWord}
|
|
158
168
|
</Button>
|
|
159
169
|
</ActionGroup>
|
|
@@ -147,13 +147,22 @@
|
|
|
147
147
|
.pf-chatbot__message-textarea {
|
|
148
148
|
font-size: var(--pf-t--global--font--size--sm) !important;
|
|
149
149
|
}
|
|
150
|
+
}
|
|
150
151
|
|
|
152
|
+
.pf-m-compact {
|
|
151
153
|
.pf-chatbot__message-bar-actions {
|
|
152
|
-
padding-block-start: var(--pf-t--global--spacer--
|
|
153
|
-
padding-block-end: var(--pf-t--global--spacer--
|
|
154
|
+
padding-block-start: var(--pf-t--global--spacer--sm);
|
|
155
|
+
padding-block-end: var(--pf-t--global--spacer--sm);
|
|
154
156
|
}
|
|
155
157
|
}
|
|
156
158
|
|
|
159
|
+
// ============================================================================
|
|
160
|
+
// Multiline textarea styles (2+ lines)
|
|
161
|
+
// ============================================================================
|
|
162
|
+
.pf-chatbot__message-bar.pf-m-multiline {
|
|
163
|
+
border-radius: calc(var(--pf-t--global--border--radius--small) * 2);
|
|
164
|
+
}
|
|
165
|
+
|
|
157
166
|
// ============================================================================
|
|
158
167
|
// High contrast styles
|
|
159
168
|
// ============================================================================
|
|
@@ -161,6 +161,7 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
|
|
|
161
161
|
const [isListeningMessage, setIsListeningMessage] = useState<boolean>(false);
|
|
162
162
|
const [hasSentMessage, setHasSentMessage] = useState(false);
|
|
163
163
|
const [isComposing, setIsComposing] = useState(false);
|
|
164
|
+
const [isMultiline, setIsMultiline] = useState(false);
|
|
164
165
|
const inputRef = useRef<HTMLTextAreaElement>(null);
|
|
165
166
|
const textareaRef = (innerRef as React.RefObject<HTMLTextAreaElement>) ?? inputRef;
|
|
166
167
|
const attachButtonRef = useRef<HTMLButtonElement>(null);
|
|
@@ -209,6 +210,19 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
|
|
|
209
210
|
return lines > 2;
|
|
210
211
|
};
|
|
211
212
|
|
|
213
|
+
const checkIfMultiline = useCallback(
|
|
214
|
+
(field: HTMLTextAreaElement) => {
|
|
215
|
+
const parent = field.parentElement;
|
|
216
|
+
const grandparent = parent?.parentElement;
|
|
217
|
+
if (grandparent) {
|
|
218
|
+
const containerHeight = grandparent.offsetHeight;
|
|
219
|
+
const threshold = isCompact ? 56 : 70;
|
|
220
|
+
setIsMultiline(containerHeight > threshold);
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
[isCompact]
|
|
224
|
+
);
|
|
225
|
+
|
|
212
226
|
const setAutoWidth = useCallback((field: HTMLTextAreaElement) => {
|
|
213
227
|
const parent = field.parentElement;
|
|
214
228
|
if (parent) {
|
|
@@ -263,12 +277,14 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
|
|
|
263
277
|
if (field) {
|
|
264
278
|
if (field.value === '') {
|
|
265
279
|
setInitialLineHeight(field);
|
|
280
|
+
setIsMultiline(false);
|
|
266
281
|
} else {
|
|
267
282
|
setAutoHeight(field);
|
|
268
283
|
setAutoWidth(field);
|
|
284
|
+
checkIfMultiline(field);
|
|
269
285
|
}
|
|
270
286
|
}
|
|
271
|
-
}, [displayMode, message, setAutoWidth]);
|
|
287
|
+
}, [displayMode, message, setAutoWidth, checkIfMultiline]);
|
|
272
288
|
|
|
273
289
|
useEffect(() => {
|
|
274
290
|
const field = textareaRef.current;
|
|
@@ -284,13 +300,15 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
|
|
|
284
300
|
if (textareaRef.current) {
|
|
285
301
|
if (event.target.value === '') {
|
|
286
302
|
setInitialLineHeight(textareaRef.current);
|
|
303
|
+
setIsMultiline(false);
|
|
287
304
|
} else {
|
|
288
305
|
setAutoHeight(textareaRef.current);
|
|
306
|
+
checkIfMultiline(textareaRef.current);
|
|
289
307
|
}
|
|
290
308
|
}
|
|
291
309
|
setMessage(event.target.value);
|
|
292
310
|
},
|
|
293
|
-
[onChange]
|
|
311
|
+
[onChange, checkIfMultiline]
|
|
294
312
|
);
|
|
295
313
|
|
|
296
314
|
// Handle sending message
|
|
@@ -453,7 +471,7 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
|
|
|
453
471
|
return (
|
|
454
472
|
<AttachMenu
|
|
455
473
|
toggle={(toggleRef) => (
|
|
456
|
-
<div ref={toggleRef} className={
|
|
474
|
+
<div ref={toggleRef} className={css('pf-chatbot__message-bar', isMultiline && 'pf-m-multiline', className)}>
|
|
457
475
|
{messageBarContents}
|
|
458
476
|
</div>
|
|
459
477
|
)}
|
|
@@ -481,6 +499,7 @@ export const MessageBarBase: FunctionComponent<MessageBarProps> = ({
|
|
|
481
499
|
isPrimary && 'pf-m-primary',
|
|
482
500
|
hasAiIndicator && 'pf-v6-m-ai-indicator',
|
|
483
501
|
isThinking && 'pf-v6-m-thinking',
|
|
502
|
+
isMultiline && 'pf-m-multiline',
|
|
484
503
|
className
|
|
485
504
|
)}
|
|
486
505
|
>
|