Skip to content

Commit c16601f

Browse files
committed
Updated exports, added new example
1 parent f3b0af0 commit c16601f

File tree

14 files changed

+173
-32
lines changed

14 files changed

+173
-32
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { FunctionComponent } from 'react';
2+
import Message, {
3+
ErrorMessage,
4+
MessageAndActions,
5+
MessageAttachmentItem,
6+
MessageAttachmentsContainer,
7+
MessageLoading
8+
} from '@patternfly/chatbot/dist/dynamic/Message';
9+
import MarkdownContent from '@patternfly/chatbot/dist/dynamic/MarkdownContent';
10+
import ToolCall from '@patternfly/chatbot/dist/dynamic/ToolCall';
11+
import ToolResponse from '@patternfly/chatbot/dist/dynamic/ToolResponse';
12+
import FileDetailsLabel from '@patternfly/chatbot/dist/dynamic/FileDetailsLabel';
13+
import ResponseActions, { ResponseActionsGroups } from '@patternfly/chatbot/dist/dynamic/ResponseActions';
14+
import patternflyAvatar from './patternfly_avatar.jpg';
15+
import userAvatar from './user_avatar.svg';
16+
17+
export const MessageWithCustomStructure: FunctionComponent = () => (
18+
<>
19+
<Message name="Bot" role="bot" avatar={patternflyAvatar}>
20+
<MessageAndActions>
21+
<MarkdownContent
22+
content={`This is a basic message with a more custom, fine-tuned structure. You can pass markdown to the MarkdownContent component, such as **bold content with double asterisks** or _italic content with single underscores_.`}
23+
/>
24+
<ToolCall titleText="Calling 'awesome_tool'" loadingText="Loading 'awesome_tool'" isLoading={true} />
25+
<ToolResponse
26+
toggleContent="Tool response: fetch_user_data"
27+
subheading="Executed in 0.3 seconds"
28+
body="Successfully retrieved user data from the database."
29+
cardTitle="User Data Response"
30+
cardBody="The tool returned 150 user records matching the specified criteria."
31+
/>
32+
<ErrorMessage title="An issue placed within this custom structure." />
33+
<MarkdownContent
34+
isMarkdownDisabled
35+
textComponent={`You can also pass plain text without markdown to the MarkdownContent component by passing the isMarkdownDisabled prop. Optionally, you can also use the textComponent prop instead of content.`}
36+
/>
37+
<ToolCall titleText="Calling 'more_awesome_tool'" loadingText="Loading 'more_awesome_tool'" isLoading={true} />
38+
<ToolCall titleText="Calling 'even_more_awesome_tool'" loadingText="Loading 'even_more_awesome_tool'" />
39+
<MessageLoading loadingWord="Loading something in the middle of a custom structured message" />
40+
<MarkdownContent
41+
content={`You can even place a message loading state in the middle of a message, as seen above.`}
42+
/>
43+
<ResponseActionsGroups>
44+
<ResponseActions
45+
actions={{
46+
positive: { onClick: () => console.log('Good response'), ariaLabel: 'Good response' },
47+
negative: { onClick: () => console.log('Bad response'), ariaLabel: 'Bad response' }
48+
}}
49+
persistActionSelection={true}
50+
/>
51+
<ResponseActions
52+
actions={{
53+
copy: { onClick: () => console.log('Copied!'), ariaLabel: 'Copy' },
54+
download: { onClick: () => console.log('Downloaded!'), ariaLabel: 'Download' }
55+
}}
56+
persistActionSelection={false}
57+
/>
58+
<ResponseActions
59+
actions={{
60+
listen: { onClick: () => console.log('Listening'), ariaLabel: 'Listen' }
61+
}}
62+
persistActionSelection={true}
63+
/>
64+
</ResponseActionsGroups>
65+
</MessageAndActions>
66+
</Message>
67+
<Message name="User" role="user" avatar={userAvatar}>
68+
<MessageAndActions>
69+
<MarkdownContent content="This message is in the MessageAndActions container, and the file attachments below are in their own separate MessageAttachmentsContainer!" />
70+
</MessageAndActions>
71+
<MessageAttachmentsContainer>
72+
<MessageAttachmentItem>
73+
<FileDetailsLabel fileName="project-report.pdf" />
74+
</MessageAttachmentItem>
75+
<MessageAttachmentItem>
76+
<FileDetailsLabel fileName="data-analysis.csv" />
77+
</MessageAttachmentItem>
78+
<MessageAttachmentItem>
79+
<FileDetailsLabel fileName="presentation-slides.pptx" />
80+
</MessageAttachmentItem>
81+
</MessageAttachmentsContainer>
82+
</Message>
83+
</>
84+
);

packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,41 +12,42 @@ source: react
1212
# These are found through the sourceProps function provided in patternfly-docs.source.js
1313
propComponents:
1414
[
15-
'ActionProps',
1615
'AttachMenu',
1716
'AttachmentEdit',
18-
'FileDetailsProps',
19-
'FileDetailsLabelProps',
2017
'FileDropZone',
2118
'Message',
22-
'MessageAndActions',
23-
'ResponseActionsGroups',
24-
'ResponseActions',
25-
'MessageAttachmentsContainer',
26-
'MessageAttachmentItem',
27-
'MessageExtraContent',
28-
'MessageInput',
29-
'MessageLoading',
3019
'ErrorMessage',
31-
'PreviewAttachment',
32-
'QuickResponse',
33-
'QuickStartTile',
34-
'QuickStart',
35-
'QuickStartAction',
20+
'MessageLoadingProps',
21+
'MessageInputProps',
22+
'MessageAndActionsProps',
23+
'MarkdownContent',
24+
'QuickResponseProps',
25+
'QuickStartTileProps',
26+
'UserFeedback',
27+
'UserFeedbackComplete',
3628
'DeepThinking',
3729
'ToolCall',
3830
'ToolResponse',
3931
'SourcesCard',
40-
'UserFeedback',
41-
'UserFeedbackComplete',
42-
'UserFeedbackProps',
43-
'UserFeedbackCompleteProps'
32+
'ResponseActionsGroupsProps',
33+
'ResponseActionProps',
34+
'ActionProps',
35+
'MessageAttachmentsContainerProps',
36+
'MessageAttachmentItemProps',
37+
'FileDetailsProps',
38+
'FileDetailsLabelProps',
39+
'MessageExtraContent',
40+
'PreviewAttachment'
4441
]
4542
sortValue: 3
4643
---
4744

48-
import Message from '@patternfly/chatbot/dist/dynamic/Message';
45+
import Message, { ErrorMessage, MessageAndActions, MessageLoading, MessageAttachmentItem, MessageAttachmentsContainer } from '@patternfly/chatbot/dist/dynamic/Message';
46+
import MarkdownContent from '@patternfly/chatbot/dist/dynamic/MarkdownContent';
4947
import MessageDivider from '@patternfly/chatbot/dist/dynamic/MessageDivider';
48+
import ToolCall from '@patternfly/chatbot/dist/dynamic/ToolCall';
49+
import ResponseActions, { ResponseActionsGroups } from '@patternfly/chatbot/dist/dynamic/ResponseActions';
50+
import ToolResponse from '@patternfly/chatbot/dist/dynamic/ToolResponse';
5051
import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/esm/Message/Plugins/rehypeCodeBlockToggle';
5152
import SourcesCard from '@patternfly/chatbot/dist/dynamic/SourcesCard';
5253
import { ArrowCircleDownIcon, ArrowRightIcon, CheckCircleIcon, CopyIcon, CubeIcon, CubesIcon, DownloadIcon, InfoCircleIcon, OutlinedQuestionCircleIcon, RedoIcon, RobotIcon, WrenchIcon } from '@patternfly/react-icons';
@@ -286,6 +287,35 @@ You can add custom content to specific parts of a `<Message>` via the `extraCont
286287

287288
```
288289

290+
### Custom message structure
291+
292+
For more advanced use cases, you can build completely custom message structures by passing children directly to `<Message>`. This approach is useful when you need to customize the order or structure of message elements beyond what the standard props allow.
293+
294+
When creating custom message structures, you must follow an intended composable structure:
295+
296+
1. **Message content and actions** must be wrapped in `<MessageAndActions>`. This includes, but is not limited to:
297+
298+
- `<MarkdownContent>` - For rendering markdown or plain text content
299+
- `<ErrorMessage>`
300+
- `<MessageLoading>`
301+
- `<MessageInput>`
302+
- `<ToolCall>`
303+
- `<ToolResponse>`
304+
- `<DeepThinking>`
305+
- `<QuickResponse>`
306+
- `<QuickStartTile>`
307+
- `<UserFeedback>` and `<UserFeedbackComplete>`
308+
- `<SourcesCard>`
309+
- `<ResponseActionsGroups>` and `<ResponseActions>`
310+
311+
2. **File attachments** must be placed outside `<MessageAndActions>`, wrapped in attachment containers:
312+
- `<MessageAttachmentsContainer>` - Container for all attachments
313+
- `<MessageAttachmentItem>` - Individual attachment wrapper (contains `<FileDetailsLabel>` or other attachment components)
314+
315+
```ts file="./MessageWithCustomStructure.tsx"
316+
317+
```
318+
289319
## File attachments
290320

291321
### Messages with attachments

packages/module/src/Message/ErrorMessage/ErrorMessage.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,23 @@
44

55
import { Alert, AlertProps } from '@patternfly/react-core';
66

7-
const ErrorMessage = ({ title, actionLinks, children, ...props }: AlertProps) => (
8-
<Alert isInline variant="danger" title={title} actionLinks={actionLinks} {...props}>
7+
/**
8+
* ErrorMessage displays an inline danger alert for error states in messages.
9+
* Use this component when passing children to Message to display error information.
10+
*/
11+
export interface ErrorMessageProps extends Partial<AlertProps> {
12+
/** Title of the error alert */
13+
title?: React.ReactNode;
14+
/** Action links to display in the alert footer */
15+
actionLinks?: React.ReactNode;
16+
/** Content to display in the error alert body */
17+
children?: React.ReactNode;
18+
/** Additional classes for the error alert */
19+
className?: string;
20+
}
21+
22+
export const ErrorMessage = ({ title, actionLinks, children, className, ...props }: ErrorMessageProps) => (
23+
<Alert isInline variant="danger" title={title} actionLinks={actionLinks} className={className} {...props}>
924
{children}
1025
</Alert>
1126
);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './MessageAndActions';
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './MessageAttachmentItem';
2+
export * from './MessageAttachmentsContainer';

packages/module/src/Message/MessageInput.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export interface MessageInputProps extends FormProps {
2222
content?: string;
2323
}
2424

25-
const MessageInput: FunctionComponent<MessageInputProps> = ({
25+
export const MessageInput: FunctionComponent<MessageInputProps> = ({
2626
editPlaceholder = 'Edit prompt message...',
2727
updateWord = 'Update',
2828
cancelWord = 'Cancel',

packages/module/src/Message/MessageLoading.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export interface MessageLoadingProps extends HTMLProps<HTMLDivElement> {
1717
isPrimary?: boolean;
1818
}
1919

20-
const MessageLoading: FunctionComponent<MessageLoadingProps> = ({ loadingWord, isPrimary, ...props }) => (
20+
export const MessageLoading: FunctionComponent<MessageLoadingProps> = ({ loadingWord, isPrimary, ...props }) => (
2121
<div className={css('pf-chatbot__message-loading', isPrimary && 'pf-m-primary')} {...props}>
2222
<span className="pf-chatbot__message-loading-dots">
2323
<span className="pf-v6-screen-reader">{loadingWord}</span>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './QuickResponse';

packages/module/src/Message/QuickStarts/QuickStartTile.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export interface QuickStartTileProps {
5353
isCompact?: boolean;
5454
}
5555

56-
const QuickStartTile: FC<QuickStartTileProps> = ({
56+
export const QuickStartTile: FC<QuickStartTileProps> = ({
5757
className,
5858
quickStart,
5959
onClick,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './QuickStartTile';
2+
export * from './types';

0 commit comments

Comments
 (0)