facebook / docusaurus

Easy to maintain open source documentation websites.
https://docusaurus.io
MIT License
55.68k stars 8.34k forks source link

use composition style for prism-highlighting #1546

Closed jaredpalmer closed 5 years ago

jaredpalmer commented 5 years ago

If we do prism highlighting at render-time in React and not in the mdx loader, it would allow people to get access to code blocks as strings instead of html. This would make it easy for folks to add live code editors like react-live.

We could keep the default prism setup too if we follow this guide in the MDX docs: https://mdxjs.com/guides/live-code#live-code.

The benefits are pretty rad. I made a video of my setup for the formik v2 docs.

Kapture 2019-06-02 at 15 34 38

My swizzled <DocsItem> looks like this. As you can see, I am wrapping the DocContent with MDXProvider so I can override the code component with my playground.

import React from 'react';
import Head from '@docusaurus/Head';
import DocPaginator from '@theme/DocPaginator';
import { MDXProvider } from '@mdx-js/react';
import styles from './styles.module.css';
import Playground from '../../components/Playground';

const Components = {};
Components.code = Playground;
Components.inlineCode = props => <code className="code" {...props} />;
Components.wrapper = props => <React.Fragment {...props} />;
Components.h1 = props => <h1 className="h1" {...props} />;
Components.h2 = props => <h2 className="h2" {...props} />;
Components.h3 = props => <h3 className="h3" {...props} />;
Components.h4 = props => <h4 className="h4" {...props} />;
Components.h5 = props => <h5 className="h5" {...props} />;
Components.h6 = props => <h6 className="h6" {...props} />;
Components.p = props => <p className="paragraph" {...props} />;
Components.ul = props => <ul className="ul" {...props} />;
Components.ol = props => <ol className="ol" {...props} />;
Components.li = props => <li className="li" {...props} />;
Components.a = props => <a className="link" {...props} />;
Components.blockquote = props => (
  <blockquote className="blockquote" {...props} />
);
Components.strong = props => <strong className="strong" {...props} />;
Components.pre = props => (
  <pre
    className="pre"
    style={{ backgroundColor: 'transparent', fontFamily: 'inherit' }}
    {...props}
  />
);

function Headings({ headings, isChild }) {
  if (!headings.length) return null;
  return (
    <ul className={isChild ? 'contents' : 'contents contents__left-border'}>
      {headings.map(heading => (
        <li key={heading.id}>
          <a href={`#${heading.id}`} className="contents__link">
            {heading.value}
          </a>
          <Headings isChild headings={heading.children} />
        </li>
      ))}
    </ul>
  );
}

function DocItem(props) {
  const { metadata, content: DocContent, docsMetadata } = props;

  return (
    <div className={styles.docBody}>
      <Head>
        {metadata && metadata.title && <title>{metadata.title}</title>}
      </Head>
      <div className="container margin-vert--lg">
        <div className="row">
          <div className="col col--8">
            <header>
              <h1 className="margin-bottom--lg">{metadata.title}</h1>
            </header>
            <article>
              <div className="markdown">
                <MDXProvider components={Components}>
                  <DocContent />
                </MDXProvider>
              </div>
            </article>
            <div className="margin-vert--lg" />
            <DocPaginator docsMetadata={docsMetadata} metadata={metadata} />
          </div>
          <div className="col col--3 col--offset-1">
            {DocContent.rightToc && <Headings headings={DocContent.rightToc} />}
          </div>
        </div>
      </div>
    </div>
  );
}

export default DocItem;
endiliey commented 5 years ago

@jaredpalmer

Thanks for trying out v2 and letting us know about this. Its quite a coincidence that I was just reading https://mdxjs.com/guides/live-code/ recently and was thinking about this too.

I will look into this.

On another note, are you hosting your code somewhere ? We will most likely have breaking changes in subsequent alpha. we can help you update if you are adopting it early

jaredpalmer commented 5 years ago

@endiliey my branch for formik 2 docs is here https://github.com/jaredpalmer/formik/tree/feat/docsite

endiliey commented 5 years ago

@jaredpalmer

Thanks, I'll try my best to spend time to help you update for subsequent version. Actually we don't want people to swizzle too much at this point because we're in alpha and few things are still experimental. Didn't really expect someone to start swizzling already :)