hipstersmoothie / storybook-dark-mode

A storybook addon that lets your users toggle between dark and light mode.
MIT License
429 stars 56 forks source link

Storybook v7 "getChannel" is not a function #205

Open sneko opened 1 year ago

sneko commented 1 year ago

Hi,

I just upgraded to the beta of Storybook v7 and I get:

TypeError: __STORYBOOK_MODULE_ADDONS__.getChannel is not a function
    at http://localhost:6006/.storybook/preview.jsx?t=1671442444705:12:45

I did not see any indication something would break about this, it was working as intended under v6.

Anyone succeeded in making it working with v7?

Thank you,

EDIT: I simply use the follwing in my preview.jsx:

import addons from '@storybook/addons';
const channel = addons.getChannel();
sneko commented 1 year ago

@hipstersmoothie interested to know if you tried the v7 beta yet?

Thank you,

hobadams commented 1 year ago

I'd love to use this plugin with Storybook 7 beta too. Thanks in advance if you have time to get it working :-)

hipstersmoothie commented 1 year ago

If anyone wants to help me upgrade to v7 I'd appreciate it. Willing to merge whatever is found

jameschensmith commented 1 year ago

I got this to work today for the most part (I'll put down what's not working below to see if it can be addressed). I think for OP, one issue may be that they are attempting to use the default export from @storybook/addons, which has been removed. They may have picked that up from the README. An update should address that. Next, for any parameters.docs.container overrides, make sure any unattached docs files (files without a story) are not referencing props.context.storyById or anything story-related. For anyone attempting to update the docs theme with a container override, I've found this almost working:

export const parameters = {
  darkMode: {
    // ...
  },
  docs: {
    container: (props) => {
      const isDark = useDarkMode();

      return React.createElement(DocsContainer, {
        ...props,
        theme: isDark ? themes.dark : themes.light,
      });
    },
  },
};

Now, onto the issue I'm currently facing. In Storybook 6, I've used stylePreview to update the story theme along with the docs theme using the container override above. But in v7, useParameter('darkMode', {}); appears to be returning undefined when on a docs page. When I change theme, it's changing the docs theme, but the preview iframe is not getting updated. What's weird is that if I go to a story view, the iframe gets updated, then a visit back to a docs view shows the docs and the story in the proper theme. I hope this makes sense. I can try to clarify more if needed.

arlenxuzj commented 1 year ago

Based on the storybook 7.0 docs, the way to import addons should be import { addons } from '@storybook/preview-api';. And this is working for me:

import { DocsContainer } from '@storybook/addon-docs';
import { addons } from '@storybook/preview-api';
import { themes } from '@storybook/theming';
import { useEffect, useState } from 'react';
import { DARK_MODE_EVENT_NAME, useDarkMode } from 'storybook-dark-mode';

const channel = addons.getChannel();

export const parameters = {
  darkMode: {
    // ...
  },
  docs: {
    // @ts-ignore
    container: ({ children, context }) => {
      const [isDark, setDark] = useState(useDarkMode());

      useEffect(() => {
        channel.on(DARK_MODE_EVENT_NAME, setDark);
        return () => channel.off(DARK_MODE_EVENT_NAME, setDark);
      }, [channel, setDark]);

      return (
        <DocsContainer
          context={context}
          theme={isDark ? themes.dark : themes.light}
        >
          {children}
        </DocsContainer>
      );
    }
  }
};