Skip to content
This repository has been archived by the owner on Jan 5, 2023. It is now read-only.

feat/ignore-props #65

Merged
merged 4 commits into from
Oct 24, 2019
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
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,24 @@ Button.propTypes = {
}

storiesOf('Button')
.addDecorator(withSmartKnobs)
.addDecorator(withSmartKnobs(options))
.addDecorator(withKnobs)
.add('simple', () => <Button>Smart knobed button</Button>)

```

## Options

- **ignoreProps**

Type: `Array`

Will not automatically create knobs for props whose name is in this array. Example:
```js
.withSmartKnobs({ ignoreProps: ['numberProp'] })
.add('example', () => <div numberProp={date('date', date)} />)
```

## Configuration:

This plugin has a peer dependency on [babel-plugin-react-docgen
Expand Down
15 changes: 10 additions & 5 deletions example/stories/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import { storiesOf } from '@storybook/react'
import { withSmartKnobs } from '../../src'
import { withKnobs, select } from '@storybook/addon-knobs'
import { withKnobs, select, date } from '@storybook/addon-knobs'
import { withInfo } from '@storybook/addon-info'

import SmartKnobedComponent from './SmartKnobedComponent'
Expand All @@ -11,7 +11,7 @@ import SmartKnobedComponentWithFlow from './SmartKnobedComponentWithFlow'
const stub = fn => fn()

storiesOf('Basic', module)
.addDecorator(withSmartKnobs)
.addDecorator(withSmartKnobs())
.addDecorator(withKnobs)
.add('proptypes', () => <SmartKnobedComponent />)
.add('flow', () => <SmartKnobedComponentWithFlow />)
Expand All @@ -23,22 +23,27 @@ storiesOf('Basic', module)
))

storiesOf('withInfo', module)
.addDecorator(withSmartKnobs)
.addDecorator(withSmartKnobs())
.addDecorator(withKnobs)
.addDecorator(withInfo)
.add('proptypes', () => <SmartKnobedComponent />)

storiesOf('Missing props', module)
.addDecorator(withSmartKnobs)
.addDecorator(withSmartKnobs())
.addDecorator(withKnobs)
.add('example', () => (
<SmartKnobedComponentMissingProps foo='baz' />
))

storiesOf('Manual knobs', module)
.addDecorator(stub)
.addDecorator(withSmartKnobs)
.addDecorator(withSmartKnobs())
.addDecorator(withKnobs)
.add('example', () => (
<SmartKnobedComponent string={ select('string', ['1', '2', '3'], '2') } />
))

storiesOf('Ignore Props', module)
.addDecorator(withSmartKnobs({ ignoreProps: ['number'] }))
.addDecorator(withKnobs)
.add('proptypes', () => <SmartKnobedComponent number={ date('date', new Date()) } />)
19 changes: 12 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ addKnobResolver({

const ensureType = (item) => item.flowType ? ({ ...item, type: item.flowType }) : item

const getNewProps = (target, context) => {
const getNewProps = (target, context, opts) => {
const { __docgenInfo: { props } = { props: {} } } = target.type
const { ignoreProps = [] } = opts
const defaultProps = {
...(target.type.defaultProps || {}),
...target.props
Expand All @@ -81,6 +82,10 @@ const getNewProps = (target, context) => {
const finalProps = props ? Object.keys(props).reduce((acc, n) => {
const item = ensureType(props[n])

if (ignoreProps.includes(n)) {
return acc
}

if (!item.type) {
const defaultValue = item.defaultValue ? item.defaultValue.value : 'Unknown'
logger.warn(`There is a prop with defaultValue ${defaultValue} but it wasn't specified on element.propTypes. Check story: "${context.kind}".`)
Expand All @@ -96,30 +101,30 @@ const getNewProps = (target, context) => {
return resolvePropValues(finalProps, defaultProps)
}

const mutateChildren = (component) => {
const mutateChildren = (component, context, opts) => {
return cloneElement(component, { children: Children.map(component.props.children, (child) => {
if (child.type && child.type.__docgenInfo) {
const newProps = getNewProps(child)
const newProps = getNewProps(child, context, opts)

return cloneElement(child, { ...child.props, ...newProps })
}

if (child.props && child.props.children) {
return mutateChildren(child)
return mutateChildren(child, context, opts)
}

return child
}) })
}

export const withSmartKnobs = (story, context) => {
export const withSmartKnobs = (opts = {}) => (story, context) => {
const component = story(context)

if (!component.type.__docgenInfo && component.props.children) {
return mutateChildren(component)
return mutateChildren(component, context, opts)
}

const newProps = getNewProps(component, context)
const newProps = getNewProps(component, context, opts)

return cloneElement(component, newProps)
}
Expand Down