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

storybook chakra-ui themes addon #2190

Closed
hems opened this issue Oct 7, 2020 · 11 comments
Closed

storybook chakra-ui themes addon #2190

hems opened this issue Oct 7, 2020 · 11 comments
Labels
PR welcome 😇 Priority: Low Topic: Integrations ♾️ Relates to integrating Chakra UI with other ecosystems.

Comments

@hems
Copy link

hems commented Oct 7, 2020

Feature request

Is your feature request related to a problem? Please describe.

Currently, there is no easy way of switching chakra-ui theme on Storybook

Describe the solution you'd like

A implementation similar to https://github.com/echoulen/storybook-addon-styled-component-theme

Describe alternatives you've considered

Forking https://github.com/echoulen/storybook-addon-styled-component-theme and hacking a chakra-ui version of the same addon

Additional context

I'm not entirely sure if the chakra-ui team is planning to release such addon for Storybook and if forking the styled-component repo would be the best way of going about it

@with-heart with-heart added Topic: Integrations ♾️ Relates to integrating Chakra UI with other ecosystems. PR welcome 😇 Priority: Low labels Oct 8, 2020
@with-heart
Copy link
Contributor

with-heart commented Oct 8, 2020

That's an interesting idea. We could certainly create an addon to enable that but with our current team capacity, that'll have to be low priority. If anyone would like to take the time to investigate though and attempt to implement something similar, we can see how we can integrate that into the Chakra UI tooling ecosystem.

@hems
Copy link
Author

hems commented Oct 14, 2020

That's an interesting idea. We could certainly create an addon

I believe you wouldn't need to create one from scratch, you could just fork the addon i mentioned here:
https://github.com/echoulen/storybook-addon-styled-component-theme

to enable that but with our current team capacity, that'll have to be low priority.

I would say someone with TypeScript knowledge and good understanding of Chakra would be able to fork and change that addon to work with chakra in less than 2 hours?

If anyone would like to take the time to investigate though and attempt to implement something similar

I'm new to typescript and very new to chakra ( and even more knew to the @next version ), so i'm still wrapping my head around the differences in the implementation styled-components ( currently used on my application ) to the way theme-ing works on chakra, i'm still slightly confused but the new documentation is actually clarifying a lot of my questions.

From my understanding We would have to fork that addon i mentioned and then replace the <ThemeProvider> from styled-compoents tag by the <ChakraProvider> and then use the input from the addon to set the initialColorMode as described on this help page??

@hems
Copy link
Author

hems commented Oct 14, 2020

Actually it seems that library already accepts a CustomThemeProvider so we could potentially just write a "CustomThemeProvider" and then use that to write the <ChakraProvider> tag without having to change the addon, the only thing is the library uses styled-components as a dependency because the default theme provider is the one from styled-components

@hems
Copy link
Author

hems commented Oct 14, 2020

One issue that is happening on my application is that if i use

const config = {
  useSystemColorMode: false,
  initialColorMode: 'dark'
}

// 3. extend the theme
const customTheme = extendTheme({ config, styles })

....

<ChakraProvider theme={customTheme}>
   // my app
</ChakraProvider>

My application still starts in light mode instead of dark, so i needed to add this before everything:

<ColorModeScript initialColorMode="dark" />

Which in turn made this part of the code irrelevant:

const config = {
  useSystemColorMode: false,
  initialColorMode: 'dark'
}

// 3. extend the theme
const customTheme = extendTheme({ config, styles })

....

<ChakraProvider theme={customTheme}>

I'm not sure if that's the intended behaviour or if it's a problem with my implementation, but in the end when trying out on my app i found out this is what needed to be done:

<ColorModeScript initialColorMode="dark" />

<ChakraProvider
   // my app
</ChakraProvider>

I still did not try toggling the Theme tough.

If i manage to understand / test everything better here i might be able to implement a CustomProvider for the addon, in the meanwhile i'll post my findings here ( i hope that's ok? )

@hems
Copy link
Author

hems commented Oct 16, 2020

I did manage to progress quite a lot, by using the aforementioned customProvider on preview.js this way:

preview.js

const themes = [{name: 'dark',},{name: 'light',}]

const customProvider = (props) => {
  const mode = props.theme.name

  console.log("settig theme ->", mode)

  return (<>
      <ColorModeScript initialColorMode={mode} />

      <ChakraProvider resetCSS={true} theme={theme} mode={mode}>
        {props.children}
      </ChakraProvider>

  </>)
}

addDecorator(withThemesProvider(themes, customProvider))

Then creating a button:

#ChakraButton/index.tsx

import { Button } from '@chakra-ui/core'
import { useColorMode } from '@chakra-ui/core'

export default function ChakraButton() {
  const { colorMode, toggleColorMode } = useColorMode()

  console.error('chakra butto says current mode ->', colorMode)

  return (
    <>
      <Button translate="" size="sm" onClick={toggleColorMode}>
        CHAKRA BUTTON
      </Button>
    </>
  )
}

And a story:

ChakraButton/ChakraButton.stories.tsx

import React from 'react'
import Component from './'

export default {
  component: Component,
  title: 'components/atoms/ChakraButton'
}

export const Primary = () => (
  <>
    <Component />
  </>
)

It all works as expected on the website context.

Button when testing my Storybook the Button is being rendered two times, firs ttime useColorMode() return undefined and second time it returns ( empty string ) and the button is being rendered in light mode despite the fact i set initialColorMode to dark and ChakraProvider mode='dark'

image

Clicking the button on StoryBook does switch the theme tough and it works as expected, so it seems there is just something wrong about the way the button is being initialized.

Worth noticing on my applicaiton, the first time it also says undefined but the second time it says dark, so it seems the problem on the Storybook happens on the second render. Seems like useColorMode can't find the right state inside of StoryBook, which seems a bit strange, maybe the addon is messing with some of the state?

image

Any ideas?

@hems
Copy link
Author

hems commented Oct 16, 2020

Turns out the same is happening even when i use pure ChakraProvider on Storybook

#preview.js

import CSSReset from "@chakra-ui/css-reset"
import theme from "../src/chakra"
import { ChakraProvider, Box } from "@chakra-ui/core"
import { addDecorator } from "@storybook/react"
import * as React from "react"

const newTheme = {
  ...theme,
  config: {
    initialColorMode: "dark",
    useSystemColorMode: false,
  }
}

export const Chakra = ({ children }) => (
  <ChakraProvider theme={newTheme}>
    <CSSReset />
    <Box p={5}>
      {children}
    </Box>
  </ChakraProvider>
)

addDecorator(StoryFn =>
  <Chakra>
    <StoryFn />
  </Chakra>)

It first renders with dark and then for some reason it seems to get "disconnected" from the provider and have an empty state:

image

@hems
Copy link
Author

hems commented Oct 20, 2020

I have created a new repository exclusively with chakra-ui code and i'm still able to reproduce the issue, so it seems the issue is 100% related to Chakra #2270 i hope that helps and that solving #2270 i'll also be closing this issue as it seems that's the only piece of the puzzle needed to finish integrating ChakraProvider with the aforementioned plugin.

@segunadebayo
Copy link
Member

As much as I'd love to add this to Chakra UI. I think we can keep the setup as-is for now.

We've added a switch for light and dark more in Storybook and I think that should be enough for now considering the human resources we have.

Thank you. We might look into this in the future.

@hems
Copy link
Author

hems commented Oct 21, 2020

We've added a switch for light and dark more in Storybook and I think that should be enough for now considering the human resources we have.

To be honest i hadn't see that switch on your storybook before, and i do think that's a very good an simple approach that solves most of the cases.

The problem i see if with tough is that it breaks the design when using the "viewports" addon of Storybook, for instance on our storybook we have currently all our breakpoints pre-set on Storybook and we can preview any component in any breakpoint this way.

Having the extra "Theme Switcher" from Chrakra would add an extra element to the design on Storybook which creates a discrepancy between how you see it on the storybook and how it looks like on the breakpoints.

Also, considering your knowledge about Chakra and how the Storybook is implemented on Chakra it wouldn't take more than a few hours to implement the switcher on the Addons pane as opposed to having it on the preview file.

Here is the official documentation for the Viewport addon on the storybook website

Have a look at this screenshot:

image

@maapteh
Copy link
Contributor

maapteh commented Sep 3, 2021

For the searchers like me who end up here and think it's not possible after reading this topic.
There is actually a default plugin for it. Its totally possible with '@react-theming/storybook-addon'

In .storybook/main you add the plugin like (see their docs):

module.exports = {
  addons: [
    ... others ...,
    '@react-theming/storybook-addon',
  ],

In .storybook/preview it would be like:

import React from 'react';
import { ChakraProvider, extendTheme } from '@chakra-ui/react';
import { addDecorator } from '@storybook/react';
import { withThemes } from '@react-theming/storybook-addon';

// add prop name to each theme so the buttons have correct title
import { themeDefault } from '../src/themes/default';
import { themeFoo } from '../src/themes/foo';

const providerFn = ({ theme, children }) => {
  const extendedTheme = extendTheme(theme);
  return <ChakraProvider theme={extendedTheme}>{children}</ChakraProvider>;
};

addDecorator(
  withThemes(null, [themeDefault, themeFoo], {
    providerFn,
  })
);

And there you have your theme switcher.
@segunadebayo maybe worthwhile for your docs?

Screenshot 2021-09-03 at 21 20 24

when wondering about the first string in screenshot, 'sm' in the view comes from own hook using the useBreakpointValue hook. I used it while testing if it gave correct value :)

With the theme addon i can switch between any optional given theme.

@ivan-rivera
Copy link

@maapteh thank you! That helped, Although I had to make minor changes to your example in order to make it work for me:

// preview.js

import { ChakraProvider } from "@chakra-ui/react";
import { addDecorator } from "@storybook/react";
import { withThemes } from "@react-theming/storybook-addon";
import theme from "../theme/theme";

addDecorator(withThemes(ChakraProvider, [theme]));

...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR welcome 😇 Priority: Low Topic: Integrations ♾️ Relates to integrating Chakra UI with other ecosystems.
Projects
None yet
Development

No branches or pull requests

5 participants