Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .storybook/config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { configure } from '@storybook/react'
import React from 'react'
import { configure, addDecorator } from '@storybook/react'
import { setOptions } from '@storybook/addon-options'
import '../modules/primer-css/index.scss'

Expand All @@ -8,6 +9,12 @@ setOptions({
showDownPanel: false,
})

addDecorator(story => (
<div className='p-4'>
{story()}
</div>
))

const contexts = [
require.context('.', true, /\.js$/),
require.context('../modules', true, /stories.*\.js$/),
Expand Down
45 changes: 45 additions & 0 deletions .storybook/lib/storiesFromMarkdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import remark from 'remark'
import parents from 'unist-util-parents'
import select from 'unist-util-select'
import findBefore from 'unist-util-find-before'
import htmlToReact from 'html-to-react'
import parsePairs from 'parse-pairs'

const htmlParser = new htmlToReact.Parser()

const nodeToStory = (node, file) => {
const html = node.value
const element = htmlParser.parse(html)
const pairs = node.lang.replace(/^html\s*/, '')
const attrs = pairs.length ? parsePairs(pairs) : {}
const title = attrs.title || getPreviousHeading(node) ||
`story @ ${file}:${node.position.start.line}`
return {
title,
story: () => element,
attrs,
html,
file,
node,
}
}

const getPreviousHeading = node => {
const heading = findBefore(node.parent, node, 'heading')
return (heading && !heading.used)
? (heading.used = true, heading.children.map(c => c.value).join(''))
: undefined
}

export default req => {
return req.keys().reduce((stories, file) => {
const content = req(file)
const ast = parents(remark.parse(content))
const path = file.replace(/^\.\//, '')
return stories.concat(
select(ast, 'code[lang^=html]')
.map(node => nodeToStory(node, path))
.filter(({attrs}) => attrs.story !== "false")
)
}, [])
}
8 changes: 6 additions & 2 deletions .storybook/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ const modulesPath = path.resolve(__dirname, "../modules")
module.exports = {
module: {
rules: [
{
test: /\.md$/,
use: "raw-loader",
},
{
test: /\.scss$/,
loaders: [
Expand All @@ -28,7 +32,7 @@ module.exports = {
},
],
include: modulesPath,
}
]
},
],
},
}
2 changes: 1 addition & 1 deletion modules/primer-breadcrumb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Breadcrumbs are used to show taxonomical context on pages that are many levels d

#### Usage

```html
```html title="Breadcrumb"
<nav aria-label="Breadcrumb">
<ol>
<li class="breadcrumb-item text-small"><a href="/business">Business</a></li>
Expand Down
19 changes: 7 additions & 12 deletions modules/primer-breadcrumb/stories.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import React from 'react'
import { storiesOf } from '@storybook/react'
import storiesFromMarkdown from '../../.storybook/lib/storiesFromMarkdown'

storiesOf('Breadcrumb', module)
.add('breadcrumb', () => (
<div className='p-4'>
<nav aria-label='Breadcrumb'>
<ol>
<li className='breadcrumb-item text-small'><a href='/business'>Business</a></li>
<li className='breadcrumb-item text-small'><a href='/business/customers'>Customers</a></li>
<li className='breadcrumb-item breadcrumb-item-selected text-small text-gray' aria-current='page'>MailChimp</li>
</ol>
</nav>
</div>
))
const stories = storiesOf('Breadcrumb', module)

storiesFromMarkdown(require.context('.', true, /\.md$/))
.forEach(({title, story}) => {
stories.add(title, story)
})
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,27 @@
"commit-status": "^4.1.0",
"css-loader": "^0.28.4",
"glob": "^7.1.2",
"html-to-react": "^1.2.11",
"lerna": "^2.0.0",
"node-sass": "^4.5.3",
"npm-run-all": "^4.0.2",
"octicons": "^6.0.1",
"parse-pairs": "^0.2.2",
"postcss-loader": "^2.0.6",
"primer-module-build": "^1.0.2",
"raw-loader": "^0.5.1",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-svg-inline": "^2.0.0",
"remark": "^8.0.0",
"sass-loader": "^6.0.6",
"semver": "^5.3.0",
"style-loader": "^0.18.2",
"stylelint": "^7.13.0",
"stylelint-config-primer": "^2.0.0",
"unist-util-find-before": "^2.0.1",
"unist-util-parents": "^1.0.0",
"unist-util-select": "^1.5.0",
"yo": "^2.0.0"
}
}