Smoothly Inclusive: React component library documentation with Gatsby and MDX

A presentation at Gatsby Days in February 2020 in Los Angeles, CA, USA by Kathleen McMahon

Slide 1

Slide 1

Hi, my name is Kathleen McMahon and I’m here today to tell you how Gatsby and MDX helped us make our React component library documentation smoothly inclusive

Before we begin, let’s get some details out of the way

Slide 2

Slide 2

Since time is compressed, and I’d love to talk at a reasonable pace for our live captioner…

My slide deck will be posted on Notist, including links to resources I briefly touch upon. The full URL will be available later today on Twitter.

Slide 3

Slide 3

You can follow me at. Resource11 on Twitter, Instagram, and GitHub.

Before we dig into Gatsby and MDX, let’s back up so I can introduce myself better…

Slide 4

Slide 4

I’m the Tech Lead for O’Reilly Media’s design system

Slide 5

Slide 5

And I race bikes… very badly.

Slide 6

Slide 6

Mostly you’ll see me in costume, racing two laps to your six, at the back of the pack, on a singlespeed.

So while racing in costume is exciting…

Slide 7

Slide 7

…working on a design system is even better! Especially if you’re rebooting your system.

Slide 8

Slide 8

If you’ve never worked on a design system, let’s just say… There are a lot of moving parts.

Slide 9

Slide 9

If your core team is small like ours — around 3-4 people — you really have to choose your focus. And… rely on your contributors.

Slide 10

Slide 10

In our case, or focus was business logic out, accessibility in. We fixed our colors, our components, our patterns, and rebooted our docs.

Slide 11

Slide 11

Once we did that, we realized that a part of our system was becoming a hindrance for our team, and a barrier to entry for our contributors: our documentation.

Our process was spread across two projects: the design-system repo, and the design-system-docs repo.

Slide 12

Slide 12

In the design-system repo, our documentation content was stored…

Slide 13

Slide 13

…in two locations…

Slide 14

Slide 14

While docs repo held the site scaffolding…

Slide 15

Slide 15

…and docs layout components.

Slide 16

Slide 16

To get up and running, you had to follow a detailed series of steps to sync, run scripts, grab files, parse information, generate data, and render the docs to a React app. Phew!

Slide 17

Slide 17

Just getting starting working with our repos was overwhelming for new contributors to say the least…

Slide 18

Slide 18

But wait there’s more!

Our scripts were set up in such a way that you had to write your Markdown in a very specific order for your content to show up in the docs.

Slide 19

Slide 19

Your Button heading could be paired with an intro paragraph, but only one paragraph.

Slide 20

Slide 20

Same with your variants. Only one paragraph, and then a code block.

Slide 21

Slide 21

Best practices had to be written as an unordered list. Always.

Slide 22

Slide 22

Same with the Related components section. Always an unordered list.

Slide 23

Slide 23

So while our docs scripts were great for of generating color swatches and details about which props were available in components…

Slide 24

Slide 24

The process was not great for creating our component documentation.

Slide 25

Slide 25

Which frustrated all of us.

Slide 26

Slide 26

One mistake, and parts if not whole chunks of documentation would be missing on the component pages. We had the freedom of using markdown, yet weren’t taking advantage of it.

Slide 27

Slide 27

This was a serious cognitive lift, even for someone who is very familiar with the codebase

Slide 28

Slide 28

Now imagine if you have a new contributor to your project…? Not exactly a welcoming experience.

Slide 29

Slide 29

We decided to review our process and see what wasn’t working.

Slide 30

Slide 30

One of our biggest issues: we chose to show one component variant at a time, rather than all at once. We forced our users to access a select menu over and over to compare variants, which increased the time they needed to look up information. It didn’t make sense.

Slide 31

Slide 31

In retrospect, that decision was about as questionable as a recipe that combines Jello with shellfish

Slide 32

Slide 32

We decided that it was time to make our docs contribution process more user friendly, in terms of the structure, and how we authored.

Slide 33

Slide 33

Especially the component example pages. We wanted the users to have confidence that whatever content they wrote in a docs page

Slide 34

Slide 34

…would make it into that docs page.

Slide 35

Slide 35

@resource11 If we made our docs more user friendly, we’d have more contributors rather than fewer.

Slide 36

Slide 36

We considered our options for making our docs better, and decided upon Gatsby for a few reasons.

Slide 37

Slide 37

  1. Gatsby gave us a way to migrate all our main documentation pages right into the site without much fuss,

  2. Gatsby provides a Webpack and Babel config similar to create-react-app, so we could start with a scaffolded project, and extend as needed.

And…

Slide 38

Slide 38

  1. Gatsby supports MDX, so we can write component documentation using Markdown, import React components right in the file, and it just works. Even better, MDX will compile down into…

Slide 39

Slide 39

Semantic HTML. Which in, gives your site…

Slide 40

Slide 40

Improved accessibility. Better support for your users that rely on assistive technology to access your docs. Yuraima Estevez will be talking about general component accessibility later on today, and it’s a really good talk. That said, if your design system is promoting inclusivity in general, it follows that inclusive docs makes sense.

Slide 41

Slide 41

As a bonus, with Gatsby we could streamline our setup from two repos to one, and…

Slide 42

Slide 42

Reduce the amount of CLI commands

Slide 43

Slide 43

Dramatically.

Slide 44

Slide 44

The default setup for Gatsby is great, however, we’ll need to make some adjustments so Gatsby can work for our needs.

Slide 45

Slide 45

In the gatsby-config file…

Slide 46

Slide 46

we add gatsby-plugin-postcss to support PostCSS…

Slide 47

Slide 47

gatsby-plugin-compile-es6-packages to support our design system package…

Slide 48

Slide 48

gatsby-plugin-mdx, so our site will recognize MDX files..

Slide 49

Slide 49

gatsby-remark-autolink-headers, to generate auto links for our headings for better screen reader and keyboard support…

Slide 50

Slide 50

gatsby-plugin-page-creator to create pages from the src/pages folder…

Slide 51

Slide 51

And gatsby-plugin-filesystem so we can pull in our data file, and…

Slide 52

Slide 52

…point Gatsby to the folder where all our component MDX files live.

Slide 53

Slide 53

In the gatsby-node file…

Slide 54

Slide 54

we add a GraphQL query to find the component MDX content

Slide 55

Slide 55

And a createPage action to generate routes and pages for the component docs.

Slide 56

Slide 56

…into the gatsby-browser file, since this file is used to make changes at the site-wide level.

Slide 57

Slide 57

We add things we want to apply throughout the site, like our global CSS styles and the wrap-root-element component.

Slide 58

Slide 58

This wrap-root-element component will act as a wrapper around our site’s root element…

Slide 59

Slide 59

…And imports MDXProvider. This, way the entire site will recognize MDX content.

Slide 60

Slide 60

We have to do one extra thing for our component docs page template, though.

Slide 61

Slide 61

Since our component MDX files are located outside of the src/pages folder, MDXRenderer needs to wrap the contents of our component page template.

Otherwise, our MDXs file would render…

Slide 62

Slide 62

…like this in the browser…

Slide 63

Slide 63

…Now that our template uses MDXRenderer, our component MDX pages…

Slide 64

Slide 64

…will render as we want in the browser.

Slide 65

Slide 65

Now you can pop in React components next to your code blocks

Slide 66

Slide 66

And they will render, no problem.

Slide 67

Slide 67

You can even wrap your Button component with a DisplayBox component

Slide 68

Slide 68

And add a more cohesive look to your component/code block pairing

Slide 69

Slide 69

If we want to add a props table to show which props can be uses with the component…

Slide 70

Slide 70

We can create a component that pulls in data, into a table component. Pass in the component to render…

Slide 71

Slide 71

Pop that component into your docs MDX, pass in the name of the component to render…

Slide 72

Slide 72

And your docs will show a props table.

Slide 73

Slide 73

For those component Dos and Don’ts

Slide 74

Slide 74

If you write out an unordered list in your MDX file

Slide 75

Slide 75

The list will render.

Slide 76

Slide 76

If you instead create a custom component that renders unordered lists for you

Slide 77

Slide 77

And send a dosList and a dontsList array into your component

Slide 78

Slide 78

You can have a nicely styles dos/don’ts list

Slide 79

Slide 79

Code blocks. Markdown has great code block support. MDX makes those even more powerful.

You can override the styling of a code block in an MDX file with a custom code block, or even display different types of code blocks.

Slide 80

Slide 80

You could use prism-react-renderer in a custom CodeBlock component and import a theme with good color contrast

Slide 81

Slide 81

… wrap your code block and theme it…

Slide 82

Slide 82

Import that into your wrap-root-element along with the preToCodeBlock util

Slide 83

Slide 83

And override the default pre styling at the app level by passing it in as a component to the wrapRootElement.

Slide 84

Slide 84

So now when you write a code block in MDX

Slide 85

Slide 85

Instead of the baseline styling…

Slide 86

Slide 86

…the custom code block will render with syntax highligthing.

Slide 87

Slide 87

Fun fact: you can pass in a prop to that code block and do really cool things if you use custom code blocks!

Slide 88

Slide 88

For example, we can abstract this MDX into a DRYer pattern into custom our CodeBlock component…

Slide 89

Slide 89

… and if the displaybox prop is passed in, show a. displayBox/code block pairing

Slide 90

Slide 90

So if you add the displaybox prop to their code block in MDX…

Slide 91

Slide 91

You’ll get a display box paired with a code block. What about if you want your code block to be an editable code block?

Slide 92

Slide 92

You can add a react-live option in our component.

Slide 93

Slide 93

…and show component inside a displayBox pairing with an editable code block…

Slide 94

Slide 94

… so if you add the react-live prop to your MDX code block…

Slide 95

Slide 95

You’ll get an editable block, and see your changes in real time.

Slide 96

Slide 96

… So if we write something like this… this is what you see in the app

[open demo]

Here’s a side-by-side example of the three options, the live editable code block is the top block here.

Slide 97

Slide 97

So to wrap up…

Slide 98

Slide 98

If your documentation setup is brittle, your contributors will flee…

Slide 99

Slide 99

But Gatsby…

Slide 100

Slide 100

And MDX…

Slide 101

Slide 101

Can help make your docs inclusively smooth in both setup and execution.

Slide 102

Slide 102

Then your contributors will return…

Slide 103

Slide 103

…and will be happy to be part of your team.

Slide 104

Slide 104

Thank you

Slide 105

Slide 105

https://noti.st/resource11 Slide deck posted after the talk

@resource11 Twitter | Instagram | GitHub