Skip to content

Commit

Permalink
Styleguide example (#3304)
Browse files Browse the repository at this point in the history
* Adds plop boilerplate

* Adds base stuff

* Configurable background colors

* Rename props

* Add a comment

* Add a component README

* Tweaks

* Can query successfully

* Adds components and index

* Add prop types

* Adds component index

* Link back to component index

* Showing props / methods

* Add size prop to Button

* Remove log

* We are querying markdown

* Feeds example html into renderer

* Parsing / rendering HTML

* Starts parsing nodes

* It works

* Add prop types

* Adds size example to README

* Sets up component index

* Writes dyanmic component index to the cache

* Renaming for clarity

* Add description

* Renaming

* Possible strategy for ensuring durability of components in library previews

* Using a particular prism theme

* Fix proptypes

* POC styling editor

* Converts to table

* new name
  • Loading branch information
scottyeck authored and KyleAMathews committed Apr 4, 2018
1 parent dadf533 commit b06fcab
Show file tree
Hide file tree
Showing 19 changed files with 653 additions and 0 deletions.
8 changes: 8 additions & 0 deletions examples/styleguide/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"env": {
"browser": true
},
"globals": {
"graphql": false
}
}
3 changes: 3 additions & 0 deletions examples/styleguide/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
public
.cache
node_modules
5 changes: 5 additions & 0 deletions examples/styleguide/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Gatsby Styleguide Example

> A living styleguide proof-of-concept built using Gatsby. Inspired by [react-styleguidist](https://react-styleguidist.js.org/).
https://styleguide.gatsbyjs.org
19 changes: 19 additions & 0 deletions examples/styleguide/gatsby-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const path = require(`path`)

module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
path: path.join(__dirname, `src/components`),
name: `components`,
},
},
{
resolve: `gatsby-transformer-react-docgen`,
},
{
resolve: `gatsby-transformer-remark`,
},
],
}
115 changes: 115 additions & 0 deletions examples/styleguide/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
const path = require(`path`)
const fs = require(`fs`)
const appRootDir = require(`app-root-dir`).get()

const componentPageTemplate = path.resolve(
`src/templates/ComponentPage/index.js`
)
const tableOfContentsTemplate = path.resolve(`src/templates/TOC/index.js`)

exports.createPages = ({ graphql, boundActionCreators }) => {
const { createPage } = boundActionCreators

return new Promise((resolve, reject) => {
resolve(
Promise.all([
graphql(`
{
allComponentMetadata {
edges {
node {
id
displayName
description {
text
}
props {
name
type {
value
raw
name
}
description {
text
}
required
}
}
}
}
}
`),
graphql(`
{
allMarkdownRemark(
filter: { fileAbsolutePath: { regex: "/README.md/" } }
) {
edges {
node {
fileAbsolutePath
html
}
}
}
}
`),
])
.then(([docgenResult, markdownResult]) => {
const errors = docgenResult.errors || markdownResult.errors
if (errors) {
reject(new Error(errors))
return
}

const allComponents = docgenResult.data.allComponentMetadata.edges.map(
(edge, i) =>
Object.assign({}, edge.node, {
path: `/components/${edge.node.displayName.toLowerCase()}/`,
html: markdownResult.data.allMarkdownRemark.edges[i].node.html,
})
)

const exportFileContents =
allComponents
.reduce((accumulator, { id, displayName }) => {
const absolutePath = id.replace(/ absPath of.*$/, ``)
accumulator.push(
`export { default as ${displayName} } from "${absolutePath}"`
)
return accumulator
}, [])
.join(`\n`) + `\n`

fs.writeFileSync(
path.join(appRootDir, `.cache/components.js`),
exportFileContents
)

allComponents.forEach(data => {
const { path } = data
const context = Object.assign({}, data, {
allComponents,
})
createPage({
path,
component: componentPageTemplate,
context,
})
})

createPage({
path: `/components/`,
component: tableOfContentsTemplate,
context: {
allComponents,
},
})
})
.catch(err => {
console.log(err)
throw new Error(err)
})
)
})
}
23 changes: 23 additions & 0 deletions examples/styleguide/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "styleguide",
"private": true,
"description": "Gatsby example site demoing living-style-guide",
"author": "[email protected]",
"dependencies": {
"app-root-dir": "^1.0.2",
"gatsby": "latest",
"gatsby-link": "latest",
"gatsby-source-filesystem": "^1.5.11",
"gatsby-transformer-react-docgen": "^1.0.11",
"gatsby-transformer-remark": "^1.7.25",
"glamor": "^2.20.40",
"html-to-react": "^1.3.1",
"react-live": "^1.7.1"
},
"license": "MIT",
"main": "n/a",
"scripts": {
"develop": "gatsby develop",
"build": "gatsby build"
}
}
84 changes: 84 additions & 0 deletions examples/styleguide/src/components/Button/Button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from "react"
import PropTypes from "prop-types"
import { css } from "glamor"

const blue = `blue`
const orange = `orange`
const green = `green`

const colors = {
[blue]: {
primary: `#A0CED9`,
hover: `#92BCC6`,
},
[orange]: {
primary: `#EAB69B`,
hover: `#E8AF91`,
},
[green]: {
primary: `#ADF7B6`,
hover: `#9EE1A6`,
},
}

const sm = `sm`
const md = `md`
const lg = `lg`

const sizes = {
[sm]: {
fontSize: `14px`,
padding: `12px 20px`,
minWidth: `160px`,
},
[md]: {
fontSize: `18px`,
padding: `16px 24px`,
minWidth: `200px`,
},
[lg]: {
fontSize: `22px`,
padding: `20px 28px`,
minWidth: `260px`,
},
}

const styles = ({ backgroundColor, size }) => {
const backgroundColorConfig =
colors[backgroundColor] || colors[Button.defaultProps.backgroundColor]
const sizeConfig = sizes[size] || sizes[Button.defaultProps.size]
return css({
backgroundColor: backgroundColorConfig.primary,
...sizeConfig,
color: `rgba(36, 47, 60, 0.66)`,
display: `inline-block`,
borderRadius: `3px`,
border: 0,
cursor: `pointer`,
"&:hover": {
backgroundColor: backgroundColorConfig.hover,
},
})
}

/**
* The `<Button>` is a foundational trigger component for capturing
* and guiding user-interaction.
*/
const Button = ({ backgroundColor, size, ...rest }) => (
<button className={styles({ backgroundColor, size })} {...rest} />
)

Button.propTypes = {
/** The color to use as the background */
backgroundColor: PropTypes.oneOf(Object.keys(colors)),
/** The size of the button */
size: PropTypes.oneOf(Object.keys(sizes)),
}

Button.defaultProps = {
backgroundColor: blue,
size: md,
}

export default Button
25 changes: 25 additions & 0 deletions examples/styleguide/src/components/Button/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
The basic button.

```
<Button>Get Started</Button>
```

Colors are configurable.

```
<div>
<div><Button backgroundColor="blue">Get Started</Button></div>
<div><Button backgroundColor="green">Get Started</Button></div>
<div><Button backgroundColor="orange">Get Started</Button></div>
</div>
```

Sizes are also configurable.

```
<div>
<div><Button size="sm">Get Started</Button></div>
<div><Button size="md">Get Started</Button></div>
<div><Button size="lg">Get Started</Button></div>
</div>
```
1 change: 1 addition & 0 deletions examples/styleguide/src/components/Button/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./Button"
12 changes: 12 additions & 0 deletions examples/styleguide/src/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react"
import { Route, Redirect } from "react-router-dom"

class Home extends React.Component {
render() {
return (
<Route exact path="/" render={() => <Redirect to="/components/" />} />
)
}
}

export default Home
56 changes: 56 additions & 0 deletions examples/styleguide/src/templates/ComponentPage/ComponentPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from "react"
import PropTypes from "prop-types"
import GatsbyLink from "gatsby-link"

import Example from "./components/Example"

class ComponentPage extends React.Component {
render() {
const { displayName, props, html, description } = this.props.pathContext

return (
<div>
<h1>{displayName}</h1>
<p>{description.text}</p>
<h2>Props/Methods</h2>
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Type</th>
<th>Required</th>
</tr>
</thead>
<tbody>
{props.map(({ name, description, type, required }, index) => (
<tr key={index}>
<td>{name}</td>
<td>{description.text}</td>
<td>{type.name}</td>
<td>{String(Boolean(required))}</td>
</tr>
))}
</tbody>
</table>
<Example html={html} />
<p>
<GatsbyLink to="/components/">[index]</GatsbyLink>
</p>
</div>
)
}
}

ComponentPage.propTypes = {
pathContext: PropTypes.shape({
displayName: PropTypes.string.isRequired,
props: PropTypes.array.isRequired,
html: PropTypes.string.isRequired,
description: PropTypes.shape({
text: PropTypes.string.isRequired,
}),
}).isRequired,
}

export default ComponentPage
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from "react"
import PropTypes from "prop-types"
import { LiveProvider, LiveEditor, LiveError, LivePreview } from "react-live"

import * as components from "../../../../../.cache/components"

import "./prism-theme.css"

const editorStyles = {
backgroundColor: `#f2f2f2`,
boxSizing: `border-box`,
padding: `16px`,
}

class ComponentPreview extends React.Component {
render() {
return (
<LiveProvider
scope={components}
code={this.props.code}
mountStylesheet={false}
>
<LiveEditor style={editorStyles} />
<LiveError />
<LivePreview />
</LiveProvider>
)
}
}

ComponentPreview.propTypes = {
code: PropTypes.string.isRequired,
}

export default ComponentPreview
Loading

0 comments on commit b06fcab

Please sign in to comment.