Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[addon-knobs] Seeing knobs from previously selected story #19

Closed
thany opened this issue Nov 4, 2020 · 15 comments
Closed

[addon-knobs] Seeing knobs from previously selected story #19

thany opened this issue Nov 4, 2020 · 15 comments

Comments

@thany
Copy link

thany commented Nov 4, 2020

Describe the bug
When I select the first story after starting storybook, I see its knobs just fine. Then when I select another story, its knobs are added to the knobs that were there from the previously selected knobs.

Worse even, if the previously selected story had knobs in categories (tabs), the non-categorized knobs from the newly selected story are now tucked away in a "Other" tab.

To Reproduce
Upgrading/migrating from storybook 5.3 to 6.0, I suppose. That's the only thing that happened that made this break. I am already using the knobs preset in main.js, rather than its "register" notation in addons.js. And of course, everything is at the same 6.0.28 version.

Expected behavior
Knobs panel should only ever display knobs from the currently selected story.

Screenshots
image
1 - These are from the previously selected story and do not belong here. They never go away, even after having selected a docs-only story where the side panel goes away entirely.
2 - This is from the currently selected story, and should not be a tab. The currently selected does not have its knobs in categories, so I expect no tabs at all.

Code snippets
Relevant part of main.js:

module.exports = {
  stories: ['../../src/**/*.stories.@(jsx|mdx)'],
  addons: [
    '@storybook/addon-options',
    '@storybook/addon-knobs',
    '@storybook/addon-a11y',
    '@storybook/addon-docs',
  ]
};

Relevant part of manager.js:

import { addons } from '@storybook/addons';

// Option defaults:
addons.setConfig({
  name: 'Mijn Enexis',
  showNav: true,
  showPanel: true,
  panelPosition: 'right',
});

I don't know what else. There's no reference to knobs in preview.jsx, nor in theme.js.

System
Results of npx sb@next info:

  System:
    OS: Windows 10 10.0.19041
    CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
  Binaries:
    Node: 12.19.0 - C:\Program Files\nodejs\node.EXE
    npm: 6.14.8 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 86.0.4240.183
    Edge: Spartan (44.19041.423.0)
  npmPackages:
    @storybook/addon-a11y: 6.0.28 => 6.0.28
    @storybook/addon-actions: 6.0.28 => 6.0.28
    @storybook/addon-docs: 6.0.28 => 6.0.28
    @storybook/addon-knobs: 6.0.28 => 6.0.28
    @storybook/react: 6.0.28 => 6.0.28
    @storybook/theming: 6.0.28 => 6.0.28

It doesn't see my actual browser, Firefox 82.

@thany
Copy link
Author

thany commented Nov 4, 2020

Okay I did find that npx sb upgrade doesn't fully/correctly perform the upgrade, as a lot of 5.3-packages remained in my package-lock.json. I performed a npm update and those all went away. So now everything is definitely at 6.0.28. The addon-options package doesn't exist anymore, so I deleted that from main.js as well.

And the result: still not fixed 😥

@shilman
Copy link
Member

shilman commented Nov 4, 2020

Please try addon-controls in Storybook 6.0. Controls are portable, auto-generated knobs that are intended to replace addon-knobs long term.

@thany
Copy link
Author

thany commented Nov 4, 2020

I know, but addon-controls requires a HUGE amount of refactoring, and tbh the syntax doesn't quite make a lot of sense to me yet. I think the documentation needs more love. Anyhow, I want to keep using addon-knobs for now, and migrate to addon-controls at a later stage. The upgrade itself is already big enough as it is.

On top of that, since addon-knobs was upgraded to 6.0 as well, I'd expect it to at least work correctly. Even if it's deprecated.

In the mean time I've got a workaround. In main.js:

module.exports = {
  stories: ['../../src/**/*.stories.@(jsx|mdx)'],
  addons: [
    '@storybook/addon-knobs/register',
    '@storybook/addon-a11y',
    '@storybook/addon-docs',
  ],
};

So, using the register-behaviour instead of the preset. And then in my preview.jsx, I've re-added:

import { withKnobs } from '@storybook/addon-knobs';

// Some other guff here

export const decorators = [
  // Some others
  withKnobs,
  // Some others more
];

Works great now. But the question is, why is the preset now working?

@shilman
Copy link
Member

shilman commented Nov 4, 2020

@thany that comment was as much for anybody else who stumbles onto this issue as it was for you. we're all in addon-controls with stabilizations in 6.1 and a bunch of new features coming in 6.2.

@thany
Copy link
Author

thany commented Nov 4, 2020

Alright, fair enough. So, should I keep using the register-behaviour or should we try and find the actual cause of why the preset-behaviour is causing this weird behaviour where knobs are sort of persisted?

/edit
Oh, I can reproduce this problem by placing the withKnobs decorator at the very start of the decorators export.

/edit2
When I place the withKnobs decorator before (as opposed to after) our withTracking decorator, it breaks. The decorator looks like this (removed stuff that doesn't matter):

import React, { Fragment } from 'react';
import track from 'react-tracking';

const withTracking = storyFunc => {
  const TrackedStoryWrapper = track({ event: 'event' }, {
    dispatch: data => {
      console.log('%cTracking event', 'color:#1ea7fd;font-style:italic', data);
    },
  })(storyFunc);

  return (
    <Fragment>
      <TrackedStoryWrapper />
    </Fragment>
  );
};

export default withTracking;

It seems to be the track decorator from react-tracking that magically breaks knobs. This doesn't make very much sense to me right now. Apparently the track decorator does... something, that isn't compatible with Storybook 6, but worked fine in 5.3.

@stale
Copy link

stale bot commented Dec 25, 2020

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!

@shilman shilman transferred this issue from storybookjs/storybook May 10, 2021
@thany
Copy link
Author

thany commented Jul 27, 2021

The workaround (to specifiy @storybook/addon-knobs/register instead of @storybook/addon-knobs) no longer works. And of course the problem is back. I thought it worked, but it doesn't.

On top of that, changing the value in a knob has no effect on the story that uses it.

@shilman Would you happen to know another trick to get knobs to work again?

@rohanrp
Copy link

rohanrp commented Dec 9, 2021

As a temporary fix, you can run some code in an interval to reset the knobs every time a new story has changed. In the below code, all I am doing is waiting for the URL query string 'path' to change and once it does, it will reset the knobs to its original state. This seems to fix the problem.

in your main.js ensure that knobs is your first add-on tab

addons: [
    '@storybook/addon-knobs',
      ...
]

In your preview.js, add this code to the bottom of the file

let currentPath
if (window.parent) {
  const parentWindow = window.parent
  parentWindow.setInterval(function(){
    const urlParams = new URLSearchParams(parentWindow.location.search);
    const path = urlParams.get('path');
    if (path && path !== currentPath) {
      currentPath = path
      
      const knobButtons = parentWindow.document.querySelectorAll('#panel-tab-content button')
      if (knobButtons) {
        const resetButton = knobButtons[knobButtons.length - 1]
        resetButton.click()
      }

    }
  }, 100);
}

@luispied
Copy link

As a temporary fix, you can run some code in an interval to reset the knobs every time a new story has changed. In the below code, all I am doing is waiting for the URL query string 'path' to change and once it does, it will reset the knobs to its original state. This seems to fix the problem.

in your main.js ensure that knobs is your first add-on tab

addons: [
    '@storybook/addon-knobs',
      ...
]

In your preview.js, add this code to the bottom of the file

let currentPath
if (window.parent) {
  const parentWindow = window.parent
  parentWindow.setInterval(function(){
    const urlParams = new URLSearchParams(parentWindow.location.search);
    const path = urlParams.get('path');
    if (path && path !== currentPath) {
      currentPath = path
      
      const knobButtons = parentWindow.document.querySelectorAll('#panel-tab-content button')
      if (knobButtons) {
        const resetButton = knobButtons[knobButtons.length - 1]
        resetButton.click()
      }

    }
  }, 100);
}

Awesome workaround, works very good for me.
In my case it also has a delay in the number of Knobs displayed in the label, so I added a simple overwrite to the text.

const knobLabel = parentWindow.document.querySelector('[id*="tabbutton-knobs-"]',);
knobLabel.textContent = 'Knobs'; 

@mgameover
Copy link

Hi everyone, I've created PR with the fix.
In two words, disconnectCallbacks is invoked before STORY_CHANGED event has been emitted. As the result the knobs are not being reset.
@shilman , Could you please take a look and merge?

@luispied
Copy link

Hi everyone, I've created PR with the fix. In two words, disconnectCallbacks is invoked before STORY_CHANGED event has been emitted. As the result the knobs are not being reset. @shilman , Could you please take a look and merge?

Works for me the fix!! thanks @mgameover
I just only have an issue with the amount of knobs displayed when change to a new component, did you realized about it? Tooks the amount of the previous visited component.

@mgameover
Copy link

I haven't got a chance to take a look at those numbers, but I'll try to take a look at that.

That PR is fixing just one issue - "adding knobs from other stories".
In my case, original knobs were overridden by previous story and it broke the entire story. I've found out that in v6.4 it doesn't reset knobs on storychange event.

@YaronMiro
Copy link

I also encountered this bug when knobs are not cleared between stories, if using the @storybook/react up to version 6.3.13 it works as expected but higher versions are not. At least there is a possibility to upgrade from version 5 to 6 but not the latest version 6.x if intending to use knobs.

@Shelagh-Lewins
Copy link

I had an issue with knobs for the wrong component (always the same wrong component) being shown on first load, which takes longer to render than switching between components. I modified @rohanrp's solution slightly to allow longer on the first render, and to check for length of the array to avoid console error.

let currentPath;
let timeout = 600;

if (window.parent) {
  const parentWindow = window.parent;
  parentWindow.setInterval(function () {
    const urlParams = new URLSearchParams(parentWindow.location.search);
    const path = urlParams.get('path');
    timeout = 150;

    if (path && path !== currentPath) {
      currentPath = path;

      const knobButtons = parentWindow.document.querySelectorAll(
        '#panel-tab-content button',
      );

      if (knobButtons.length) {
        const resetButton = knobButtons[knobButtons.length - 1];
        resetButton.click();
      }
    }
  }, timeout);
}

@literalpie
Copy link
Collaborator

#45 was merged with the fix for this. It is included in the 7.0.2 release

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

No branches or pull requests

8 participants