storybook: The view is not re-rendered on toolbar change

Describe the bug I have created a new toolbar button following the steps in the documentation, the button is for localization change, the problem is that the story won’t re-render on globals change.

Expected behavior I expect the page reloads as language is changed as it is in your official storybook

I am using @ngx-translate/core for managing the translations.

export const globalTypes = {
  locale: {
    name: 'Locale',
    description: 'Internationalization locale',
    defaultValue: 'en',
    toolbar: {
      icon: 'globe',
      items: [
        { value: 'en', right: 'en', title: 'English' },
        { value: 'he', right: 'he', title: 'Hebrew' },
      ],
    },
  },
};
const withLocaleProvider = (storyFunc, { globals: { locale } }) => {
  const story = storyFunc();

  story.moduleMetadata.imports.push(
    TranslateModule.forRoot({
      defaultLanguage: locale,
      useDefaultLang: true,
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient],
      },
    })
  );
  return story;
}

export const decorators = [
  withLocaleProvider,
];

System

  System:
    OS: Windows 10 10.0.19041
    CPU: (8) x64 Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz 
  Binaries:
    Node: 12.18.3 - C:\Program Files\nodejs\node.EXE      
    npm: 6.14.6 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 87.0.4280.141
    Edge: Spartan (44.19041.423.0), Chromium (88.0.705.56)
  npmPackages:
    @storybook/addon-actions: ^6.1.15 => 6.1.15 
    @storybook/addon-essentials: ^6.1.15 => 6.1.15        
    @storybook/addon-links: ^6.1.15 => 6.1.15 
    @storybook/angular: ^6.1.15 => 6.1.15 

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 17 (3 by maintainers)

Most upvoted comments

The issue is still present, at least with Vue. The Vue component defined in the decorators array doesn’t receive the updated globals value until a re-render happens some other way like when switching to a different story or the Docs tab.

I noticed the same thing with vue. In the docs tab auto-reload works though.

I moved to using useChannel() to emit the updated value of the toolbar component instead, since the toolbar controls are rendered with React: https://storybook.js.org/docs/react/addons/addons-api#usechannel

And then I’ve created a Vue decorator that listens for this event and re-renders the story accordingly:

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

(story, ctx) => ({
    template: `<template v-if="cssType"><story /></template><template v-else><whatever/></template>`,
    created() {
      this.cssTypeUpdateListener = addons
        .getChannel()
        .addListener(EVENT_CSS_TYPE_UPDATED, ({ cssType: newVal }) => {
          this.cssType = newVal;
        });
    },
    destroyed() {
      addons
        .getChannel()
        .removeListener(EVENT_CSS_TYPE_UPDATED, this.cssTypeUpdateListener);
    },
})

@wes0310 For React you should be able to follow the pattern used by WordPress/Gutenberg here: https://github.com/WordPress/gutenberg/pull/35711/files#diff-493c10b62f2ed6d7c2a9945a55b58043b0f042c6b840f78c2193f8a01b2af613R15

Basically useEffect to watch the global variable, manipulate whatever context you need to, then call forceReRender(). (forceReRender does nothing for Vue but appears to work fine for React)