MDX is super-cool, allowing one to include React Components in a markdown file:
# Title
A nicely formatted paragraph of text with [some links](www.blahblah.com).
<MyIncredibleComponent data={{ status: "brilliant }} />
More text which is *effortlessly* well-styled.
One of the most useful features is that it allows you to supply components to use in place of the defaults for markdown's fundamental building blocks, like <p>
or <h1>
. Whatever CSS solution you're using, this makes it easy to pass in pre-styled tags:
.my-paragraph-style {
color: #444;
margin-bottom: 2em;
}
const Paragraph = ({ children }) => <p className="my-paragraph-style">{children}</p> // or just a styled-component, etc.
<MDXProvider components={{ p: Paragraph }}>
...
</MDXProvider>
Hooray! But what happens when you occasionally want to use a slightly special style for a markdown primitive? Sure, you can inline your own markdown component, like <ParagraphWithFlair>
, but for more complex primitives (e.g. tables) this would mean supplying the tag's content in a completely different format for the vanilla and alternative versions. So?
Well, you can leverage CSS sibling selectors and some hold-your-nose hackery to achieve the same thing without ruining your markup, using a kind of "decorator" style:
.my-table-style {
table-layout: fixed;
...some other styles
}
.auto-layout-table + .my-table-style {
table-layout: auto;
}
const Table = ({ children }) => <table className="my-table-style">{children}</table>
const AutoLayoutTable = () => <div className="auto-layout-table" />
<MDXProvider components={{ table: Table }}>
...
</MDXProvider>
And now, in your MDX:
This table is fixed layout:
| Letter | Number | Direction |
|---------------|---------------|------------|
| A | 1 | north |
| B | 2 | south |
This table is auto layout:
<AutoLayoutTable />
| Letter | Number | Direction |
|---------------|---------------|------------|
| C | 3 | east |
| D | 4 | west |
🚀