Skip to content

Commit 912cd12

Browse files
authored
Merge pull request #585 from rebeccaalpert/rehype-show-more
chore(docs): Make Message expandable code links unique
2 parents 78c7a18 + ccf6895 commit 912cd12

File tree

8 files changed

+64
-3
lines changed

8 files changed

+64
-3
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
SelectList,
1111
SelectOption
1212
} from '@patternfly/react-core';
13+
import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/esm/Message/Plugins/rehypeCodeBlockToggle';
1314

1415
export const BotMessageExample: FunctionComponent = () => {
1516
const [variant, setVariant] = useState<string>('Code');
@@ -260,6 +261,10 @@ _Italic text, formatted with single underscores_
260261
}
261262
error={variant === 'Error' ? error : undefined}
262263
codeBlockProps={{ isExpandable, expandableSectionProps: { truncateMaxLines: isExpandable ? 1 : undefined } }}
264+
// In this example, custom plugin will override any custom expandedText or collapsedText attributes provided
265+
// The purpose of this plugin is to provide unique link names for the code blocks
266+
// Because they are in the same message, this requires a custom plugin to parse the syntax tree
267+
additionalRehypePlugins={[rehypeCodeBlockToggle]}
263268
/>
264269
</>
265270
);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ sortValue: 3
3131
---
3232

3333
import Message from '@patternfly/chatbot/dist/dynamic/Message';
34+
import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/esm/Message/Plugins/rehypeCodeBlockToggle';
3435
import SourcesCard from '@patternfly/chatbot/dist/dynamic/SourcesCard';
3536
import { RobotIcon } from '@patternfly/react-icons/dist/esm/icons/robot-icon';
3637
import InfoCircleIcon from '@patternfly/react-icons/dist/esm/icons/info-circle-icon';

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
SelectList,
1010
SelectOption
1111
} from '@patternfly/react-core';
12+
import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/esm/Message/Plugins/rehypeCodeBlockToggle';
1213

1314
export const UserMessageExample: FunctionComponent = () => {
1415
const [variant, setVariant] = useState<string>('Code');
@@ -250,6 +251,10 @@ _Italic text, formatted with single underscores_
250251
onEditUpdate={() => setIsEditable(false)}
251252
onEditCancel={() => setIsEditable(false)}
252253
codeBlockProps={{ isExpandable, expandableSectionProps: { truncateMaxLines: isExpandable ? 1 : undefined } }}
254+
// In this example, custom plugin will override any custom expandedText or collapsedText attributes provided
255+
// The purpose of this plugin is to provide unique link names for the code blocks
256+
// Because they are in the same message, this requires a custom plugin to parse the syntax tree
257+
additionalRehypePlugins={[rehypeCodeBlockToggle]}
253258
/>
254259
</>
255260
);

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

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,18 @@ export interface CodeBlockMessageProps {
4141
collapsedText?: string;
4242
}
4343

44+
const DEFAULT_EXPANDED_TEXT = 'Show less';
45+
const DEFAULT_COLLAPSED_TEXT = 'Show more';
46+
4447
const CodeBlockMessage = ({
4548
children,
4649
className,
4750
'aria-label': ariaLabel,
4851
isExpandable = false,
4952
expandableSectionProps,
5053
expandableSectionToggleProps,
51-
expandedText = 'Show less',
52-
collapsedText = 'Show more',
54+
expandedText = DEFAULT_EXPANDED_TEXT,
55+
collapsedText = DEFAULT_COLLAPSED_TEXT,
5356
...props
5457
}: CodeBlockMessageProps) => {
5558
const [copied, setCopied] = useState(false);
@@ -63,6 +66,24 @@ const CodeBlockMessage = ({
6366

6467
const language = /language-(\w+)/.exec(className || '')?.[1];
6568

69+
// Get custom toggle text from data attributes if available - for use with rehype plugins
70+
const customExpandedText = props['data-expanded-text'];
71+
const customCollapsedText = props['data-collapsed-text'];
72+
73+
const finalExpandedText = customExpandedText || expandedText;
74+
const finalCollapsedText = customCollapsedText || collapsedText;
75+
76+
if (
77+
(customExpandedText && expandedText !== DEFAULT_EXPANDED_TEXT) ||
78+
(customCollapsedText && collapsedText !== DEFAULT_COLLAPSED_TEXT)
79+
) {
80+
// eslint-disable-next-line no-console
81+
console.error(
82+
'Message:',
83+
'Custom rehype plugins that rely on data-expanded-text or data-collapsed-text will override expandedText and collapsedText props if both are passed in.'
84+
);
85+
}
86+
6687
const onToggle = (isExpanded) => {
6788
setIsExpanded(isExpanded);
6889
};
@@ -164,7 +185,7 @@ const CodeBlockMessage = ({
164185
className="pf-chatbot__message-code-toggle"
165186
{...expandableSectionToggleProps}
166187
>
167-
{isExpanded ? expandedText : collapsedText}
188+
{isExpanded ? finalExpandedText : finalCollapsedText}
168189
</ExpandableSectionToggle>
169190
)}
170191
</CodeBlock>

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ class ExpandableSectionForSyntaxHighlighter extends Component<ExpandableSectionP
176176
contentId,
177177
toggleId,
178178
variant,
179+
// Gets rid of console error about it being on a DOM element
180+
// eslint-disable-next-line
181+
truncateMaxLines,
179182
...props
180183
} = this.props;
181184

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { rehypeCodeBlockToggle } from './rehypeCodeBlockToggle';
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { visit } from 'unist-util-visit';
2+
import { Element } from 'hast';
3+
import { Node } from 'unist';
4+
5+
// Rehype plugin to add language information to code block props
6+
// Per Eric, Ideally any toggle buttons that can be navigated to would have unique accessible names
7+
// For the purposes of our examples this should suffice, but in a real-world use case they may need to be more unique
8+
export const rehypeCodeBlockToggle = () => (tree: Node) => {
9+
visit(tree, 'element', (node: Element) => {
10+
if (node.tagName === 'code' && node.properties?.className) {
11+
const className = node.properties.className as string[];
12+
const languageMatch = className.find((cls) => cls.startsWith('language-'));
13+
14+
if (languageMatch) {
15+
const language = languageMatch.replace('language-', '').toUpperCase();
16+
17+
// Add the language and toggle text as data attributes
18+
node.properties['data-language'] = language;
19+
node.properties['data-expanded-text'] = `Show less ${language} code`;
20+
node.properties['data-collapsed-text'] = `Show more ${language} code`;
21+
}
22+
}
23+
});
24+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export { default } from './Message';
2+
export { rehypeCodeBlockToggle } from './Plugins/rehypeCodeBlockToggle';
23

34
export * from './Message';

0 commit comments

Comments
 (0)