Storybook: Knobs disappear

Created on 1 Dec 2017  路  14Comments  路  Source: storybookjs/storybook

awesomescreenshot-2017-12-01t00-14-52-244z

knobs bug inactive question / support

Most helpful comment

For me, I stumbled upon another fix for this issue. I still have withKnobs defined globally in my storybook config, but then in my Divider.stories.js file, I found that I could not reference the functions when they were stored in a variable. I had to include it directly.

I was trying to do this (as the docs advise you to do), which was not working:

const valueWidth = number(labelWidth, defaultValueWidth, optionsWidth)

stories.add('Default Divider', () => (
    <Divider
        width={valueWidth}
    />
))

and it would disappear. When I switched it from the reference to using the function directly, it worked no problem:

stories.add('Default Divider', () => (
    <Divider
        width={number(labelWidth, defaultValueWidth, optionsWidth)}
    />
))

Hope this helps someone.

All 14 comments

Got the same issue with storybook/[email protected]

@powermikee I have the same issue, but only when my knobs are added through addDecorator or imported from other file. Is it the same in your case?

I also noticed, that they appear again for a split of second during resizing of the panel.

I noticed exactly the same behavior shortly after I tried adding a light/dark theme knob globally in .storybook.

StorybookStyleDecorator.js

import React, { Component } from 'react'
const classes = require('../src/ui/styles/core.scss')
import { select, withKnobs } from '@storybook/addon-knobs'

const StorybookGlobalDecoratorComponent = (storyFn, context) => {
  const storyWithKnobs = withKnobs(storyFn, context)
  const theme = select('Theme', { dark: 'dark', light: 'light' }, 'light')
  const themeClass = theme === 'dark' ? classes.dark : classes.light
  return (
    <div className={themeClass} style={{ height: '100%', margin: 0 }} id="storybookRoot">
      {storyWithKnobs}
    </div>
  )
}

export default StorybookGlobalDecoratorComponent

config.js

import { configure, addDecorator } from '@storybook/react'
import StorybookStyleDecorator from './GlobalStorybookDecorator.component'

const req = require.context('../src', true, /.stories.tsx$/)
function loadStories() {
  req
    .keys()
    .sort()
    .forEach(req)
}

addDecorator(StorybookStyleDecorator)
configure(loadStories, module)

I was able to fix it by combining the two files into one and calling const content = story() immediately.

import { configure, addDecorator } from '@storybook/react'
import StorybookStyleDecorator from './GlobalStorybookDecorator.component'
import { withKnobs, select } from '@storybook/addon-knobs'
import React, { Component } from 'react'
const classes = require('../src/ui/styles/core.scss')
const req = require.context('../src', true, /.stories.tsx$/)
function loadStories() {
  req
    .keys()
    .sort()
    .forEach(req)
}

// addDecorator(StorybookStyleDecorator)
addDecorator(story => {
  const content = story() // call story early so knob store is created before `select` call
  const theme = select('Theme', { dark: 'dark', light: 'light' }, 'dark')
  const themeClass = theme === 'dark' ? classes.dark : classes.light
  return (
    <div className={themeClass} style={{ height: '100%', margin: 0 }} id="storybookRoot">
      {content}
    </div>
  )
})
addDecorator(withKnobs) // add withKnobs

configure(loadStories, module)

This was inspired by an earlier version of Storybook's solution for global knobs:
https://github.com/storybook-eol/storybook-addon-knobs/issues/31#issuecomment-247878576

@powermikee @andest01 @jalooc @ralzinov is this still happening with the latest alpha. Some time ago I did a big refactor that fixed a bunch of weird issues, please let me know if this is happening

@alterx Just gave it a shot with the latest alpha, still happening. Defining knobs in decorators would be a really powerful feature when working with themes, etc.

Edit: I can't get it working with @andest01's workaround either. @andest01 - what version are you on?

Edit (2): Actually, I can get this working without the workaround (on the latest stable version), as long as the withKnobs decorator is added after my decorator. It might be worth adding a section on "global knobs" to the README?

The problem with defining "global" knobs, if I'm understanding this correctly is that this would have to be applied as yet another wrapper component that we need to keep around when switching stories. This is something that needs some thought, specially on angular and similar frameworks (not react o preact).

I suspect this global behavior could be happening with all the apps and Knobs (not only Angular). Do you have a working repo in which we can replicate the issue?

Happening to me as well, only when defining globally.

Edit:

Ok, so the solution I found was actually opposite of what @angusfretwell found, interestingly enough. What worked for me was adding the withKnobs decorator first, and then creating a function for fetching values.

config.js
addDecorator(withKnobs)

index.stories.js

const getStyle = () => object('stories', {
  backgroundColor: 'red'
})

storiesOf('Button', module)
  .add('with red bg', () => (
    <Button style={getStyle()} onClick={action('clicked')}>Hello Button</Button>
  ));

For me, I stumbled upon another fix for this issue. I still have withKnobs defined globally in my storybook config, but then in my Divider.stories.js file, I found that I could not reference the functions when they were stored in a variable. I had to include it directly.

I was trying to do this (as the docs advise you to do), which was not working:

const valueWidth = number(labelWidth, defaultValueWidth, optionsWidth)

stories.add('Default Divider', () => (
    <Divider
        width={valueWidth}
    />
))

and it would disappear. When I switched it from the reference to using the function directly, it worked no problem:

stories.add('Default Divider', () => (
    <Divider
        width={number(labelWidth, defaultValueWidth, optionsWidth)}
    />
))

Hope this helps someone.

@camsloanftc trick did the trick.

Any news on a more structured solution?

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

We use something like this in our project:

const BasicComponent = (props = {}) => {
  const defaultProps = {
    // some props...
    label: text('label', 'Default label'),
    value: number('value', 0), 

    ...props // Override defaults if needed,
  }; 

  return <Component {...defaultProps} />;
}

storiesOf('Component', module)
  .add('Default', () => <BaseComponent />)
  .add('With overridden defaults', () => <BaseComponent someProp={value} />);

Basically, just avoid having file-scoped knobs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexanbj picture alexanbj  路  3Comments

purplecones picture purplecones  路  3Comments

arunoda picture arunoda  路  3Comments

shilman picture shilman  路  3Comments

miljan-aleksic picture miljan-aleksic  路  3Comments