Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,13 @@ _Italic text, formatted with single underscores_
hasRoundAvatar={false}
/>
<Message name="Bot" role="bot" content="This is a message from a bot with no avatar." />
<Message
name="Bot"
role="bot"
avatar={patternflyAvatar}
isMetadataVisible={false}
content="This is a message from a bot with metadata not visible."
/>
<Select
id="single-select"
isOpen={isOpen}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,13 @@ _Italic text, formatted with single underscores_
avatarProps={{ isBordered: true }}
/>
<Message name="User" role="user" content="This is a user message with no avatar" />
<Message
name="User"
role="user"
content="This is a user message with metadata not visible."
avatar={userAvatar}
isMetadataVisible={false}
/>
<Message
name="User"
role="user"
Expand All @@ -345,6 +352,13 @@ _Italic text, formatted with single underscores_
avatar={userAvatar}
inputRef={messageInputRef}
/>
<Message
name="User"
role="user"
avatar={userAvatar}
alignment="end"
content="This is a user message that is aligned at the end of the message container."
/>
<Select
id="single-select"
isOpen={isOpen}
Expand Down
9 changes: 9 additions & 0 deletions packages/module/src/Message/Message.scss
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@
.footnotes {
background-color: var(--pf-t--global--background--color--tertiary--default);
}

// Right/End-aligned messages
&.pf-m-end {
flex-direction: row-reverse;

.pf-chatbot__message-contents {
align-items: flex-end;
}
}
}

// Attachments
Expand Down
21 changes: 21 additions & 0 deletions packages/module/src/Message/Message.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,17 @@ describe('Message', () => {
})
).not.toBeInTheDocument();
});

it('Does not render metadata when isMetadataVisible is false', () => {
render(
<Message isMetadataVisible={false} avatar="./img" role="bot" name="Bot" content="Hi" timestamp="2 hours ago" />
);

expect(screen.queryByText('Bot')).not.toBeInTheDocument();
expect(screen.queryByText('AI')).not.toBeInTheDocument();
expect(screen.queryByText('2 hours ago')).not.toBeInTheDocument();
});

it('should render attachments', () => {
render(<Message avatar="./img" role="user" content="Hi" attachments={[{ name: 'testAttachment' }]} />);
expect(screen.getByText('Hi')).toBeTruthy();
Expand Down Expand Up @@ -1330,4 +1341,14 @@ describe('Message', () => {
);
expect(container.querySelector('.pf-m-outline')).toBeFalsy();
});

it('Renders without pf-m-end class by default', () => {
render(<Message avatar="./img" role="user" name="User" content="" />);
expect(screen.getByRole('region')).not.toHaveClass('pf-m-end');
});

it('Renders with pf-m-end class when alignment="end"', () => {
render(<Message alignment="end" avatar="./img" role="user" name="User" content="" />);
expect(screen.getByRole('region')).toHaveClass('pf-m-end');
});
});
37 changes: 23 additions & 14 deletions packages/module/src/Message/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import ToolResponse, { ToolResponseProps } from '../ToolResponse';
import DeepThinking, { DeepThinkingProps } from '../DeepThinking';
import ToolCall, { ToolCallProps } from '../ToolCall';
import MarkdownContent from '../MarkdownContent';
import { css } from '@patternfly/react-styles';

export interface MessageAttachment {
/** Name of file attached to the message */
Expand Down Expand Up @@ -73,6 +74,10 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
id?: string;
/** Role of the user sending the message */
role: 'user' | 'bot';
/** Whether the message is aligned at the horizontal start or end of the message container. */
alignment?: 'start' | 'end';
/** Flag indicating whether message metadata (user name and timestamp) are visible. */
isMetadataVisible?: boolean;
/** Message content */
content?: string;
/** Extra Message content */
Expand Down Expand Up @@ -197,6 +202,8 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
export const MessageBase: FunctionComponent<MessageProps> = ({
children,
role,
alignment = 'start',
isMetadataVisible = true,
content,
extraContent,
name,
Expand Down Expand Up @@ -314,7 +321,7 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
return (
<section
aria-label={`Message from ${role} - ${dateString}`}
className={`pf-chatbot__message pf-chatbot__message--${role}`}
className={css(`pf-chatbot__message pf-chatbot__message--${role}`, alignment === 'end' && 'pf-m-end')}
aria-live={isLiveRegion ? 'polite' : undefined}
aria-atomic={isLiveRegion ? false : undefined}
ref={innerRef}
Expand All @@ -330,19 +337,21 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
/>
)}
<div className="pf-chatbot__message-contents">
<div className="pf-chatbot__message-meta">
{name && (
<span className="pf-chatbot__message-name">
<Truncate content={name} />
</span>
)}
{role === 'bot' && (
<Label variant="outline" isCompact>
{botWord}
</Label>
)}
<Timestamp date={date}>{timestamp}</Timestamp>
</div>
{isMetadataVisible && (
<div className="pf-chatbot__message-meta">
{name && (
<span className="pf-chatbot__message-name">
<Truncate content={name} />
</span>
)}
{role === 'bot' && (
<Label variant="outline" isCompact>
{botWord}
</Label>
)}
<Timestamp date={date}>{timestamp}</Timestamp>
</div>
)}
<div className="pf-chatbot__message-response">
{children ? (
<>{children}</>
Expand Down
Loading