Autogenerate ids for headings in markdown content

Signed-off-by: John Philip <johnphilip283@gmail.com>
This commit is contained in:
John Philip
2022-08-17 21:19:11 -04:00
parent b8136f852b
commit b29c44d895
3 changed files with 54 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': minor
---
Adds code to autogenerate ids for headers parsed through the MarkdownContent component.
@@ -100,4 +100,34 @@ describe('<MarkdownContent />', () => {
'https://example.com/blog/assets/6/header.png',
);
});
it('render MarkdownContent component with headings given proper ids', async () => {
const rendered = await renderWithEffects(
wrapInTestApp(
<MarkdownContent
content={
'# Lorem ipsum\n' +
'## bing bong\n' +
'### The FitnessGram Pacer Test is a multistage aerobic capacity test'
}
/>,
),
);
expect(rendered.getByText('Lorem ipsum').getAttribute('id')).toEqual(
'lorem-ipsum',
);
expect(rendered.getByText('bing bong').getAttribute('id')).toEqual(
'bing-bong',
);
expect(
rendered
.getByText(
'The FitnessGram Pacer Test is a multistage aerobic capacity test',
)
.getAttribute('id'),
).toEqual(
'the-fitnessgram-pacer-test-is-a-multistage-aerobic-capacity-test',
);
});
});
@@ -73,6 +73,19 @@ type Props = {
className?: string;
};
const flatten = (text, child) => {
return typeof child === 'string'
? text + child
: React.Children.toArray(child.props.children).reduce(flatten, text);
};
const headingRenderer = ({ level, children }) => {
const childrenArray = React.Children.toArray(children);
const text = childrenArray.reduce(flatten, '');
const slug = text.toLocaleLowerCase('en-US').replace(/\W/g, '-');
return React.createElement(`h${level}`, { id: slug }, children);
};
const components: Options['components'] = {
code: ({ inline, className, children, ...props }) => {
const text = String(children).replace(/\n+$/, '');
@@ -85,6 +98,12 @@ const components: Options['components'] = {
</code>
);
},
h1: headingRenderer,
h2: headingRenderer,
h3: headingRenderer,
h4: headingRenderer,
h5: headingRenderer,
h6: headingRenderer,
};
/**