Skip to content

Commit

Permalink
Update storybook metadata creation to support Knobs in docs app (#48)
Browse files Browse the repository at this point in the history
* Update storybook metadata creation to support Knobs in docs app

* Adding additional stories

* Version bump

* Add github token to action
  • Loading branch information
kevhender authored Feb 27, 2020
1 parent 138eefe commit 000477a
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 8 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ jobs:
git config --local user.name "GitHub Action"
git commit -m "Docs for version ${VERSION}" -a
git push -u origin
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57 changes: 54 additions & 3 deletions .storybook/createMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,53 @@ const readdir = promisify(fs.readdir)
const STORIES_PATH = path.join(__dirname, 'stories')
const METADATA_FILEPATH = path.join(__dirname, 'build/stories.json')

// currently supported knob types:
const KNOB_FUNCS = ['text', 'select', 'boolean', 'number']
const knobHasOptions = funcName => ['select'].includes(funcName)

function generateKnobs(componentName, storyName, src) {
const knobArray = []
const fragmentRegex = new RegExp(
`export const ${storyName}[\\s\\S]*(<${componentName}[\\s\\S]*>)`,
)
const srcFragment = (src.match(fragmentRegex) || [])[1] || ''
// weird bug where component with no attributes doesn't match right; ignore it since it has no knobs
if (srcFragment.startsWith(`<${componentName}>`)) {
return knobArray
}
KNOB_FUNCS.forEach(knobFunc => {
const knobRegexString = `\\s(.*?)={${knobFunc}\\(([\\s\\S]*?)\\)}`
const knobMatches = srcFragment.match(new RegExp(knobRegexString, 'gm'))
if (knobMatches) {
knobMatches.forEach(matchStr => {
const knobValue = eval(`[${matchStr.match(new RegExp(knobRegexString, 'm'))[2]}]`)
knobArray.push({
label: knobValue[0],
defaultValue: knobValue[knobHasOptions(knobFunc) ? 2 : 1],
type: knobFunc,
options: knobHasOptions(knobFunc) ? knobValue[1] : undefined,
})
})
}
})
return knobArray
}

/**
* Creates a JSON file containing all the storybook stories that are available in this format:
* {
* ComponentName: ['story1', 'story2']
* ComponentName: [
* {
* name: 'story1',
* knobs: [
* {
* label: 'Label',
* type: 'text',
* defaultValue: 'defaultValue'
* }
* ]
* }
* ]
* }
*/
const main = async () => {
Expand All @@ -21,9 +64,17 @@ const main = async () => {
const stories = {}

dirContents.forEach(async file => {
const contents = require(path.join(STORIES_PATH, file))
const filepath = path.join(STORIES_PATH, file)
const contents = require(filepath)
const src = fs.readFileSync(filepath, 'utf8')
if (contents.default) {
stories[contents.default.title] = Object.keys(contents).filter(key => key !== 'default')
const componentName = contents.default.title
stories[componentName] = Object.keys(contents)
.filter(key => key !== 'default')
.map(storyName => ({
name: storyName,
knobs: generateKnobs(componentName, storyName, src),
}))
}
})

Expand Down
2 changes: 1 addition & 1 deletion .storybook/stories/ActionButton.stories.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { withKnobs, text, boolean, number } from '@storybook/addon-knobs'
import { withKnobs, text } from '@storybook/addon-knobs'
import ActionButton from '../../src/ActionButton'

export default { title: 'ActionButton', decorators: [withKnobs] }
Expand Down
37 changes: 37 additions & 0 deletions .storybook/stories/Drawer.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'

import { withKnobs, text, boolean, select } from '@storybook/addon-knobs'
import Drawer from '../../src/drawer/Drawer'

export default { title: 'Drawer', decorators: [withKnobs] }

export const defaults = () => (
<>
<div>Use the knobs to open the drawer.</div>
<div>Knobs can be adjusted when the drawer is closed.</div>
<Drawer
open={boolean('Open', false)}
fullscreen={boolean('Fullscreen', true)}
anchor={select(
'Anchor',
{ Top: 'top', Bottom: 'bottom', Left: 'left', Right: 'right' },
'bottom',
)}
title={text('Title', 'Example Drawer')}
showCloseButton={boolean('Close Button', true)}
>
<div
style={{
height: 200,
margin: 50,
backgroundColor: 'silver',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
These are the drawer contents
</div>
</Drawer>
</>
)
20 changes: 20 additions & 0 deletions .storybook/stories/LoadMask.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'

import { withKnobs, boolean, select } from '@storybook/addon-knobs'
import LoadMask from '../../src/LoadMask'

export default { title: 'LoadMask', decorators: [withKnobs] }

export const defaults = () => (
<div>
<LoadMask
show={boolean('Show', true)}
transparent={boolean('Transparent', true)}
align={select('Align', { Center: 'center', Top: 'top' }, 'center')}
/>
<div style={{ padding: 30 }}>This content is being masked.</div>
<div style={{ padding: 30, backgroundColor: 'steelblue', color: 'white' }}>
This content is also being masked.
</div>
</div>
)
40 changes: 40 additions & 0 deletions .storybook/stories/ResponsiveTiles.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react'
import ResponsiveTiles from '../../src/ResponsiveTiles'

export default { title: 'ResponsiveTiles' }

const data = [
{ color: 'red', textColor: 'white', label: 'Tile 1' },
{ color: 'black', textColor: 'white', label: 'Tile 2' },
{ color: 'blue', textColor: 'white', label: 'Tile 3' },
{ color: 'skyblue', textColor: 'black', label: 'Tile 4' },
{ color: 'purple', textColor: 'white', label: 'Tile 5' },
{ color: 'yellow', textColor: 'black', label: 'Tile 6' },
{ color: 'gray', textColor: 'white', label: 'Tile 7' },
{ color: 'lime', textColor: 'black', label: 'Tile 8' },
{ color: 'pink', textColor: 'black', label: 'Tile 9' },
{ color: 'aquamarine', textColor: 'black', label: 'Tile 10' },
{ color: 'orange', textColor: 'black', label: 'Tile 11' },
{ color: 'indigo', textColor: 'white', label: 'Tile 12' },
]

export const defaults = () => (
<ResponsiveTiles>
{data.map(item => (
<div
key={item.label}
style={{
height: 150,
backgroundColor: item.color,
color: item.textColor,
display: 'flex',
fontFamily: 'Arial',
justifyContent: 'center',
alignItems: 'center',
}}
>
{item.label}
</div>
))}
</ResponsiveTiles>
)
16 changes: 16 additions & 0 deletions .storybook/stories/TabPanel.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react'

import { withKnobs, boolean } from '@storybook/addon-knobs'
import TabPanel from '../../src/TabPanel'

export default { title: 'TabPanel', decorators: [withKnobs] }

export const defaults = () => (
<TabPanel scrollable={boolean('Scrollable', true)}>
<div label="First Tab">Contents of the first tab</div>
<div label="Second Tab">Contents of the second tab</div>
<div label="Third Tab">Contents of the third tab</div>
<div label="Fourth Tab">Contents of the fourth tab</div>
<div label="Fifth Tab">Contents of the fifth tab</div>
</TabPanel>
)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-storefront",
"version": "7.5.0",
"version": "7.6.0",
"description": "Build and deploy e-commerce progressive web apps (PWAs) in record time.",
"module": "./index.js",
"license": "Apache-2.0",
Expand Down
2 changes: 1 addition & 1 deletion src/AppBar.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useContext } from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { AppBar as MUIAppBar, Container, Toolbar, useScrollTrigger, Slide } from '@material-ui/core'
import { AppBar as MUIAppBar, Toolbar, useScrollTrigger, Slide } from '@material-ui/core'
import PropTypes from 'prop-types'
import PWAContext from './PWAContext'

Expand Down
2 changes: 1 addition & 1 deletion src/ForwardThumbnail.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PWAContext from './PWAContext'

/**
* Wrap product links in this component to reuse the thumbnail as the main image in the product
* skeleton when transitioning to the PDP to make the transition feel instance. This component
* skeleton when transitioning to the PDP to make the transition feel instant. This component
* sets the `thumbnail` ref on the provided `PWAContext` to the `src` prop of the first `img`
* element found amongst the descendant elements in the tree.
*
Expand Down
2 changes: 1 addition & 1 deletion src/TabPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const styles = theme => ({
export const useStyles = makeStyles(styles, { name: 'RSFTabPanel' })

/**
* A simple tab panel that is AMP-compatible. Tab names are pull from the label prop of the child elements.
* A simple tab panel that is AMP-compatible. Tab names are pulled from the label prop of the child elements.
* Any type of element can be a child.
*
* Example:
Expand Down

0 comments on commit 000477a

Please sign in to comment.