11import { cloneElement } from 'react'
22import { action } from '@storybook/addon-actions'
3- import { withKnobs , text , boolean , number , object , select } from '@storybook/addon-knobs'
3+ import { text , boolean , number , object , select } from '@storybook/addon-knobs'
44
55const knobResolvers = { }
66export const addKnobResolver = ( { name, resolver, weight = 0 } ) => ( knobResolvers [ name ] = { name, resolver, weight } )
@@ -14,6 +14,11 @@ export const propTypeKnobResolver = (name, knob, ...args) =>
1414 ( propName , propType , value , propTypes , defaultProps ) =>
1515 propType . type . name === name ? knob ( propName , value , ...args ) : undefined
1616
17+ const flowTypeKnobsMap = [
18+ { name : 'signature' , knob : ( name , value ) => value || action ( name ) } ,
19+ { name : 'boolean' , knob : boolean } ,
20+ ]
21+
1722/* eslint-disable no-multi-spaces */
1823// Default simple PropType based knob map.
1924const propTypeKnobsMap = [
@@ -26,34 +31,42 @@ const propTypeKnobsMap = [
2631 { name : 'element' , knob : text } ,
2732]
2833
29- propTypeKnobsMap . forEach ( ( { name, knob, args = [ ] } , weight ) => addKnobResolver ( {
34+ const typeKnobsMap = [ ...flowTypeKnobsMap , ...propTypeKnobsMap ]
35+
36+ typeKnobsMap . forEach ( ( { name, knob, args = [ ] } , weight ) => addKnobResolver ( {
3037 weight : weight * 10 ,
3138 name : `PropTypes.${ name } ` ,
3239 resolver : propTypeKnobResolver ( name , knob , ...args )
3340} ) )
3441
42+ const optionsReducer = ( res , value ) => ( { ...res , [ value ] : value } )
43+ const withDefaultOption = ( options ) => ( { '' : '--' , ...options } )
44+ const createSelect = ( propName , elements , defaultProps ) => {
45+ try {
46+ const options = elements
47+ // Cleanup string quotes, if any.
48+ . map ( value => value . value . replace ( / ^ ' ( .* ) ' $ / , '$1' ) )
49+ . reduce ( optionsReducer , { } )
50+ return select ( propName , withDefaultOption ( options ) , defaultProps [ propName ] )
51+ }
52+ catch ( e ) { }
53+ }
54+
3555// Register 'oneOf' PropType knob resolver.
3656addKnobResolver ( {
3757 name : 'PropTypes.oneOf' ,
3858 resolver : ( propName , propType , value , propTypes , defaultProps ) => {
39- /* eslint-disable quotes */
4059 if ( propType . type . name === 'enum' && propType . type . value . length ) {
41- try {
42- const options = propType . type . value
43- . map ( value => value . value )
44- // Cleanup string quotes, if any.
45- . map ( value => value [ 0 ] === "'" && value [ value . length - 1 ] === "'"
46- ? '"' + value . replace ( / ' " ' / g, '\\"' ) . slice ( 1 , value . length - 1 ) + '"' : value )
47- . map ( JSON . parse )
48- . reduce ( ( res , value ) => ( { ...res , [ value ] : value } ) , { } )
49-
50- return select ( propName , { '' : '--' , ...options } , defaultProps [ propName ] )
51- }
52- catch ( e ) { }
60+ return createSelect ( propName , propType . type . value , defaultProps )
61+ }
62+ // for flow support
63+ if ( propType . type . name === 'union' && propType . type . elements ) {
64+ return createSelect ( propName , propType . type . elements , defaultProps )
5365 }
5466 }
5567} )
5668
69+ const ensureType = ( item ) => item . flowType ? ( { ...item , type : item . flowType } ) : item
5770export const withSmartKnobs = ( story , context ) => {
5871 const component = story ( context )
5972
@@ -68,10 +81,11 @@ export const withSmartKnobs = (story, context) => {
6881 }
6982
7083 const finalProps = props ? Object . keys ( props ) . reduce ( ( acc , n ) => {
71- const item = props [ n ]
84+ const item = ensureType ( props [ n ] )
7285
7386 if ( ! item . type ) {
74- console . warn ( `There is a prop with defaultValue ${ item . defaultValue . value } but it wasnt specified on element.propTypes. Check story: "${ context . kind } ".` )
87+ const defaultValue = item . defaultValue ? item . defaultValue . value : 'Unkwnow'
88+ console . warn ( `There is a prop with defaultValue ${ defaultValue } but it wasnt specified on element.propTypes. Check story: "${ context . kind } ".` )
7589 return acc
7690 }
7791
0 commit comments