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

Can't seem to get Smart Knobs working, no error messages. #24

Open
DylanLyon opened this issue Apr 19, 2018 · 3 comments
Open

Can't seem to get Smart Knobs working, no error messages. #24

DylanLyon opened this issue Apr 19, 2018 · 3 comments

Comments

@DylanLyon
Copy link

Hey all,

I've been configuring Storybook to be our new UI documentation method but I'm running into issues with Smart Knobs. I'm not getting any error messages, I'm just not getting automatically filled out knobs.

I can make my own knobs no problem, but getting them to display automatically is causing some pain. Here's my story file, looks identical to the example story in the readme but maybe I'm just missing something? The component is just a simple slider, nothing crazy about it. The only thing I can think of is that importing PropTypes from 'prop-types' might cause some pain? Apparently it's been moved from 'react' so it should still be the same and work fine. I must just be missing some small config that wasn't mentioned in the readme or something...

import React from 'react';
import { storiesOf, addDecorator } from '@storybook/react';
import PropTypes from 'prop-types';
import SliderBar from '../../imports/ui/components/shoreSlider';
import { withKnobs, text, boolean, number } from '@storybook/addon-knobs';
import { withSmartKnobs } from 'storybook-addon-smart-knobs';

const Slider = ({   resultText, 
                    value, 
                    onChange, 
                    min, 
                    max, 
                    step, 
                    defaultValue, 
                    isDisabled }) => (

                    <SliderBar 
                        resultText={resultText} 
                        value={value} 
                        onChange={onChange} 
                        min={min} 
                        max={max} 
                        step={step} 
                        defaultValue={defaultValue} 
                        isDisabled={isDisabled} 
                    />
                )

Slider.displayName = 'Slider';
Slider.propTypes = {
    resultText: PropTypes.string,
    value: PropTypes.number,
    onChange: PropTypes.func,
    min: PropTypes.number,
    max: PropTypes.number,
    step: PropTypes.number,
    defaultValue: PropTypes.number,
    isDisabled: PropTypes.bool,
};


storiesOf('Slider')
    .addDecorator(withSmartKnobs)
    .addDecorator(withKnobs)
    .add('with knobs', () =>   <Slider  /> );
@jneuendorf
Copy link

jneuendorf commented Jul 31, 2018

I wrote a decorator that works but is of course a bit less powerful. This is an actual (method) decorator because I wanted to wrap the native API a bit to look more class based (see below).
But I should not be difficult to adjust it to your needs, I guess 😉

import PropTypes from "prop-types"

const decorated = decorator => {
    return (prototype_or_class, name, descriptor) => {
        const wrapped_method = descriptor.value
        descriptor.value = decorator(wrapped_method)
        return descriptor
    }
}

const knobByPropType = new Map()
knobByPropType.set(PropTypes.string, text)
knobByPropType.set(PropTypes.number, number)
knobByPropType.set(PropTypes.bool, boolean)
knobByPropType.set(PropTypes.object, object)
knobByPropType.set(PropTypes.node, text)
knobByPropType.set(PropTypes.element, text)
export const auto_knob = decorated(wrapped_method => {
    return function() {
        const element = wrapped_method.call(this)
        const {propTypes={}, defaultProps={}} = element.type
        const props = {}
        for (const [name, type] of Object.entries(propTypes)) {
            const knob = knobByPropType.get(type)
            if (knob) {
                const defaultValue = defaultProps[name]
                props[name] = knob(name, defaultValue)
            }
        }
        return React.cloneElement(
            element,
            {...element.props, ...props},
        )
    }
})

My API

import {action} from "@storybook/addon-actions"
import {withKnobs} from "@storybook/addon-knobs"

new class MyButtonStories extends Story {
    // This is just used for `.addDecorator`
    static addons = [withKnobs]

    @auto_knob
    with_text() {
        return <Button onClick={action("clicked")}>
            Hello Button
        </Button>
    }
}

@bigcheeseh
Copy link

.addDecorator(withSmartKnobs())

@jeffreymeng
Copy link

jeffreymeng commented Mar 8, 2020

To anybody reading this in the future: It looks like you can add the decorator withKnobs without parenthesis fine (though it also works as withKnobs(), so I'm not sure whether that's 'correct' or not), but you must add the smart knobs decorator as withSmartKnobs() (note the parenthesis) to get it to work.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

4 participants