Material-ui: Typography Markdown support?

Created on 26 Jul 2018  路  11Comments  路  Source: mui-org/material-ui

Context


  • So I was looking into various implementations of the Typography component.
  • And I saw that it's a bit troublesome to manually add many Typography components with props you want to put in, such as variant prop.
  • So I'm suggesting: why not put enable markdown prop (and some supplementary props) on Typography component and let it render the markdown with all kinds of headings and variants?

  • [x] This is a v1.x issue.
  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior


Currently, you've gotta do something like:

<Typography variant="headline" gutterBottom color = "primary" align = "center">
        Explanation of the problem
</Typography>
<Typography variant="subheading" gutterBottom color = "primary">
        So what Im tyring to explain is
</Typography>
<Typography variant="body1" gutterBottom color = "primary">
        The detail, right. Youve gotta write repeated pattern of codes. 
</Typography>

If you are writing generic texts.

Suggestion

Instead of writing Typography components all over, can't we do something like:

const content = `# Explanation of the problem
## So what I'm trying to explain is
The detail, right. You've gotta write repeated pattern of codes.`

<Typography markdown={content} option ={{
              all: {
                gutterBottom: true,
                color: 'primary'
              },
              h1: { // this h1 could be something like 'headline' as well, depends on naming.
                align: 'center'
              }
            }} />
  • Then, it would the render the same thing as the example in the Current Behavior section.
  • What we can do right now with Typography is a real pain if you are trying to write many texts with various props and heading types.
  • In contrast, markdown makes it easy to keep and see what you are writing as well, and doing so also separates the content from the props, which makes it easy to digest your codes when you are reading them.

Thanks!

Typography question

Most helpful comment

@benshanahan1 We have added a Markdown demo in the repository. You can find the source:
https://github.com/mui-org/material-ui/blob/master/docs/src/pages/getting-started/templates/blog/Markdown.js
It's using markdown-to-jsx over react-markdown as it's faster and lighter.

Alternatively, if you fancy faster performance, the markdown component of the documentation: https://github.com/mui-org/material-ui/blob/master/docs/src/modules/components/MarkdownElement.js.

All 11 comments

@9oelM You could perhaps take advantage of @material-ui/docs/MarkDownElement, but it isn't documented, so you'd have to dig into the code to understand how to use it & override the styles.

Alternatively there are existing React components such as https://github.com/rexxars/react-markdown

Also, a better pattern is probably to do it the other way around. At least, it's what we have been doing on the project I'm working on. We have a markdown parser that uses the right typography variant based on the context automatically.

For instance:

import React from 'react'
import ReactMarkdown from 'react-markdown'
import { withStyles } from '@material-ui/core/styles'
import Typography from '@material-ui/core/Typography'

const styles = theme => ({
  listItem: {
    marginTop: theme.spacing.unit,
  },
})

const renderers = {
  /* eslint-disable-next-line react/prop-types */
  heading: ({ level, ...props }) => {
    let variant

    switch (level) {
      case 1:
        variant = 'display1'
        break
      case 2:
        variant = 'title'
        break
      case 3:
        variant = 'subheading'
        break
      default:
        variant = 'body1'
        break
    }

    return <Typography {...props} gutterBottom variant={variant} />
  },
  html: () => null,
  listItem: withStyles(styles)(({ classes, tight, ...props }) => (
    <li className={classes.listItem}>
      <Typography component="span" {...props} />
    </li>
  )),
  paragraph: props => <Typography {...props} paragraph />,
}

export default function Markdown(props) {
  return <ReactMarkdown renderers={renderers} {...props} />
}

Thanks! Will take reference of your example.

Thanks, this is super helpful. Things are working as expected, however, I am getting the following warning:

Warning: Received `false` for a non-boolean attribute `ordered`.

If you want to write it to the DOM, pass a string instead: ordered="false" or ordered={value.toString()}.

If you used to conditionally omit it with ordered={condition && value}, pass ordered={condition ? value : undefined} instead.
    in span (created by Typography)
    in Typography (created by WithStyles(Typography))
    ... (rest of call stack omitted)

Any thoughts? Is this a problem with the Typography component itself?

@benshanahan1 We have added a Markdown demo in the repository. You can find the source:
https://github.com/mui-org/material-ui/blob/master/docs/src/pages/getting-started/templates/blog/Markdown.js
It's using markdown-to-jsx over react-markdown as it's faster and lighter.

Alternatively, if you fancy faster performance, the markdown component of the documentation: https://github.com/mui-org/material-ui/blob/master/docs/src/modules/components/MarkdownElement.js.

I'll check it out, thank you!

@oliviertassinari Hi, regarding overriding default nodes to Typography, can your demo also be implemented using react-markdown?

react-markdown was really slow, and doesn't seem to have changed. I would avoid it.

For those sticking with react-markdown, you'll need to use the renderers property to override elements. Example using the material-ui Typography component for paragraphs:

<ReactMarkdown
  source={text}
  renderers={{ paragraph: Typography }}
/>

or if you need to apply additional props to Typography:

<ReactMarkdown
  source={text}
  renderers={{
    paragraph: ({ children }) => (
      <Typography>
        {children}
      </Typography>
    ),
  }}
/>

The full list of overridable renderers is available in the Node types section of the documentation.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ryanflorence picture ryanflorence  路  3Comments

mb-copart picture mb-copart  路  3Comments

TimoRuetten picture TimoRuetten  路  3Comments

revskill10 picture revskill10  路  3Comments

pola88 picture pola88  路  3Comments