Skip to content

Commit 8110566

Browse files
committed
Added logic to retain styles
1 parent 8ec3d61 commit 8110566

14 files changed

Lines changed: 222 additions & 45 deletions

File tree

packages/module/src/MarkdownContent/MarkdownContent.tsx

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import LinkMessage from '../Message/LinkMessage/LinkMessage';
2929
import { rehypeMoveImagesOutOfParagraphs } from '../Message/Plugins/rehypeMoveImagesOutOfParagraphs';
3030
import SuperscriptMessage from '../Message/SuperscriptMessage/SuperscriptMessage';
3131
import { ButtonProps } from '@patternfly/react-core';
32+
import { css } from '@patternfly/react-styles';
3233

3334
export interface MarkdownContentProps {
3435
/** The markdown content to render */
@@ -57,6 +58,8 @@ export interface MarkdownContentProps {
5758
isPrimary?: boolean;
5859
/** Custom component to render when markdown is disabled */
5960
textComponent?: ReactNode;
61+
/** Flag indicating whether content should retain various styles of its context (typically font-size and text color). */
62+
shouldRetainStyles?: boolean;
6063
}
6164

6265
export const MarkdownContent: FunctionComponent<MarkdownContentProps> = ({
@@ -72,7 +75,8 @@ export const MarkdownContent: FunctionComponent<MarkdownContentProps> = ({
7275
remarkGfmProps,
7376
hasNoImages = false,
7477
isPrimary,
75-
textComponent
78+
textComponent,
79+
shouldRetainStyles
7680
}: MarkdownContentProps) => {
7781
let rehypePlugins: PluggableList = [rehypeUnwrapImages, rehypeMoveImagesOutOfParagraphs, rehypeHighlight];
7882
if (openLinkInNewTab) {
@@ -104,74 +108,96 @@ export const MarkdownContent: FunctionComponent<MarkdownContentProps> = ({
104108
section: (props) => {
105109
// eslint-disable-next-line @typescript-eslint/no-unused-vars
106110
const { node, ...rest } = props;
107-
return <section {...rest} className={`pf-chatbot__message-text ${rest?.className}`} />;
111+
return (
112+
<section
113+
{...rest}
114+
className={css('pf-chatbot__message-text', shouldRetainStyles && 'pf-m-markdown', rest?.className)}
115+
/>
116+
);
108117
},
109118
p: (props) => {
110119
// eslint-disable-next-line @typescript-eslint/no-unused-vars
111120
const { node, ...rest } = props;
112-
return <TextMessage component={ContentVariants.p} {...rest} isPrimary={isPrimary} />;
121+
return (
122+
<TextMessage
123+
shouldRetainStyles={shouldRetainStyles}
124+
component={ContentVariants.p}
125+
{...rest}
126+
isPrimary={isPrimary}
127+
/>
128+
);
113129
},
114130
code: ({ children, ...props }) => {
115131
// eslint-disable-next-line @typescript-eslint/no-unused-vars
116132
const { node, ...codeProps } = props;
117133
return (
118-
<CodeBlockMessage {...codeProps} {...codeBlockProps} isPrimary={isPrimary}>
134+
<CodeBlockMessage
135+
{...codeProps}
136+
{...codeBlockProps}
137+
isPrimary={isPrimary}
138+
shouldRetainStyles={shouldRetainStyles}
139+
// className={css('pf-m-markdown', codeBlockProps?.className)}
140+
>
119141
{children}
120142
</CodeBlockMessage>
121143
);
122144
},
123145
h1: (props) => {
124146
// eslint-disable-next-line @typescript-eslint/no-unused-vars
125147
const { node, ...rest } = props;
126-
return <TextMessage component={ContentVariants.h1} {...rest} />;
148+
return <TextMessage shouldRetainStyles={shouldRetainStyles} component={ContentVariants.h1} {...rest} />;
127149
},
128150
h2: (props) => {
129151
// eslint-disable-next-line @typescript-eslint/no-unused-vars
130152
const { node, ...rest } = props;
131-
return <TextMessage component={ContentVariants.h2} {...rest} />;
153+
return <TextMessage shouldRetainStyles={shouldRetainStyles} component={ContentVariants.h2} {...rest} />;
132154
},
133155
h3: (props) => {
134156
// eslint-disable-next-line @typescript-eslint/no-unused-vars
135157
const { node, ...rest } = props;
136-
return <TextMessage component={ContentVariants.h3} {...rest} />;
158+
return <TextMessage shouldRetainStyles={shouldRetainStyles} component={ContentVariants.h3} {...rest} />;
137159
},
138160
h4: (props) => {
139161
// eslint-disable-next-line @typescript-eslint/no-unused-vars
140162
const { node, ...rest } = props;
141-
return <TextMessage component={ContentVariants.h4} {...rest} />;
163+
return <TextMessage shouldRetainStyles={shouldRetainStyles} component={ContentVariants.h4} {...rest} />;
142164
},
143165
h5: (props) => {
144166
// eslint-disable-next-line @typescript-eslint/no-unused-vars
145167
const { node, ...rest } = props;
146-
return <TextMessage component={ContentVariants.h5} {...rest} />;
168+
return <TextMessage shouldRetainStyles={shouldRetainStyles} component={ContentVariants.h5} {...rest} />;
147169
},
148170
h6: (props) => {
149171
// eslint-disable-next-line @typescript-eslint/no-unused-vars
150172
const { node, ...rest } = props;
151-
return <TextMessage component={ContentVariants.h6} {...rest} />;
173+
return <TextMessage shouldRetainStyles={shouldRetainStyles} component={ContentVariants.h6} {...rest} />;
152174
},
153175
blockquote: (props) => {
154176
// eslint-disable-next-line @typescript-eslint/no-unused-vars
155177
const { node, ...rest } = props;
156-
return <TextMessage component={ContentVariants.blockquote} {...rest} />;
178+
return (
179+
<TextMessage shouldRetainStyles={shouldRetainStyles} component={ContentVariants.blockquote} {...rest} />
180+
);
157181
},
158182
ul: (props) => {
159183
// eslint-disable-next-line @typescript-eslint/no-unused-vars
160184
const { node, ...rest } = props;
161-
return <UnorderedListMessage {...rest} />;
185+
return <UnorderedListMessage shouldRetainStyles={shouldRetainStyles} {...rest} />;
162186
},
163187
ol: (props) => {
164188
// eslint-disable-next-line @typescript-eslint/no-unused-vars
165189
const { node, ...rest } = props;
166-
return <OrderedListMessage {...rest} />;
190+
return <OrderedListMessage shouldRetainStyles={shouldRetainStyles} {...rest} />;
167191
},
168192
li: (props) => {
169193
// eslint-disable-next-line @typescript-eslint/no-unused-vars
170194
const { node, ...rest } = props;
171195
return <ListItemMessage {...rest} />;
172196
},
173197
// table requires node attribute for calculating headers for mobile breakpoint
174-
table: (props) => <TableMessage {...props} {...tableProps} isPrimary={isPrimary} />,
198+
table: (props) => (
199+
<TableMessage shouldRetainStyles={shouldRetainStyles} {...props} {...tableProps} isPrimary={isPrimary} />
200+
),
175201
tbody: (props) => {
176202
// eslint-disable-next-line @typescript-eslint/no-unused-vars
177203
const { node, ...rest } = props;
@@ -210,7 +236,7 @@ export const MarkdownContent: FunctionComponent<MarkdownContentProps> = ({
210236
return (
211237
// some a types conflict with ButtonProps, but it's ok because we are using an a tag
212238
// there are too many to handle manually
213-
<LinkMessage {...(rest as any)} {...linkProps}>
239+
<LinkMessage shouldRetainStyles={shouldRetainStyles} {...(rest as any)} {...linkProps}>
214240
{props.children}
215241
</LinkMessage>
216242
);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@
7575
overflow: hidden !important;
7676
}
7777
}
78+
79+
.pf-m-markdown > .pf-v6-c-code-block__code {
80+
font-size: inherit;
81+
}
7882
}
7983

8084
.pf-chatbot__message-inline-code {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919

2020
import { CheckIcon } from '@patternfly/react-icons/dist/esm/icons/check-icon';
2121
import { CopyIcon } from '@patternfly/react-icons/dist/esm/icons/copy-icon';
22+
import { css } from '@patternfly/react-styles';
2223

2324
export interface CodeBlockMessageProps {
2425
/** Content rendered in code block */
@@ -41,6 +42,8 @@ export interface CodeBlockMessageProps {
4142
customActions?: React.ReactNode;
4243
/** Sets background colors to be appropriate on primary chatbot background */
4344
isPrimary?: boolean;
45+
/** Flag indicating that the content should retain message styles when using Markdown. */
46+
shouldRetainStyles?: boolean;
4447
}
4548

4649
const DEFAULT_EXPANDED_TEXT = 'Show less';
@@ -57,6 +60,7 @@ const CodeBlockMessage = ({
5760
collapsedText = DEFAULT_COLLAPSED_TEXT,
5861
customActions,
5962
isPrimary,
63+
shouldRetainStyles,
6064
...props
6165
}: CodeBlockMessageProps) => {
6266
const [copied, setCopied] = useState(false);
@@ -138,9 +142,9 @@ const CodeBlockMessage = ({
138142
);
139143

140144
return (
141-
<div className="pf-chatbot__message-code-block" ref={codeBlockRef}>
145+
<div className={css('pf-chatbot__message-code-block')} ref={codeBlockRef}>
142146
<CodeBlock actions={actions}>
143-
<CodeBlockCode>
147+
<CodeBlockCode className={css(shouldRetainStyles && 'pf-m-markdown')}>
144148
<>
145149
{isExpandable ? (
146150
<ExpandableSection
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.pf-v6-c-button.pf-m-link.pf-m-inline {
2+
&.pf-m-markdown {
3+
font-size: inherit;
4+
}
5+
}

packages/module/src/Message/LinkMessage/LinkMessage.tsx

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,21 @@
55
import { Button, ButtonProps } from '@patternfly/react-core';
66
import { ExternalLinkSquareAltIcon } from '@patternfly/react-icons';
77
import { ExtraProps } from 'react-markdown';
8+
import { css } from '@patternfly/react-styles';
89

9-
const LinkMessage = ({ children, target, href, id, ...props }: ButtonProps & ExtraProps) => {
10+
export interface LinkMessageProps {
11+
/** Flag indicating that the content should retain message styles when using Markdown. */
12+
shouldRetainStyles?: boolean;
13+
}
14+
15+
const LinkMessage = ({
16+
children,
17+
target,
18+
href,
19+
id,
20+
shouldRetainStyles,
21+
...props
22+
}: LinkMessageProps & ButtonProps & ExtraProps) => {
1023
if (target === '_blank') {
1124
return (
1225
<Button
@@ -20,6 +33,7 @@ const LinkMessage = ({ children, target, href, id, ...props }: ButtonProps & Ext
2033
// need to explicitly call this out or id doesn't seem to get passed - required for footnotes
2134
id={id}
2235
{...props}
36+
className={css(shouldRetainStyles && 'pf-m-markdown', props?.className)}
2337
>
2438
{children}
2539
</Button>
@@ -28,7 +42,15 @@ const LinkMessage = ({ children, target, href, id, ...props }: ButtonProps & Ext
2842

2943
return (
3044
// need to explicitly call this out or id doesn't seem to get passed - required for footnotes
31-
<Button isInline component="a" href={href} variant="link" id={id} {...props}>
45+
<Button
46+
isInline
47+
component="a"
48+
href={href}
49+
variant="link"
50+
id={id}
51+
{...props}
52+
className={css(shouldRetainStyles && 'pf-m-markdown', props?.className)}
53+
>
3254
{children}
3355
</Button>
3456
);

packages/module/src/Message/ListMessage/ListMessage.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@
1313
li {
1414
font-size: var(--pf-t--global--font--size--md);
1515
}
16+
17+
&.pf-m-markdown {
18+
.pf-v6-c-list,
19+
ul,
20+
li {
21+
font-size: inherit;
22+
}
23+
}
1624
}
1725

1826
.pf-chatbot__message--user {

packages/module/src/Message/ListMessage/OrderedListMessage.tsx

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,29 @@
44

55
import { ExtraProps } from 'react-markdown';
66
import { List, ListComponent, OrderType } from '@patternfly/react-core';
7+
import { css } from '@patternfly/react-styles';
78

8-
const OrderedListMessage = ({ children, start }: JSX.IntrinsicElements['ol'] & ExtraProps) => (
9-
<div className="pf-chatbot__message-ordered-list">
10-
<List component={ListComponent.ol} type={OrderType.number} start={start}>
11-
{children}
12-
</List>
13-
</div>
14-
);
9+
export interface OrderedListMessageProps {
10+
/** The ordered list content */
11+
children?: React.ReactNode;
12+
/** The number to start the ordered list at. */
13+
start?: number;
14+
/** Flag indicating that the content should retain message styles when using Markdown. */
15+
shouldRetainStyles?: boolean;
16+
}
17+
18+
const OrderedListMessage = ({
19+
children,
20+
start,
21+
shouldRetainStyles
22+
}: OrderedListMessageProps & JSX.IntrinsicElements['ol'] & ExtraProps) => {
23+
return (
24+
<div className={css('pf-chatbot__message-ordered-list', shouldRetainStyles && 'pf-m-markdown')}>
25+
<List component={ListComponent.ol} type={OrderType.number} start={start}>
26+
{children}
27+
</List>
28+
</div>
29+
);
30+
};
1531

1632
export default OrderedListMessage;

packages/module/src/Message/ListMessage/UnorderedListMessage.tsx

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

55
import { ExtraProps } from 'react-markdown';
66
import { List } from '@patternfly/react-core';
7+
import { css } from '@patternfly/react-styles';
8+
export interface UnrderedListMessageProps {
9+
/** The ordered list content */
10+
children?: React.ReactNode;
11+
/** Flag indicating that the content should retain message styles when using Markdown. */
12+
shouldRetainStyles?: boolean;
13+
}
714

8-
const UnorderedListMessage = ({ children }: JSX.IntrinsicElements['ul'] & ExtraProps) => (
9-
<div className="pf-chatbot__message-unordered-list">
10-
<List>{children}</List>
11-
</div>
12-
);
15+
const UnorderedListMessage = ({
16+
children,
17+
shouldRetainStyles
18+
}: UnrderedListMessageProps & JSX.IntrinsicElements['ul'] & ExtraProps) => {
19+
return (
20+
<div className={css('pf-chatbot__message-unordered-list', shouldRetainStyles && 'pf-m-markdown')}>
21+
<List>{children}</List>
22+
</div>
23+
);
24+
};
1325

1426
export default UnorderedListMessage;

packages/module/src/Message/TableMessage/TableMessage.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,15 @@
2424
.pf-v6-c-table__tr:last-of-type {
2525
border-block-end: 0;
2626
}
27+
28+
&.pf-m-markdown {
29+
table,
30+
tbody,
31+
td,
32+
thead,
33+
th,
34+
tr {
35+
font-size: inherit;
36+
}
37+
}
2738
}

packages/module/src/Message/TableMessage/TableMessage.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import { Children, cloneElement } from 'react';
66
import { ExtraProps } from 'react-markdown';
77
import { Table, TableProps } from '@patternfly/react-table';
8+
import { css } from '@patternfly/react-styles';
89

910
interface Properties {
1011
line: number;
@@ -20,10 +21,20 @@ export interface TableNode {
2021
}
2122

2223
export interface TableMessageProps {
24+
/** Content of the table */
25+
children?: React.ReactNode;
26+
/** Flag indicating whether primary styles should be applied. */
2327
isPrimary?: boolean;
28+
/** Flag indicating that the content should retain message styles when using Markdown. */
29+
shouldRetainStyles?: boolean;
2430
}
2531

26-
const TableMessage = ({ children, isPrimary, ...props }: Omit<TableProps, 'ref'> & ExtraProps & TableMessageProps) => {
32+
const TableMessage = ({
33+
children,
34+
isPrimary,
35+
shouldRetainStyles,
36+
...props
37+
}: Omit<TableProps, 'ref'> & ExtraProps & TableMessageProps) => {
2738
const { className, ...rest } = props;
2839

2940
// This allows us to parse the nested data we get back from the 3rd party Markdown parser
@@ -76,7 +87,12 @@ const TableMessage = ({ children, isPrimary, ...props }: Omit<TableProps, 'ref'>
7687
<Table
7788
aria-label={props['aria-label']}
7889
gridBreakPoint="grid"
79-
className={`pf-chatbot__message-table ${isPrimary ? 'pf-m-primary' : ''} ${className ? className : ''}`}
90+
className={css(
91+
'pf-chatbot__message-table',
92+
isPrimary && 'pf-m-primary',
93+
shouldRetainStyles && 'pf-m-markdown',
94+
className
95+
)}
8096
{...rest}
8197
>
8298
{modifyChildren(children)}

0 commit comments

Comments
 (0)