Markdown in Antd

Viewed 894

I can confirm that this has neither been asked nor been addressed anywhere. I am currently working on a website using Gatsby, Strapi and Antd for the design. I am using the the rich text editor for one of the content types where I have put all my markdown content. However, when I try to display the actual content on the webpage, the styling is completly nuked. I figured this was because the content uses normal HTML elements like <h1> and <p> instead of the antd components like <Title> or <Text>.

So I did some researches and found that Antd has a markdown.less in their source, which I figure is used to style the markdown in their documentation. I haven't found the same after scouring the source code inside the node modules folder. Does this mean that Antd does not support styling for markdown or am I missing something here?

Btw I am using the react-markdown library to display the all the markdown. I have also posted all the relevant code below.

template.tsx

const ProductTemplate: React.FC<Props> = ({ data }: Props) => {
  const {
    ...
  } = data

  const {
    product: { strapiId: selectedKeyProp },
  } = data
  return (
    <Layout>
      <AntLayout>
        <ProductSidebar
          selectedKeyProp={selectedKeyProp}
          productsInfo={productsInfo}
        >
          <ProductInfo product={product} />
        </ProductSidebar>
      </AntLayout>
    </Layout>
  )
}

export const query = graphql`
  ...
`

export default ProductTemplate

page-component.tsx

const ComponentName = ({ data }) => {
  const {
    ...
  } = data

  console.log(data)
  return (
    <Layout>
      <AntLayout>
        <ProductSidebar productsInfo={productsInfo}>
          <div style={{ display: "unset", padding: "15px 35px" }}>
            <ReactMarkdown className="markdown" children={content} />
          </div>
        </ProductSidebar>
      </AntLayout>
    </Layout>
  )
}

export const query = graphql`
  ...
`

export default ComponentName

There problem can be pointed out here I guess. The <ReactMarkdown> receives the markdown content in the children props. But once the content is displayed to the page, the styling, as I mentioned above, is nuked out.

2 Answers

I raised this issue on github here. According to the devs, there is currently no markdown support for antd. As I thought, the markdown.less file linked above was just for the markdown in their documentation. One way to get around this solution is to include the tags exactly as specified by antd component elements. For example, instead of a # or <h1> for a header, we can use <h1 class="antd typography">, though this definitely is painful and prone to error. This other solution would be to use MDX, which support jsx inside markdown.

About a month late, but I just ran into this: I needed a way to change the styling of html generated by the react-markdown React component. I am using react-markdown in a NextJS app, and using Antd as my component library. I am additionally using react-syntax-highlighter and react-syntax-highlighter-prismjs for handling lighting codeblocks

While there is no support in Antd for markdown, there is support for custom components in react-markdown! react-markdown allows you to override the rendering engine and replace the individual components with your own, so I went through and replaced a bunch of them with Antd components:

Fair warning: This was my first pass to make sure this worked, it doesn't for instance handle checkboxes inside list item inputs.

import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import {coy} from "react-syntax-highlighter/dist/cjs/styles/prism/prism";
import gfm from 'remark-gfm';

import { Typography } from 'antd';
const { Title, Text } = Typography;
import { List } from 'antd';

const mymarkdowndata = '
# A heading
Some text
## A second heading
 * List!
 * Has
 * Many
 * Items!
'
const renderers = {
    heading: function Heading(props) {
        return <Title level={props.level}>{props.children}</Title>;
    },
    list: function MakeList(props) {
        return <List bordered>{props.children}</List>
    },  
    listItem: function MakeListItem(props) {
        return <List.Item>{props.children}</List.Item>
    },
    inlineCode: function makeInlineCode(props) {
        return  <Text code>{props.children}</Text>
    },
    code: function makeCodeBlock(props) {
        return <SyntaxHighlighter language={props.language} style={coy}>{props.value}</SyntaxHighlighter>
    },
    blockquote: function makeBlockQuote(props) {
        return <Text type="secondary">{props.children}</Text>
    }
};

Then inside your component rendering function:

render() {
    return <ReactMarkdown renderers={renderers} plugins={[gfm]} children={mymarkdowndata} />
}
Related