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

Stories that return a DOM element don't update when knobs change #5017

Closed
andyearnshaw opened this issue Dec 17, 2018 · 9 comments · Fixed by #6783
Closed

Stories that return a DOM element don't update when knobs change #5017

andyearnshaw opened this issue Dec 17, 2018 · 9 comments · Fixed by #6783

Comments

@andyearnshaw
Copy link

Describe the bug
When you adjust knobs, stories don't update when they return a DOM element but they do when you return a HTML string. The story code is executed but is discarded due to a forceRender variable that is always true, possibly introduced in this commit.

To Reproduce
Use the following JS for a story:

import { storiesOf } from '@storybook/html';
import { withKnobs, text } from '@storybook/addon-knobs';

storiesOf('TestComponent', module)
  .addDecorator(withKnobs)
  .add('html', () =>  {
    let message = text('Heading', 'Hello World');
    return `<h1>${ message }</h1>`;
  })
  .add('dom', () => {
    let h1 = document.createElement('h1');
    h1.textContent = text('Heading', 'Hello World');

    return h1;
  });

Expected behavior
As you change the "Heading" knob, the stories should re-render. In reality, only the one that returns the HTML string does.

System:

  • OS: macOS
  • Browser: all
  • Framework: none
  • Addons: knobs
  • Version: 4.1.1
@igor-dv
Copy link
Member

igor-dv commented Dec 29, 2018

@Atekon, didn't you get thing problem as well?

@stale
Copy link

stale bot commented Jan 20, 2019

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!

@stale stale bot added the inactive label Jan 20, 2019
@cdutson
Copy link

cdutson commented Jan 24, 2019

Hi there! I'm actually running into this issue right now. I'm trying to build up a doc library for a web component-based component library at my workplace. I've started by generating kitchen sink stories for all of the components, and dynamically creating the knobs for the components based on the props of each component.

This works great, except that it's not re-rendering if a dom element is returned. It does if I return a string (el.outerHTML) but this isn't ideal since I'm not just setting html atributes on all of these components. some are JS-based props. SO I need to return the dom element.

Kind of stuck in a weird place here. I could probably switch over to react and just export fragments, but that seems like an ugly workaround.

I'm happy to provide further details, sample code, etc as needed

System
OS: Windows
Browser: only chrome tested thus far
Framework: none
Addons: knobs
Version: 4.1.9

Further edit:
I removed the forceRender check that @andyearnshaw pointed out in the aforementioned commit. Removing that check fixed the issue I was running into. I am sure it was added for a good reason, but I think either we need to have some way of specifying that this story is 'live' or some other integration with knobs.

@stale stale bot removed the inactive label Jan 24, 2019
@stale
Copy link

stale bot commented Feb 14, 2019

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!

@stale stale bot added the inactive label Feb 14, 2019
@Nightbr
Copy link

Nightbr commented Mar 7, 2019

Hey, same bug here with Web Components (build with Stenciljs):

import { storiesOf } from '@storybook/html';
import { withReadme } from 'storybook-readme';
import README from './readme.md';
import { withKnobs, text, number } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';

const percentageRange = {
  range: true,
  min: 0,
  max: 100,
  step: 1
};

storiesOf('Components/MyComponent', module)
  .addDecorator(withReadme(README))
  .addDecorator(withKnobs)
  .add('With Input', () => {
    const el = document.createElement('my-component');
    const value = number('Percentage', 50, percentageRange);
    console.log(value);
    el.value = value;
    el.test = text('test', 'John');
    el.addEventListener('myComponentClicked', e => {
      action('myComponentClicked')(e.detail);
      el.test = 'plop';
    });
    return el;
  })
storiesOf('Components/MyComponent', module)
  .addDecorator(withReadme(README))
  .addDecorator(withKnobs)
  .add('dom', () => {
    const el = document.createElement('my-component');
    const value = number('Percentage', 50, percentageRange);
    console.log(value);
    el.value = value;
    el.test = text('test', 'John');
    el.addEventListener('myComponentClicked', e => {
      action('myComponentClicked')(e.detail);
      el.test = 'plop';
    });
    return el;
  })
  .add('html', () => {
    let value = number('Percentage', 50, percentageRange);
    let test = text('test', 'John');
    return `<my-component test=${test} value=${value}></my-component>`;
  });

The stories is not rerendered :/ I will try to return and HTML string to see if it is rerendered.

EDIT: dom -> not rerendered (not working), html -> rerendered as expected (working).

@dwightjack
Copy link
Contributor

Hi,

just to add a note I'm experiencing the same issue with version 5.0.1. As @andyearnshaw pointed out the problem looks like to be this check.

@shilman
Copy link
Member

shilman commented Mar 26, 2019

Jeepers creepers!! I just released https://github.com/storybooks/storybook/releases/tag/v5.1.0-alpha.15 containing PR #6190 that references this issue. Upgrade today to try it out!

Because it's a pre-release you can find it on the @next NPM tag.

Closing this issue. Please re-open if you think there's still more to do.

@mightyhorst
Copy link

@Nightbr
The only workaround I found was adding the element to the global scope, rather than the story.add scope:

e.g.

/* move to here */ const el = document.createElement('my-component');

storiesOf('Components/MyComponent', module)
  .addDecorator(withReadme(README))
  .addDecorator(withKnobs)
  .add('With Input', () => {
    /* move from here ---> const el = document.createElement('my-component'); */
    // .... ect ect 
    el.test = text('test', 'John');
  })

@mightyhorst
Copy link

mightyhorst commented May 18, 2019

Describe the bug
When you adjust knobs, stories don't update when they return a DOM element but they do when you return a HTML string. The story code is executed but is discarded due to a forceRender variable that is always true, possibly introduced in this commit.

To Reproduce
Use the following JS for a story:

import { storiesOf } from '@storybook/html';
import { withKnobs, text } from '@storybook/addon-knobs';

storiesOf('TestComponent', module)
  .addDecorator(withKnobs)
  .add('html', () =>  {
    let message = text('Heading', 'Hello World');
    return `<h1>${ message }</h1>`;
  })
  .add('dom', () => {
    let h1 = document.createElement('h1');
    h1.textContent = text('Heading', 'Hello World');

    return h1;
  });

Expected behavior
As you change the "Heading" knob, the stories should re-render. In reality, only the one that returns the HTML string does.

System:

  • OS: macOS
  • Browser: all
  • Framework: none
  • Addons: knobs
  • Version: 4.1.1
    @andyearnshaw

Try add the element to the global scope

import { storiesOf } from '@storybook/html';
import { withKnobs, text } from '@storybook/addon-knobs';

/* move here */ let h1 = document.createElement('h1');

storiesOf('TestComponent', module)
  .addDecorator(withKnobs)
  .add('dom', () => {
    /* was here  --->  let h1 = document.createElement('h1'); */
    h1.textContent = text('Heading', 'Hello World');

    return h1;
  });

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

Successfully merging a pull request may close this issue.

7 participants