The content
prop of the <Message>
component is passed to a <Markdown>
component (from react-markdown), which is configured to translate plain text strings into PatternFly <Content>
components and code blocks into PatternFly <CodeBlock>
components.
Messages
Bot messages
Messages from the ChatBot will be marked with an "AI" label to clearly communicate the use of AI to users. The ChatBot can display different content
types, including plain text, code, or a loading animation (via isLoading
).
By default, a date and timestamp is displayed with each message. We recommend using the timestamp
prop in real ChatBots, since it will allow you to set persistent dates and times on messages, even if the messages re-render. You can update timestamp
with a different date and time format as needed.
You can further customize the avatar by applying an additional class or passing PatternFly avatar props to the <Message>
component via avatarProps
.
Messages actions
You can add actions to a message, to allow users to interact with the message content. These actions can include:
- Feedback responses that allow users to rate a message as "good" or "bad".
- Copy and share controls that allow users to share the message content with others.
- A listen action, that will read the message content out loud.
Note: The logic for the actions is not built into the component and must be implemented by the consuming application.
Custom message actions
Beyond the standard message actions (positive, negative, copy, share, or listen), you can add custom actions to a bot message by passing an actions
object to the <Message>
component. This object can contain the following customizations: ariaLabel
, onClick
, className
, isDisabled
, tooltipContent
, tooltipProps
, and icon
.
Messages with quick responses
You can offer convenient, clickable responses to messages in the form of quick actions. Quick actions are PatternFly labels in a label group, configured to display up to 5 visible labels.
To add quick actions, pass quickResponses
to <Message>
. This can be overridden by passing additional <LabelGroup>
props to quickResponseContainerProps
, or additional <Label>
props to quickResponses
.
Messages with sources
If you are using Retrieval-Augmented Generation, you may want to display sources in a message. Passing sources
to <Message>
allows you to paginate between the sources you provide.
The API for a source requires a link at minimum, but we strongly recommend providing a more descriptive title and body description so users have enough context. The title is limited to 1 line and the body is limited to 2 lines.
User messages
Messages from users have a different background color to differentiate them from bot messages. You can also display a custom avatar that is uploaded by the user. You can further customize the avatar by applying an additional class or passing PatternFly avatar props to the <Message>
component via avatarProps
.
File attachments
Messages with attachments
When attachments are shared and displayed in the ChatBot window, users will see a selectable and dismissible message that contains file details in a label. Selecting the file label can open a preview modal, which allows users to view or make edits to the file contents.
The <PreviewAttachment>
component displays a modal with a read-only view of the attached file's contents. Selecting the "edit" button will open the <AttachmentEdit>
component, which provides an interactive environment where users can make changes to the file.
If a displayMode
is not passed to <PreviewAttachment>
or <AttachmentEdit>
, they both default to overlaying the default displayMode
of the <Chatbot>
component.
Note: This example does not actually apply any edits to the attached file. That logic depends on the implementation.
We are using react-dropzone for opening the file dialog and handling drag and drop. It does not process files or provide any way to make HTTP requests to a server. If you need this, react-dropzone suggests filepond or uppy.io.. To handle edge cases, like restricting the number or size of files, you can pass a function to the handleAttach
prop on MessageBar
or onFileDrop
prop in FileDropZone.
Attachment label
When an attachment is successfully uploaded, a label will appear in the message box. There are several label variants that cover different attachment states, including:
- Plain: Default attachment labels, which display the filename and extension.
- Closeable: Attachments that can be dismissed.
- Clickable: Attachments that can be selected, typically to open file details.
- Loading: Attachments that are still being uploaded.
Attachment preview
To allow users to preview the contents of an attachment, load a read-only view of the file contents in a new modal.
Editable attachments
To allow users to edit an attached file, load a new code editor within the ChatBot window. On this screen, you can allow users to edit a file and save changes if they'd like. Return users to the main ChatBot window once they dismiss the editor.
Failed attachment error
When an attachment upload fails, a danger alert is displayed to provide details about the reason for failure.
Props
AttachMenu
Name | Type | Default | Description |
---|---|---|---|
filteredItemsrequired | React.ReactNode | Items in menu | |
handleTextInputChangerequired | (value: string) => void | A callback for when the input value changes. | |
isOpenrequired | boolean | Flag to indicate if menu is opened. | |
onOpenChangerequired | (isOpen: boolean) => void | Callback to change the open state of the menu. Triggered by clicking outside of the menu. | |
togglerequired | DropdownToggleProps | ((toggleRef: React.RefObject<any>) => React.ReactNode) | Toggle to be rendered | |
onOpenChangeKeys | string[] | Keys that trigger onOpenChange, defaults to tab and escape. It is highly recommended to include Escape in the array, while Tab may be omitted if the menu contains non-menu items that are focusable. | |
onSelect | (event?: React.MouseEvent<Element, MouseEvent>, value?: string | number) => void | Function callback called when user selects item. | |
popperProps | ExtendedDropdownPopperProps | undefined | Additional properties to pass to the Popper |
searchInputAriaLabel | string | 'Filter menu items' | Aria label for search input |
searchInputPlaceholder | string | Placeholder for search input |
AttachmentEdit
Name | Type | Default | Description |
---|---|---|---|
coderequired | string | Text shown in code editor | |
fileNamerequired | string | Filename, including extension, of file shown in editor | |
handleModalTogglerequired | (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void | Function that opens and closes modal | |
isModalOpenrequired | boolean | Whether modal is open | |
onCancelrequired | (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void | Function that runs when cancel button is clicked | |
onSaverequired | (event: React.MouseEvent | MouseEvent | KeyboardEvent, code: string) => void | Function that runs when save button is clicked; allows consumers to use the edited code string | |
displayMode | ChatbotDisplayMode | ChatbotDisplayMode.default | Display mode for the Chatbot parent; this influences the styles applied |
title | string | 'Edit attachment' | Title of modal |
FileDetails
Name | Type | Default | Description |
---|
FileDetailsLabel
Name | Type | Default | Description |
---|
FileDropZone
Name | Type | Default | Description |
---|---|---|---|
onFileDroprequired | (event: DropEvent, data: File[]) => void | When files are dropped or uploaded this callback will be called with all accepted files | |
children | React.ReactNode | Content displayed when the drop zone is not currently in use | |
className | string | Custom classname for the outer dropzone component | |
displayMode | ChatbotDisplayMode | ChatbotDisplayMode.default | Display mode for the Chatbot parent; this influences the styles applied |
infoText | string | 'Maximum file size is 25 MB' | Informational text that shows below the title in the drop zone |
PreviewAttachment
Name | Type | Default | Description |
---|---|---|---|
coderequired | string | Text shown in code editor | |
fileNamerequired | string | Filename, including extension, of file shown in modal | |
handleModalTogglerequired | (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void | Function called when modal is toggled | |
isModalOpenrequired | boolean | Whether modal is open | |
onEditrequired | (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void | Function called when edit button is clicked | |
displayMode | ChatbotDisplayMode | ChatbotDisplayMode.default | Display mode for the Chatbot parent; this influences the styles applied |
onDismiss | (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void | undefined | Function called when dismiss button is clicked |
title | string | 'Preview attachment' | Title of modal |
Message
Name | Type | Default | Description |
---|---|---|---|
avatarrequired | string | Avatar src for the user | |
rolerequired | 'user' | 'bot' | Role of the user sending the message | |
actions | { [key: string]: ActionProps; } | Props for message actions, such as feedback (positive or negative), copy button, share, and listen | |
attachments | MessageAttachment[] | Array of attachments attached to a message | |
avatarProps | Omit<AvatarProps, 'alt'> | Any additional props applied to the avatar, for additional customization | |
botWord | string | 'AI' | Label for the English word "AI," used to tag messages with role "bot" |
codeBlockProps | { 'aria-label'?: string; className?: string; } | ||
content | string | Message content | |
hasRoundAvatar | boolean | true | Whether avatar is round |
id | string | Unique id for message | |
isLoading | boolean | Set this to true if message is being loaded | |
loadingWord | string | 'Loading message' | Label for the English "Loading message," displayed to screenreaders when loading a message |
name | string | Name of the user | |
quickResponseContainerProps | Omit<LabelGroupProps, 'ref'> | { numLabels: 5 } | Props for quick responses container |
quickResponses | QuickResponse[] | Props for quick responses | |
sources | SourcesCardProps | Sources for message | |
timestamp | string | Timestamp for the message |
ActionProps
Name | Type | Default | Description |
---|---|---|---|
ariaLabel | string | Aria-label for the button | |
className | string | Class name for the button | |
icon | React.ReactNode | Icon for custom response action | |
isDisabled | boolean | Props to control if the attach button should be disabled | |
onClick | ((event: MouseEvent | React.MouseEvent<Element, MouseEvent> | KeyboardEvent) => void) | undefined | On-click handler for the button | |
tooltipContent | string | Content shown in the tooltip | |
tooltipProps | TooltipProps | Props to control the PF Tooltip component |
SourcesCardProps
Name | Type | Default | Description |
---|---|---|---|
sourcesrequired | { title?: string; link: string; body?: React.ReactNode | string }[] | Content rendered inside the paginated card | |
className | string | Additional classes for the pagination navigation container. | |
isDisabled | boolean | Flag indicating if the pagination is disabled. | |
ofWord | string | Label for the English word "of". | |
onNextClick | (event: React.SyntheticEvent<HTMLButtonElement>, page: number) => void | Function called when user clicks to navigate to next page. | |
onPreviousClick | (event: React.SyntheticEvent<HTMLButtonElement>, page: number) => void | Function called when user clicks to navigate to previous page. | |
onSetPage | (event: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPage: number) => void | Function called when page is changed. | |
paginationAriaLabel | string | Accessible label for the pagination component. | |
sourceWord | string | Label for the English word "source" | |
sourceWordPlural | string | Plural for sourceWord | |
toNextPageAriaLabel | string | Accessible label for the button which moves to the next page. | |
toPreviousPageAriaLabel | string | Accessible label for the button which moves to the previous page. |