Skip to content

Commit 435f26b

Browse files
committed
Added example and updated styling
1 parent 5037d31 commit 435f26b

8 files changed

Lines changed: 345 additions & 19 deletions

File tree

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
import { useState, FunctionComponent, MouseEvent as ReactMouseEvent } from 'react';
2+
import Message from '@patternfly/chatbot/dist/dynamic/Message';
3+
import patternflyAvatar from './patternfly_avatar.jpg';
4+
import { CopyIcon, WrenchIcon } from '@patternfly/react-icons';
5+
import {
6+
Button,
7+
DescriptionList,
8+
DescriptionListDescription,
9+
DescriptionListGroup,
10+
DescriptionListTerm,
11+
ExpandableSection,
12+
ExpandableSectionVariant,
13+
Flex,
14+
FlexItem,
15+
Label
16+
} from '@patternfly/react-core';
17+
export const MessageWithToolResponseExample = () => {
18+
const [isExpanded, setIsExpanded] = useState(false);
19+
const onToggle = (_event: ReactMouseEvent, isExpanded: boolean) => {
20+
setIsExpanded(isExpanded);
21+
};
22+
const comprehensiveMarkdownBody = `Here's a comprehensive markdown example with various formatting options:
23+
24+
# h1 Heading
25+
26+
## h2 Heading
27+
28+
### h3 Heading
29+
30+
#### h4 Heading
31+
32+
##### h5 Heading
33+
34+
###### h6 Heading
35+
36+
## Text Emphasis
37+
38+
**Bold text, formatted with double asterisks**
39+
40+
__Bold text, formatted with double underscores__
41+
42+
*Italic text, formatted with single asterisks*
43+
44+
_Italic text, formatted with single underscores_
45+
46+
~~Strikethrough~~
47+
48+
## Inline Code
49+
50+
Here is an inline code example - \`() => void\`
51+
52+
## Code Blocks
53+
54+
Here is some YAML code:
55+
56+
~~~yaml
57+
apiVersion: helm.openshift.io/v1beta1/
58+
kind: HelmChartRepository
59+
metadata:
60+
name: azure-sample-repo0oooo00ooo
61+
spec:
62+
connectionConfig:
63+
url: https://raw.githubusercontent.com/Azure-Samples/helm-charts/master/docs
64+
~~~
65+
66+
Here is some JavaScript code:
67+
68+
~~~js
69+
const MessageLoading = () => (
70+
<div className="pf-chatbot__message-loading">
71+
<span className="pf-chatbot__message-loading-dots">
72+
<span className="pf-v6-screen-reader">Loading message</span>
73+
</span>
74+
</div>
75+
);
76+
77+
export default MessageLoading;
78+
~~~
79+
80+
## Block Quotes
81+
82+
> Blockquotes can also be nested...
83+
>> ...by using additional greater-than signs (>) right next to each other...
84+
> > > ...or with spaces between each sign.
85+
86+
## Lists
87+
88+
### Ordered List
89+
90+
1. Item 1
91+
2. Item 2
92+
3. Item 3
93+
94+
### Unordered List
95+
96+
* Item 1
97+
* Item 2
98+
* Item 3
99+
100+
### More Complex List
101+
102+
You may be wondering whether you can display more complex lists with formatting. In response to your question, I will explain how to spread butter on toast.
103+
104+
1. **Using a \`toaster\`:**
105+
106+
- Place \`bread\` in a \`toaster\`
107+
- Once \`bread\` is lightly browned, remove from \`toaster\`
108+
109+
2. **Using a \`knife\`:**
110+
111+
- Acquire 1 tablespoon of room temperature \`butter\`. Use \`knife\` to spread butter on \`toast\`. Bon appétit!
112+
113+
## Links
114+
115+
A paragraph with a URL: https://reactjs.org.
116+
117+
## Tables
118+
119+
To customize your table, you can use [PatternFly TableProps](/components/table#table)
120+
121+
| Version | GA date | User role
122+
|-|-|-|
123+
| 2.5 | September 30, 2024 | Administrator |
124+
| 2.5 | June 27, 2023 | Editor |
125+
| 3.0 | April 1, 2025 | Administrator
126+
127+
## Images
128+
129+
![Multi-colored wavy lines on a black background](https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif)
130+
131+
## Footnotes
132+
133+
This is some text that has a short footnote[^1] and this is text with a longer footnote.[^bignote]
134+
135+
[^1]: This is a short footnote. To return the highlight to the original message, click the arrow.
136+
137+
[^bignote]: This is a long footnote with multiple paragraphs and formatting.
138+
139+
To break long footnotes into paragraphs, indent the text.
140+
141+
Add as many paragraphs as you like. You can include *italic text*, **bold text**, and \`code\`.
142+
143+
> You can even include blockquotes in footnotes!
144+
`;
145+
return (
146+
<Message
147+
name="Bot"
148+
role="bot"
149+
avatar={patternflyAvatar}
150+
content="This example demonstrates a tool response with a comprehensive markdown body showing all formatting options:"
151+
toolResponse={{
152+
isToggleContentMarkdown: true,
153+
toggleContent: '# Tool response: toolName',
154+
isSubheadingMarkdown: true,
155+
subheading: '> Thought for 3 seconds',
156+
body: comprehensiveMarkdownBody,
157+
isBodyMarkdown: true,
158+
cardTitle: (
159+
<Flex
160+
alignItems={{
161+
default: 'alignItemsCenter'
162+
}}
163+
justifyContent={{
164+
default: 'justifyContentSpaceBetween'
165+
}}
166+
>
167+
<FlexItem>
168+
<Flex
169+
direction={{
170+
default: 'column'
171+
}}
172+
gap={{
173+
default: 'gapXs'
174+
}}
175+
>
176+
<FlexItem
177+
grow={{
178+
default: 'grow'
179+
}}
180+
>
181+
<Flex
182+
gap={{
183+
default: 'gapXs'
184+
}}
185+
>
186+
<FlexItem>
187+
<WrenchIcon
188+
style={{
189+
color: 'var(--pf-t--global--icon--color--brand--default'
190+
}}
191+
/>
192+
</FlexItem>
193+
<FlexItem>toolName</FlexItem>
194+
</Flex>
195+
</FlexItem>
196+
<FlexItem>
197+
<Flex
198+
gap={{
199+
default: 'gapSm'
200+
}}
201+
style={{
202+
fontSize: '12px',
203+
fontWeight: '400'
204+
}}
205+
>
206+
<FlexItem>Execution time:</FlexItem>
207+
<FlexItem>0.12 seconds</FlexItem>
208+
</Flex>
209+
</FlexItem>
210+
</Flex>
211+
</FlexItem>
212+
<FlexItem>
213+
<Button
214+
variant="plain"
215+
aria-label="Copy tool response to clipboard"
216+
icon={
217+
<CopyIcon
218+
style={{
219+
color: 'var(--pf-t--global--icon--color--subtle)'
220+
}}
221+
/>
222+
}
223+
></Button>
224+
</FlexItem>
225+
</Flex>
226+
),
227+
cardBody: (
228+
<>
229+
<DescriptionList
230+
style={{
231+
'--pf-v6-c-description-list--RowGap': 'var(--pf-t--global--spacer--md)'
232+
}}
233+
aria-label="Tool response"
234+
>
235+
<DescriptionListGroup
236+
style={{
237+
'--pf-v6-c-description-list__group--RowGap': 'var(--pf-t--global--spacer--xs)'
238+
}}
239+
>
240+
<DescriptionListTerm>Parameters</DescriptionListTerm>
241+
<DescriptionListDescription>
242+
<Flex
243+
direction={{
244+
default: 'column'
245+
}}
246+
>
247+
<FlexItem>Optional description text for parameters.</FlexItem>
248+
<FlexItem>
249+
<Flex
250+
gap={{
251+
default: 'gapSm'
252+
}}
253+
>
254+
<FlexItem>
255+
<Label variant="outline" color="blue">
256+
type
257+
</Label>
258+
</FlexItem>
259+
<FlexItem>
260+
<Label variant="outline" color="blue">
261+
properties
262+
</Label>
263+
</FlexItem>
264+
<FlexItem>
265+
<Label variant="outline" color="blue">
266+
label
267+
</Label>
268+
</FlexItem>
269+
<FlexItem>
270+
<Label variant="outline" color="blue">
271+
label
272+
</Label>
273+
</FlexItem>
274+
</Flex>
275+
</FlexItem>
276+
</Flex>
277+
</DescriptionListDescription>
278+
</DescriptionListGroup>
279+
<DescriptionListGroup
280+
style={{
281+
'--pf-v6-c-description-list__group--RowGap': 'var(--pf-t--global--spacer--xs)'
282+
}}
283+
>
284+
<DescriptionListTerm>Response</DescriptionListTerm>
285+
<DescriptionListDescription>
286+
<ExpandableSection
287+
variant={ExpandableSectionVariant.truncate}
288+
toggleTextExpanded="show less of response"
289+
toggleTextCollapsed="show more of response"
290+
onToggle={onToggle}
291+
isExpanded={isExpanded}
292+
style={{
293+
'--pf-v6-c-expandable-section__content--Opacity': '1',
294+
'--pf-v6-c-expandable-section__content--PaddingInlineStart': 0,
295+
'--pf-v6-c-expandable-section__content--TranslateY': 0,
296+
'--pf-v6-c-expandable-section--m-expand-top__content--TranslateY': 0
297+
}}
298+
>
299+
Descriptive text about the tool response, including completion status, details on the data that was
300+
processed, or anything else relevant to the use case.
301+
</ExpandableSection>
302+
</DescriptionListDescription>
303+
</DescriptionListGroup>
304+
</DescriptionList>
305+
</>
306+
)
307+
}}
308+
/>
309+
);
310+
};

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,12 @@ If you are using [model context protocol (MCP)](https://www.redhat.com/en/blog/m
203203

204204
```
205205

206+
### Messages with Markdown in tool response
207+
208+
```ts file="./MessageWithMarkdownToolResponse.tsx"
209+
210+
```
211+
206212
### Messages with deep thinking
207213

208214
You can share details about the "thought process" behind an LLM's response, also known as deep thinking. To display a customizable, expandable card with these details, pass `deepThinking` to `<Message>` and provide a subheading (optional) and content body.

packages/module/src/MarkdownContent/MarkdownContent.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ export const MarkdownContent: FunctionComponent<MarkdownContentProps> = ({
136136
{...codeBlockProps}
137137
isPrimary={isPrimary}
138138
shouldRetainStyles={shouldRetainStyles}
139-
// className={css('pf-m-markdown', codeBlockProps?.className)}
140139
>
141140
{children}
142141
</CodeBlockMessage>

packages/module/src/Message/CodeBlockMessage/CodeBlockMessage.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
}
7777
}
7878

79-
.pf-m-markdown > .pf-v6-c-code-block__code {
79+
&.pf-m-markdown .pf-v6-c-code-block__code {
8080
font-size: inherit;
8181
}
8282
}

packages/module/src/Message/CodeBlockMessage/CodeBlockMessage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ const CodeBlockMessage = ({
142142
);
143143

144144
return (
145-
<div className={css('pf-chatbot__message-code-block')} ref={codeBlockRef}>
145+
<div className={css('pf-chatbot__message-code-block', shouldRetainStyles && 'pf-m-markdown')} ref={codeBlockRef}>
146146
<CodeBlock actions={actions}>
147-
<CodeBlockCode className={css(shouldRetainStyles && 'pf-m-markdown')}>
147+
<CodeBlockCode className={css()}>
148148
<>
149149
{isExpandable ? (
150150
<ExpandableSection

packages/module/src/Message/TextMessage/TextMessage.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@
5353
background-color: var(--pf-t--global--background--color--secondary--default);
5454
}
5555
}
56+
57+
&.pf-m-markdown {
58+
display: block;
59+
}
60+
&.pf-m-markdown > [class^='pf-v6-c-content'] {
61+
font-size: inherit;
62+
}
63+
64+
// &.pf-m-markdown + & {
65+
// margin-top: 10px;
66+
// }
5667
}
5768

5869
// ============================================================================

packages/module/src/Message/TextMessage/TextMessage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ const TextMessage = ({
4242
shouldRetainStyles,
4343
...props
4444
}: Omit<ContentProps, 'ref'> & ExtraProps & TextMessageProps) => (
45-
<span className={css('pf-chatbot__message-text', isPrimary && 'pf-m-primary')}>
46-
<Content component={component} {...props} className={css(shouldRetainStyles && 'pf-m-markdown', props?.className)}>
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)}>
4747
{children}
4848
</Content>
4949
</span>

0 commit comments

Comments
 (0)