Our application is build using Material-UI library (with themes). As part of this app we are parsing markdown to html (marked library).
How can you apply material-ui themes ( Typography ) to a pure html ?
Somehow
<div dangerouslySetInnerHTML={ {__html: marked(markdown code)}}/>
Should have the styles as defined by material-ui Typography
It is an HTML, CSS & JS framework to make responsive websites that are mobile-friendly and easy to create. Material UI is a highly interactive & customizable framework based on React UI and Material Design.
Material-UI is a great library and has had my back in the past years, yet now I would strongly advise against using it if your application might present performance challenges. A simple form or a standard web page shouldn't be a problem, but still, keep that in mind.
What is react-markdown? react-markdown is a React component that converts Markdown text into the corresponding HTML code. It is built on remark, which is a Markdown preprocessor. react-markdown enables you to safely render markdown because it does not rely on the dangerouslySetInnerHTML prop.
The styles for all the Typography
variants are in the theme at theme.typography.<variant>
(you can browse those entries in the default theme here: https://material-ui.com/customization/default-theme/#default-theme). You can leverage this to create styles to target the tags you want to support as shown in the example below:
import React from "react";
import { makeStyles } from "@material-ui/core";
import Typography from "@material-ui/core/Typography";
const useStyles = makeStyles((theme) => {
const tags = ["h1", "h2", "h3", "h4", "h5", "h6"];
const nestedRules = {};
tags.forEach((tag) => {
nestedRules[`& ${tag}`] = { ...theme.typography[tag] };
});
return {
root: nestedRules
};
});
export default function App() {
const classes = useStyles();
return (
<Typography
className={classes.root}
variant="body1"
dangerouslySetInnerHTML={{
__html:
"<h1>H1</h1><h2>H2</h2><h3>H3</h3><h4>H4</h4><h5>H5</h5><h6>H6</h6><p>default body1</p>"
}}
></Typography>
);
}
Related answer: material-ui makeStyles: how to style by tag name?
use regular Typography
component and pass that HTML in a similar way as it is passed in the question.
<Typography
variant="h2"
color="primary"
dangerouslySetInnerHTML={{ __html: "<p>Hi from inner HTML</p>" }}>
</Typography>
One catch is here that when dangerouslySetInnerHTML
is passed then don't pass anything as children.
Here is a working demo :
Note: Also make sure that the function marked(markdown code)
returns the HTML in string.
Use the markdown-to-jsx
npm package. here is the example from the material ui templates.
You basically have to create a config object that ReactMarkdown likes, that is specific for material ui
import React from 'react';
import ReactMarkdown from 'markdown-to-jsx';
import { withStyles } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import Link from '@material-ui/core/Link';
const styles = (theme) => ({
listItem: {
marginTop: theme.spacing(1),
},
});
const options = {
overrides: {
h1: {
component: Typography,
props: {
gutterBottom: true,
variant: 'h5',
},
},
h2: { component: Typography, props: { gutterBottom: true, variant: 'h6' } },
h3: { component: Typography, props: { gutterBottom: true, variant: 'subtitle1' } },
h4: {
component: Typography,
props: { gutterBottom: true, variant: 'caption', paragraph: true },
},
p: { component: Typography, props: { paragraph: true } },
a: { component: Link },
li: {
component: withStyles(styles)(({ classes, ...props }) => (
<li className={classes.listItem}>
<Typography component="span" {...props} />
</li>
)),
},
},
};
export default function Markdown(props) {
return <ReactMarkdown options={options} {...props} />;
}
I got that straight from their example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With