Giter Club home page Giter Club logo

gatsby-documentation-starter's Introduction

Screenshot of example Documentation website created with this template

Gatsby Documentation Starter

Automatically generate documentation for your project using MDX, react-docgen, and GatsbyJS.

Features

  • ๐Ÿ“ MDX - Write your documentation in Markdown and include React components using JSX!
  • โ™ป๏ธ react-docgen - Automatically parses all your React components (functional, stateful, even stateless!) for JS Docblocks and Prop Types.
  • โš›๏ธ GatsbyJS - Creates local GraphQL server to build static version of documentation (easily deployed on a CDN or GHPages, Netlify, etc)
  • ๐Ÿ—„ Props Table - Component for displaying component props in a table format
  • ๐ŸŽ› Modular - Easily install inside existing projects!
  • โš–๏ธ Lightweight - Only what you need, no extra dependencies.

Quick Start

Install with Netlify

  1. Deploy to Netlify

Install with Gatsby CLI

  1. gatsby new docs https://github.com/whoisryosuke/gatsby-documentation-starter/

Custom install

  1. git clone https://github.com/whoisryosuke/gatsby-documentation-starter.git
  2. Update gatsby-config.js with the location of your components + MDX (see: "Changing source folder")
  3. npm install inside project
  4. npm run develop
  5. View your documentation: http://localhost:8000

Check out the example branch to see the source code of the demo.

Creating documentation

Documentation is sourced from two places: component source code and MDX files.

src
โ””โ”€โ”€ components
    โ””โ”€โ”€ Button
        โ”œโ”€โ”€ Button.js
        โ””โ”€โ”€ Button.mdx

React-docgen grabs any JS Docblocks you write for your React classes/functions (Button.js), as well as the Prop Types. These are displayed on your documentation page, with the props displayed in a table.

Inside your MDX file you can write additional documentation with JSX examples. You can also specify the page slug here (a page name and category). Your pages will be generated as http://yoursite.com/<category>/<pageName>.

In order for your component data to show up, you need an MDX file for the component - and the page name and component name in the docblock need to match.

/**
 * ComponentTitle
**/
class ComponentName extends React.Component {}
---
name: ComponentTitle
menu: CategoryName
---

Creates a page for the component located at http://localhost:8000/categoryname/componentname

Documentation

Customizing sidebar navigation

The sidebar navigation is generated from two places: a JSON config with static pages, and component MDX files. The static pages are displayed before the components.

To customize the static pages, go to gatsby-config.js and edit the sidebar object inside the siteMetadata config. Each page is represented as an object with a slug (the URL) and title:

  siteMetadata: {
    title: 'Gatsby Documentation Starter',
    sidebar: {
      pages: [
        {
          slug: '/about',
          title: 'about',
        },
      ],
    },
  },

The component pages in the navigation are automatically generated by querying all components with MDX files. If you want to change this, see section: "Creating pages from react-docgen"

You can override all of this functionality inside components/sidebar.js.

Changing source folder

Add the relative location of your components and MDX files in gatsby-config.js. The default configuration is set to the /src/components/ folder of your root project (which ideally should document every component):

    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `components`,
        path: `../src/components/`,
      },
    },

Gatsby will load all the JS and MDX files inside this folder. Then using the "transformer" plugins, Gatsby creates GraphQL endpoints for both components and MDX (allMdx and allComponentMetadata).

You can add as many file sources as you need. The transformer plugins will automatically group content based on their format (JS, MDX, etc), and it uses all the content that's loaded.

Adding to existing projects

This project is designed to be embedded inside existing projects.

  1. git clone this repo into your project as a docs subfolder.
  2. Optionally change the folder where components are loaded from (see "Changing source folder")
  3. npm install && npm run develop

Creating pages from react-docgen

This template is setup to generate pages based off MDX files in your project. This allows you to create a Button.mdx to document your <Button />.

It's not required to make pages based off MDX. You can use Gatsby's default routing configuration, which creates pages based on any .js files located in the pages subfolder.

If you don't plan on having MDX files for each component, you can easily swap over to using react-docgen data to generate pages. That way, you're ensured a documentation page for each component (instead of MDX file). This isn't the only option either, Gatsby's flexibility allows you to use both react-docgen and MDX files if you wanted the best of both worlds

gatsby-node.js:

/**
 * Implement Gatsby's Node APIs in this file.
 *
 * See: https://www.gatsbyjs.org/docs/node-apis/
 */

const path = require('path')
const componentWithMDXScope = require('gatsby-mdx/component-with-mdx-scope')

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  return new Promise((resolve, reject) => {
    resolve(
      graphql(
        `
          {
            allComponentMetadata {
              edges {
                node {
                  id
                  displayName
                  docblock
                  doclets
                  childrenComponentProp {
                    name
                    docblock
                    required
                    type {
                      value
                    }
                    defaultValue {
                      value
                      computed
                    }
                  }
                  composes
                }
              }
            }
          }
        `
      ).then(result => {
        if (result.errors) {
          console.log(result.errors)
          reject(result.errors)
        }
        // Create blog posts pages.
        result.data.allComponentMetadata.edges.forEach(async ({ node }) => {
          createPage({
            path: `/components/${node.displayName.toLowerCase()}`,
            component: componentWithMDXScope(
              path.resolve('./src/templates/posts.js'),
              node.code.scope
            ),
            context: {
              id: node.id,
              name: node.displayName,
            },
          })
        })
      })
    )
  })
}

We query the components through the react-docgen endpoint and use those to generate pages (instead of MDX files). Then we alter the page template to query MDX by name (located in the Markdown 'frontmatter'), and component by ID (the vice versa of it's default setup):

templates/posts.js:

import React, { Component } from 'react'
import { graphql } from 'gatsby'
import MDXRenderer from 'gatsby-mdx/mdx-renderer'
import { MDXProvider } from '@mdx-js/tag'

import Layout from '../components/layout'
import PropsTable from '../components/propstable'

export default class MDXRuntimeTest extends Component {
  render() {
    const { children, data, tableOfContents } = this.props
    return (
        <MDXProvider>
          <Layout>
            <div className="content">
              {children}
              <h1>{data.componentMetadata.displayName}</h1>
              <p>{data.componentMetadata.docblock}</p>
              <MDXRenderer tableOfContents={tableOfContents}>
                {data.mdx.code.body}
              </MDXRenderer>
              <h2 style={{ marginTop: '2rem' }}>Props:</h2>
              <PropsTable
                propMetaData={data.componentMetadata.childrenComponentProp}
              />
            </div>
          </Layout>
        </MDXProvider>
    )
  }
}

export const pageQuery = graphql`
  query($id: String!, $name: String!) {
    mdx(frontmatter: { name: { eq: $name } }) {
      id
      code {
        body
      }
      tableOfContents
    }
    componentMetadata(id: { eq: $id }) {
      id
      displayName
      docblock
      doclets
      childrenComponentProp {
        name
        docblock
        required
        parentType {
          name
        }
        type {
          value
        }
        defaultValue {
          value
          computed
        }
      }
      composes
    }
  }
`

Credits

gatsby-documentation-starter's People

Contributors

kyleamathews avatar whoisryosuke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

gatsby-documentation-starter's Issues

Can't to npm install

image

npm ERR! code ETARGET
npm ERR! notarget No matching version found for gatsby@next
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget 
npm ERR! notarget It was specified as a dependency of 'gatsby-documentation-starter'
npm ERR! notarget 

Incorrect components source path

When running the gatsby develop script on a fresh copy of this starter, the following error occurs:

The path passed to gatsby-source-filesystem does not exist on your file system:

../src/components/

Is the path supposed to be ./src/components/ (./ instead of ../)?

GraphQLError: Cannot query field "name" on type "frontmatter"

I have follow all the documented steps and gets the following error on npm run develop

Error:

[ { GraphQLError: Cannot query field "name" on type "frontmatter".
message: 'Cannot query field "name" on type "frontmatter".',
    locations: [ [Object] ],
    path: undefined 
},
{ GraphQLError: Cannot query field "menu" on type "frontmatter".
message: 'Cannot query field "menu" on type "frontmatter".',
    locations: [ [Object] ],
    path: undefined 
} ]

And this:

TypeError: Cannot read property 'allMdx' of undefined

  - gatsby-node.js:46 graphql.then.result
    /my/path/to/docs/gatsby-documentation-starter/gatsby-node.js:46:21

  - util.js:16 tryCatcher
    [gatsby-documentation-starter]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [gatsby-documentation-starter]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [gatsby-documentation-starter]/[bluebird]/js/release/promise.js:569:18

  - promise.js:606 Promise._settlePromiseCtx
    [gatsby-documentation-starter]/[bluebird]/js/release/promise.js:606:10

  - async.js:142 _drainQueueStep
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:142:12

  - async.js:131 _drainQueue
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:131:9

  - async.js:147 Async._drainQueues
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:147:5

  - async.js:17 Immediate.Async.drainQueues [as _onImmediate]
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:17:14


error Cannot read property 'filter' of undefined


  TypeError: Cannot read property 'filter' of undefined

  - api-runner-node.js:274 Promise.mapSeries.catch.then.results
    [gatsby-documentation-starter]/[gatsby]/dist/utils/api-runner-node.js:274:42

  - util.js:16 tryCatcher
    [gatsby-documentation-starter]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [gatsby-documentation-starter]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [gatsby-documentation-starter]/[bluebird]/js/release/promise.js:569:18

  - promise.js:614 Promise._settlePromise0
    [gatsby-documentation-starter]/[bluebird]/js/release/promise.js:614:10

  - promise.js:694 Promise._settlePromises
    [gatsby-documentation-starter]/[bluebird]/js/release/promise.js:694:18

  - async.js:138 _drainQueueStep
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:138:12

  - async.js:131 _drainQueue
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:131:9

  - async.js:147 Async._drainQueues
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:147:5

  - async.js:17 Immediate.Async.drainQueues [as _onImmediate]
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:17:14


error UNHANDLED REJECTION


  TypeError: Cannot read property 'filter' of undefined

  - api-runner-node.js:274 Promise.mapSeries.catch.then.results
    [gatsby-documentation-starter]/[gatsby]/dist/utils/api-runner-node.js:274:42

  - util.js:16 tryCatcher
    [gatsby-documentation-starter]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [gatsby-documentation-starter]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [gatsby-documentation-starter]/[bluebird]/js/release/promise.js:569:18

  - promise.js:614 Promise._settlePromise0
    [gatsby-documentation-starter]/[bluebird]/js/release/promise.js:614:10

  - promise.js:694 Promise._settlePromises
    [gatsby-documentation-starter]/[bluebird]/js/release/promise.js:694:18

  - async.js:138 _drainQueueStep
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:138:12

  - async.js:131 _drainQueue
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:131:9

  - async.js:147 Async._drainQueues
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:147:5

  - async.js:17 Immediate.Async.drainQueues [as _onImmediate]
    [gatsby-documentation-starter]/[bluebird]/js/release/async.js:17:14

My debug-log:

0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/Cellar/node/11.6.0/bin/node',
1 verbose cli   '/usr/local/bin/npm',
1 verbose cli   'run',
1 verbose cli   'develop' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'predevelop', 'develop', 'postdevelop' ]
5 info lifecycle [email protected]~predevelop: [email protected]
6 info lifecycle [email protected]~develop: [email protected]
7 verbose lifecycle [email protected]~develop: unsafe-perm in lifecycle true
8 verbose lifecycle [email protected]~develop: PATH: /usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/my/path/to/project/docs/gatsby-documentation-starter/node_modules/.bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
9 verbose lifecycle [email protected]~develop: CWD: /my/path/to/project/docs/gatsby-documentation-starter
10 silly lifecycle [email protected]~develop: Args: [ '-c', 'gatsby develop' ]
11 silly lifecycle [email protected]~develop: Returned: code: 1  signal: null
12 info lifecycle [email protected]~develop: Failed to exec develop script
13 verbose stack Error: [email protected] develop: `gatsby develop`
13 verbose stack Exit status 1
13 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:301:16)
13 verbose stack     at EventEmitter.emit (events.js:188:13)
13 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
13 verbose stack     at ChildProcess.emit (events.js:188:13)
13 verbose stack     at maybeClose (internal/child_process.js:978:16)
13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:265:5)
14 verbose pkgid [email protected]
15 verbose cwd /my/path/to/project/docs/gatsby-documentation-starter
16 verbose Darwin 18.2.0
17 verbose argv "/usr/local/Cellar/node/11.6.0/bin/node" "/usr/local/bin/npm" "run" "develop"
18 verbose node v11.6.0
19 verbose npm  v6.5.0
20 error code ELIFECYCLE
21 error errno 1
22 error [email protected] develop: `gatsby develop`
22 error Exit status 1
23 error Failed at the [email protected] develop script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

Is there a minimum node version required for this?

Thanks!

yarn run develop gives error: ""siteMetadata.siteUrl" must be a valid uri"

Error while running yarn run develop. I realize you might not care about this since you use npm in you're examples, but in case you do:

docs-docs % yarn run develop
yarn run v1.22.10
warning ../../../../package.json: No license field
$ gatsby develop

 ERROR #10122  CONFIG

The site's gatsby-config.js failed validation:

"siteMetadata.siteUrl" must be a valid uri

not finished open and validate gatsby-configs, load plugins - 0.204s

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
yarn run develop  3.54s user 1.23s system 62% cpu 7.620 total

Accessibility improvements!

Cool starter! I noticed there are some accessibility opportunities with this repo, including some issues with the header:

  • There's an onclick event directly on an SVG element. If possible, can you wrap the SVG with a button element to be keyboard-and-screen-reader-focusable and interactive?
  • You could use an aria-label attribute on the button to indicate its name (whatever it's doing, like "Menu open" / "Menu closed" depending on state). That would also add a visible keyboard focus style, since it would be a native button!
  • When the sidebar is collapsed, using the inert attribute and polyfill on it will prevent keyboard focus from going into visually-hidden links!
  • Some additional improvements could be adding role="presentation" and focusable="false" on the SVG to make it work like a decorative image.

You could also add some landmarks for the header, sidebar and main content area (<header>, <nav> and <main>, respectively).

I'd be happy to answer any accessibility questions you might have, as this starter would be such a great way to distribute accessible docs. I've got a demo that might come in handy: the sidebar and markup uses these patterns. https://github.com/marcysutton/a11y-demo-app/tree/master

Creating pages from react-docgen

Hey, I think there is something wrong in doc in section Creating pages from react-docgen. I'm not using MDX files, so I'm trying to use react-docgen. In example file (gatsby-node.js), in GRAPHQL part there is NO object code {scope}, but in createPage -> componentWithMDXScope part the code is trying to pass this object. Node says: error: UNHANDLER REJECTION.

GraphQLError: Cannot query field "allMdx" on type "Query".

Hi, i'm getting the following error on vanilla install...I've followed the docs as the read for adding to an existing project - My project does not have any mdx files, only js....is that my issue?

Let me know what else i can provide.

โ  [ { GraphQLError: Cannot query field "allMdx" on type "Query".
    at Object.Field (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/graphql/validation/rules/FieldsOnCorrectType.js:65:31)
    at Object.enter (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/graphql/language/visitor.js:324:29)
    at Object.enter (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/graphql/language/visitor.js:366:25)
    at visit (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/graphql/language/visitor.js:254:26)
    at visitUsingRules (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/graphql/validation/validate.js:74:22)
    at validate (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/graphql/validation/validate.js:59:10)
    at graphqlImpl (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/graphql/graphql.js:106:50)
    at /Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/graphql/graphql.js:66:223
    at Promise._execute (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/bluebird/js/release/debuggability.js:313:9)
    at Promise._resolveFromExecutor (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/bluebird/js/release/promise.js:483:18)
    at new Promise (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/bluebird/js/release/promise.js:79:10)
    at graphql (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/graphql/graphql.js:63:10)
    at graphqlRunner (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/gatsby/dist/bootstrap/index.js:300:14)
    at Promise (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/gatsby-node.js:14:7)
    at Promise._execute (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/bluebird/js/release/debuggability.js:313:9)
    at Promise._resolveFromExecutor (/Users/em/Documents/work/Daikin/daikin-ssr-app/docs/node_modules/bluebird/js/release/promise.js:483:18)
    message: 'Cannot query field "allMdx" on type "Query".',
    locations: [ [Object] ],
    path: undefined } ]
error gatsby-node.js returned an error

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.