diff --git a/.storybook/config.js b/.storybook/config.js index 32418d6f97..97c1c24eed 100644 --- a/.storybook/config.js +++ b/.storybook/config.js @@ -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' @@ -8,6 +9,12 @@ setOptions({ showDownPanel: false, }) +addDecorator(story => ( +
+ {story()} +
+)) + const contexts = [ require.context('.', true, /\.js$/), require.context('../modules', true, /stories.*\.js$/), diff --git a/.storybook/lib/storiesFromMarkdown.js b/.storybook/lib/storiesFromMarkdown.js new file mode 100644 index 0000000000..440ddb67f2 --- /dev/null +++ b/.storybook/lib/storiesFromMarkdown.js @@ -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") + ) + }, []) +} diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js index 037ae7908e..29de1c3ad8 100644 --- a/.storybook/webpack.config.js +++ b/.storybook/webpack.config.js @@ -5,6 +5,10 @@ const modulesPath = path.resolve(__dirname, "../modules") module.exports = { module: { rules: [ + { + test: /\.md$/, + use: "raw-loader", + }, { test: /\.scss$/, loaders: [ @@ -28,7 +32,7 @@ module.exports = { }, ], include: modulesPath, - } - ] + }, + ], }, } diff --git a/modules/primer-breadcrumb/README.md b/modules/primer-breadcrumb/README.md index a0c3a0a5d0..640c779ba7 100644 --- a/modules/primer-breadcrumb/README.md +++ b/modules/primer-breadcrumb/README.md @@ -22,7 +22,7 @@ Breadcrumbs are used to show taxonomical context on pages that are many levels d #### Usage -```html +```html title="Breadcrumb"