@patternfly/chatbot 2.2.0-prerelease.23 → 2.2.0-prerelease.25
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/Message/ImageMessage/ImageMessage.d.ts +4 -0
- package/dist/cjs/Message/ImageMessage/ImageMessage.js +25 -0
- package/dist/cjs/Message/Message.d.ts +11 -1
- package/dist/cjs/Message/Message.js +38 -30
- package/dist/cjs/Message/Message.test.js +68 -0
- package/dist/cjs/MessageBar/MessageBar.d.ts +4 -4
- package/dist/cjs/MessageBar/MessageBar.js +2 -2
- package/dist/cjs/MessageBar/MessageBar.test.js +8 -0
- package/dist/cjs/__mocks__/rehype-unwrap-images.d.ts +2 -0
- package/dist/cjs/__mocks__/rehype-unwrap-images.js +4 -0
- package/dist/css/main.css +8 -0
- package/dist/css/main.css.map +1 -1
- package/dist/esm/Message/ImageMessage/ImageMessage.d.ts +4 -0
- package/dist/esm/Message/ImageMessage/ImageMessage.js +20 -0
- package/dist/esm/Message/Message.d.ts +11 -1
- package/dist/esm/Message/Message.js +38 -30
- package/dist/esm/Message/Message.test.js +68 -0
- package/dist/esm/MessageBar/MessageBar.d.ts +4 -4
- package/dist/esm/MessageBar/MessageBar.js +2 -2
- package/dist/esm/MessageBar/MessageBar.test.js +8 -0
- package/dist/esm/__mocks__/rehype-unwrap-images.d.ts +2 -0
- package/dist/esm/__mocks__/rehype-unwrap-images.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +11 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +11 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +11 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessageWithExtraContent.tsx +54 -0
- package/src/Message/ImageMessage/ImageMessage.scss +9 -0
- package/src/Message/ImageMessage/ImageMessage.tsx +14 -0
- package/src/Message/Message.test.tsx +120 -0
- package/src/Message/Message.tsx +59 -35
- package/src/MessageBar/MessageBar.test.tsx +8 -0
- package/src/MessageBar/MessageBar.tsx +6 -5
- package/src/__mocks__/rehype-unwrap-images.tsx +3 -0
- package/src/main.scss +1 -0
package/src/Message/Message.tsx
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
// Chatbot Main - Message
|
3
3
|
// ============================================================================
|
4
4
|
|
5
|
-
import React from 'react';
|
5
|
+
import React, { ReactNode } from 'react';
|
6
6
|
|
7
7
|
import Markdown from 'react-markdown';
|
8
8
|
import remarkGfm from 'remark-gfm';
|
@@ -36,6 +36,8 @@ import TbodyMessage from './TableMessage/TbodyMessage';
|
|
36
36
|
import TheadMessage from './TableMessage/TheadMessage';
|
37
37
|
import ThMessage from './TableMessage/ThMessage';
|
38
38
|
import { TableProps } from '@patternfly/react-table';
|
39
|
+
import ImageMessage from './ImageMessage/ImageMessage';
|
40
|
+
import rehypeUnwrapImages from 'rehype-unwrap-images';
|
39
41
|
|
40
42
|
export interface MessageAttachment {
|
41
43
|
/** Name of file attached to the message */
|
@@ -56,6 +58,17 @@ export interface MessageAttachment {
|
|
56
58
|
spinnerTestId?: string;
|
57
59
|
}
|
58
60
|
|
61
|
+
export interface MessageExtraContent {
|
62
|
+
/** Content to display before the main content */
|
63
|
+
beforeMainContent?: ReactNode;
|
64
|
+
|
65
|
+
/** Content to display after the main content */
|
66
|
+
afterMainContent?: ReactNode;
|
67
|
+
|
68
|
+
/** Content to display at the end */
|
69
|
+
endContent?: ReactNode;
|
70
|
+
}
|
71
|
+
|
59
72
|
export interface MessageProps extends Omit<React.HTMLProps<HTMLDivElement>, 'role'> {
|
60
73
|
/** Unique id for message */
|
61
74
|
id?: string;
|
@@ -63,6 +76,8 @@ export interface MessageProps extends Omit<React.HTMLProps<HTMLDivElement>, 'rol
|
|
63
76
|
role: 'user' | 'bot';
|
64
77
|
/** Message content */
|
65
78
|
content?: string;
|
79
|
+
/** Extra Message content */
|
80
|
+
extraContent?: MessageExtraContent;
|
66
81
|
/** Name of the user */
|
67
82
|
name?: string;
|
68
83
|
/** Avatar src for the user */
|
@@ -123,6 +138,7 @@ export interface MessageProps extends Omit<React.HTMLProps<HTMLDivElement>, 'rol
|
|
123
138
|
export const MessageBase: React.FunctionComponent<MessageProps> = ({
|
124
139
|
role,
|
125
140
|
content,
|
141
|
+
extraContent,
|
126
142
|
name,
|
127
143
|
avatar,
|
128
144
|
timestamp,
|
@@ -145,6 +161,7 @@ export const MessageBase: React.FunctionComponent<MessageProps> = ({
|
|
145
161
|
tableProps,
|
146
162
|
...props
|
147
163
|
}: MessageProps) => {
|
164
|
+
const { beforeMainContent, afterMainContent, endContent } = extraContent || {};
|
148
165
|
let avatarClassName;
|
149
166
|
if (avatarProps && 'className' in avatarProps) {
|
150
167
|
const { className, ...rest } = avatarProps;
|
@@ -189,40 +206,46 @@ export const MessageBase: React.FunctionComponent<MessageProps> = ({
|
|
189
206
|
{isLoading ? (
|
190
207
|
<MessageLoading loadingWord={loadingWord} />
|
191
208
|
) : (
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
<
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
209
|
+
<>
|
210
|
+
{beforeMainContent && <>{beforeMainContent}</>}
|
211
|
+
<Markdown
|
212
|
+
components={{
|
213
|
+
p: (props) => <TextMessage component={ContentVariants.p} {...props} />,
|
214
|
+
code: ({ children, ...props }) => (
|
215
|
+
<CodeBlockMessage {...props} {...codeBlockProps}>
|
216
|
+
{children}
|
217
|
+
</CodeBlockMessage>
|
218
|
+
),
|
219
|
+
h1: (props) => <TextMessage component={ContentVariants.h1} {...props} />,
|
220
|
+
h2: (props) => <TextMessage component={ContentVariants.h2} {...props} />,
|
221
|
+
h3: (props) => <TextMessage component={ContentVariants.h3} {...props} />,
|
222
|
+
h4: (props) => <TextMessage component={ContentVariants.h4} {...props} />,
|
223
|
+
h5: (props) => <TextMessage component={ContentVariants.h5} {...props} />,
|
224
|
+
h6: (props) => <TextMessage component={ContentVariants.h6} {...props} />,
|
225
|
+
blockquote: (props) => <TextMessage component={ContentVariants.blockquote} {...props} />,
|
226
|
+
ul: (props) => <UnorderedListMessage {...props} />,
|
227
|
+
ol: (props) => <OrderedListMessage {...props} />,
|
228
|
+
li: (props) => <ListItemMessage {...props} />,
|
229
|
+
table: (props) => <TableMessage {...props} {...tableProps} />,
|
230
|
+
tbody: (props) => <TbodyMessage {...props} />,
|
231
|
+
thead: (props) => <TheadMessage {...props} />,
|
232
|
+
tr: (props) => <TrMessage {...props} />,
|
233
|
+
td: (props) => {
|
234
|
+
// Conflicts with Td type
|
235
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
236
|
+
const { width, ...rest } = props;
|
237
|
+
return <TdMessage {...rest} />;
|
238
|
+
},
|
239
|
+
th: (props) => <ThMessage {...props} />,
|
240
|
+
img: (props) => <ImageMessage {...props} />
|
241
|
+
}}
|
242
|
+
remarkPlugins={[remarkGfm]}
|
243
|
+
rehypePlugins={[rehypeUnwrapImages]}
|
244
|
+
>
|
245
|
+
{content}
|
246
|
+
</Markdown>
|
247
|
+
{afterMainContent && <>{afterMainContent}</>}
|
248
|
+
</>
|
226
249
|
)}
|
227
250
|
{!isLoading && sources && <SourcesCard {...sources} />}
|
228
251
|
{quickStarts && quickStarts.quickStart && (
|
@@ -264,6 +287,7 @@ export const MessageBase: React.FunctionComponent<MessageProps> = ({
|
|
264
287
|
))}
|
265
288
|
</div>
|
266
289
|
)}
|
290
|
+
{!isLoading && endContent && <>{endContent}</>}
|
267
291
|
</div>
|
268
292
|
</div>
|
269
293
|
</section>
|
@@ -315,4 +315,12 @@ describe('Message bar', () => {
|
|
315
315
|
);
|
316
316
|
await userEvent.click(screen.getByRole('button', { name: 'Test' }));
|
317
317
|
});
|
318
|
+
it('can be controlled', () => {
|
319
|
+
render(<MessageBar onSendMessage={jest.fn} value="test" />);
|
320
|
+
expect(screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
|
321
|
+
expect(screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
|
322
|
+
expect(screen.queryByRole('button', { name: 'Microphone button' })).toBeFalsy();
|
323
|
+
expect(screen.getByRole('textbox', { name: /Send a message.../i })).toBeTruthy();
|
324
|
+
expect(screen.getByRole('textbox', { name: /Send a message.../i })).toHaveValue('test');
|
325
|
+
});
|
318
326
|
});
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import { ButtonProps, DropEvent, TextArea } from '@patternfly/react-core';
|
2
|
+
import { ButtonProps, DropEvent, TextArea, TextAreaProps } from '@patternfly/react-core';
|
3
3
|
|
4
4
|
// Import Chatbot components
|
5
5
|
import SendButton from './SendButton';
|
@@ -30,9 +30,9 @@ export interface MessageBarWithAttachMenuProps {
|
|
30
30
|
onAttachMenuOpenChange?: (isOpen: boolean) => void;
|
31
31
|
}
|
32
32
|
|
33
|
-
export interface MessageBarProps {
|
33
|
+
export interface MessageBarProps extends TextAreaProps {
|
34
34
|
/** Callback to get the value of input message by user */
|
35
|
-
onSendMessage: (message: string) => void;
|
35
|
+
onSendMessage: (message: string | number) => void;
|
36
36
|
/** Class Name for the MessageBar component */
|
37
37
|
className?: string;
|
38
38
|
/** Flag to always to show the send button. By default send button is shown when there is a message in the input field */
|
@@ -63,7 +63,7 @@ export interface MessageBarProps {
|
|
63
63
|
};
|
64
64
|
};
|
65
65
|
/** A callback for when the text area value changes. */
|
66
|
-
onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>, value: string) => void;
|
66
|
+
onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>, value: string | number) => void;
|
67
67
|
/** Display mode of chatbot, if you want to message bar to resize when the display mode changes */
|
68
68
|
displayMode?: ChatbotDisplayMode;
|
69
69
|
}
|
@@ -82,11 +82,12 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
|
|
82
82
|
buttonProps,
|
83
83
|
onChange,
|
84
84
|
displayMode,
|
85
|
+
value,
|
85
86
|
...props
|
86
87
|
}: MessageBarProps) => {
|
87
88
|
// Text Input
|
88
89
|
// --------------------------------------------------------------------------
|
89
|
-
const [message, setMessage] = React.useState<string>('');
|
90
|
+
const [message, setMessage] = React.useState<string | number>(value ?? '');
|
90
91
|
const [isListeningMessage, setIsListeningMessage] = React.useState<boolean>(false);
|
91
92
|
const [hasSentMessage, setHasSentMessage] = React.useState(false);
|
92
93
|
const textareaRef = React.useRef<HTMLTextAreaElement>(null);
|
package/src/main.scss
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
@import './FileDropZone/FileDropZone';
|
17
17
|
@import './Message/Message';
|
18
18
|
@import './Message/CodeBlockMessage/CodeBlockMessage';
|
19
|
+
@import './Message/ImageMessage/ImageMessage';
|
19
20
|
@import './Message/TextMessage/TextMessage';
|
20
21
|
@import './Message/ListMessage/ListMessage';
|
21
22
|
@import './Message/TableMessage/TableMessage';
|