-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
@emotion/react ThemeProvider does not work with @emotion/styled #10231
Comments
We are also using emotion 10.0.x in Storybook. I'm guessing the two are not playing nicely together. cc @ndelangen |
Hello @shilman , thank you very much for the fast processing. I am currently in the process of moving our design system to Storybook. Due to this problem, a part of our frontend development is currently at a standstill. If it helps you, I will support you in solving this problem. |
Is there any news yet? @shamin @ndelangen |
I don't know what's happening here. Hopefully @ndelangen does. |
Are you wrapping your stories with a decorator providing the theme context? |
Yes. As described in step 7 (steps to reproduce), I have done that. Because the useTheme hook works, as you can see in the photo, the theme context is available. I created a repository where you can look at the code or clone it for testing. |
Might be related to #10296 It seems that context provider doesn't work on the top level in stories. |
In my case it just does not work with the styled components. In the other cases, as you can see in the screenshot, the context works. But maybe the reason for the problem is the same for both of us. |
I spoke to one of the emotion maintainers yesterday, and this is essentially due to both storybook & your app/component using emotion & theming. Emotion theming solution uses React context, meaning is somewhat global. The proper solution is to not use emotion context but our own. Here's the suggested solution from https://github.com/Andarist: styled.div(props => ({
const theme = useMyTheme();
return {
color: theme.color,
};
})} I'm not mentioning this because I think YOU should do this, but actually, this is something Storybook should do, so we would never conflict with someone using emotion. We think emotion is the best, and we certainly don't want to stand in the way of anyone using it + storybook. @fabian-hiller I have some pretty strong ideas on how to make this work from storybook, would you be interested in working with me to solve this in storybook? |
Yeah, I'd be honored. How much effort do you estimate? |
We need
part 3 is going to be the most challenging, particularly to make all the typings correct. If you'd want to tackle this together in a pair programming session, let's schedule something: |
All right. See you later. |
Woohoo! It's great to see this being worked on. We face the same issue at sumup-oss/circuit-ui when trying to upgrade to Emotion 11. If there's anything that I can do to help here, please let me know. |
Thanks for your message @connor-baer.
Could you find a solution? Where can I find the code for it in your repository? |
@fabian-hiller I searched the Emotion and Storybook issues extensively and there doesn't seem to be a solution that can be implemented on the user's side. I came across the same suggestion that @ndelangen relayed from @Andarist: frameworks should implement and use their own theme context. The steps that @ndelangen outlined are much more straightforward than what I had in mind. Did you two already get started on those? I looked a bit into @storybook/theming and how we could auto-inject the custom theme context into import React from 'react';
import emotionStyled from '@emotion/styled-base'
const useTheme = () => React.useContext(StorybookThemeContext);
const styled = (...args) => {
const Styled = emotionStyled(...args);
const theme = useTheme();
return React.forwardRef((props) => <Styled theme={theme} {...props} />;
} Then we just need to apply the same magic that @emotion/styled does to make the |
@connor-baer I had an approach similar to yours, but I haven't been able to make it work yet. I will test your code the days and if it works, I can create a PR. |
Doing something like this as a workaround would be a bad idea? import styled from "@emotion/styled";
import { theme } from "custom-theme";
export const Button = styled.button`
background-color: ${theme.colors.green};
`; Another thing that seems to work is keep using import { ThemeProvider } from "emotion-theming";
import { theme } from "custom-theme";
const ThemeDecorator = (storyFn) => (
<ThemeProvider theme={theme}>{storyFn()}</ThemeProvider>
);
addDecorator(ThemeDecorator); |
This would require updating every component inside Storybook or your own codebase which would be a huge amount of work. It also makes it impossible to dynamically update the theme, e.g. from light to dark.
I assume you're talking about using Emotion 11 in the component library? Does |
Good point. |
Interesting, I'll give that a shot. Thanks for the tip! |
Given that the above PR is not yet merged, I think this issue should be re-opened. |
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! |
potential complications:
|
potential additional upside:
|
Also ran into this issue today and it took some time to figure out which combination of things was causing the issue. I am building a component library upon styled-system and emotion. Inside my App, everything worked fine but in Storybook the components didn't take any values from the ThemeProvider (added via decorators in preview.js). Would love to see support for ThemeProvider from @emotion/react 🙂 |
For me the solution was to add the emotion packages to the webpack.config.js: module.exports = {
resolve: {
extensions: ['.ts', '.tsx', '.js'],
alias: {
...,
'@emotion/react': '@emotion/react',
'@emotion/styled': '@emotion/styled',
},
},
... |
I have it working like this .storybook/main.js const path = require("path")
const { override, babelInclude, addWebpackAlias, addWebpackResolve } = require("customize-cra")
module.exports = {
stories: [
"../stories/**/*.js"
],
addons: [
"@storybook/addon-links",
{
name: "@storybook/addon-essentials",
options: {
actions: false,
controls: false,
viewport: false,
}
},
"@react-theming/storybook-addon"
],
webpackFinal: async (config, env) => {
return Object.assign(
config,
override(
/* TODO: remove once this is merged: https://github.com/storybookjs/storybook/pull/13300
*
* Storybook does not support emotion 11 yet.
* Sometimes the modules get crossed. If that happens, uncomment these lines, delete/re-install modules and run storybook again.
* IT WILL FAIL until you re-comment out these lines and restart the storybook server.
* import addWebpackAlias from customize-cra
*
**/
addWebpackAlias({
"@emotion/core": path.resolve("node_modules/@emotion/react"),
"@emotion/styled": path.resolve("node_modules/@emotion/styled"),
"emotion-theming": path.resolve("node_modules/@emotion/react"),
"@emotion/react": path.resolve("node_modules/@emotion/react"),
}),
addWebpackResolve({
modules: [
...(config.resolve.modules || []),
path.resolve(__dirname, "../../webapp/src")
]
}),
)(config, env)
)
},
} .storybook/preview.js import { ThemeProvider } from "@emotion/react"
import { withThemes } from "@react-theming/storybook-addon"
const themes = []
export const decorators = [
withThemes(ThemeProvider, themes),
]
export const parameters = {
backgrounds: {
default: "light",
values: themes.map(({ name, colors }) => ({ name, value: colors.background }))
},
} |
* refactor(web): migrate to emotion * fix(web): fix emotion theme collision in storybook Related issues: - storybookjs/storybook#12262 - storybookjs/storybook#10231 Solution by storybookjs/storybook#10231 (comment) * style(web): rename theme type * refactor(web): remove theme import * refactor(web): add emotion animation snippet helper See: emotion-js/emotion#239
For anyone else having problems with MUIv5 + Storybook 'Docs' tab, this was my solution. We use MUIv5 (currently in beta) which depends on Emotion 11. Like many others here, I added a decorator in preview.js. export const decorators = [
(Story) => (
<MUIThemeProvider theme={muiTheme}>
<CssBaseline />
<Story />
</MUIThemeProvider>
),
]; Many (all?) MUI components depend on the MUI theme object, which users typically provide via MUI's borderColor: theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)' The problem: as we started trialling Storybook v6.3, while Storybook's 'Canvas' tab was working OK, the 'Docs' tab was crashing in some cases. Apparently components whose styling depends on values from the MUI theme (e.g. dark/light relies on Inspecting via React DevTools, it looks like Storybook wraps things using its own Solution: I started with @lucascurti tip (thanks!), but also wrapped that with MUI's theme provider. preview.js
I'm pretty sure this is mixing both Emotion 10 and 11, which seems not great and hope we don't have new issues down the road. It seems preferable to have just one ThemeProvider, for this reason I'd also love to see Emotion 11 support land (#13300), which I believe would make my solution no longer needed. If anyone has insight into what's going on would be nice to hear, either way hope this helps someone else. |
- Discovered some kind of theme object/Context conflict imposed by the fact Storybook wraps our components with its own ThemeProvider. (Echoes of Theme-UI vs MUI issue from before) - Resolution: learning info from storybookjs/storybook#10231 + a small change storybookjs/storybook#10231 (comment) - Result: Docs tab now works again
- Discovered some kind of theme object/Context conflict imposed by the fact Storybook wraps our components with its own ThemeProvider. (Echoes of Theme-UI vs MUI issue from before) - Resolution: learning info from storybookjs/storybook#10231 + a small change storybookjs/storybook#10231 (comment) - Result: Docs tab now works again
- Discovered some kind of theme object/Context conflict imposed by the fact Storybook wraps our components with its own ThemeProvider. (Echoes of Theme-UI vs MUI issue from before) - Resolution: learning info from storybookjs/storybook#10231 + a small change storybookjs/storybook#10231 (comment) - Result: Docs tab now works again
- Discovered some kind of theme object/Context conflict imposed by the fact Storybook wraps our components with its own ThemeProvider. (Echoes of Theme-UI vs MUI issue from before) - Resolution: learning info from storybookjs/storybook#10231 + a small change storybookjs/storybook#10231 (comment) - Result: Docs tab now works again
- Discovered some kind of theme object/Context conflict imposed by the fact Storybook wraps our components with its own ThemeProvider. (Echoes of Theme-UI vs MUI issue from before) - Resolution: learning info from storybookjs/storybook#10231 + a small change storybookjs/storybook#10231 (comment) - Result: Docs tab now works again
- Discovered some kind of theme object/Context conflict imposed by the fact Storybook wraps our components with its own ThemeProvider. (Echoes of Theme-UI vs MUI issue from before) - Resolution: learning info from storybookjs/storybook#10231 + a small change storybookjs/storybook#10231 (comment) - Result: Docs tab now works again
- Discovered some kind of theme object/Context conflict imposed by the fact Storybook wraps our components with its own ThemeProvider. (Echoes of Theme-UI vs MUI issue from before) - Resolution: learning info from storybookjs/storybook#10231 + a small change storybookjs/storybook#10231 (comment) - Result: Docs tab now works again
- Discovered some kind of theme object/Context conflict imposed by the fact Storybook wraps our components with its own ThemeProvider. (Echoes of Theme-UI vs MUI issue from before) - Resolution: learning info from storybookjs/storybook#10231 + a small change storybookjs/storybook#10231 (comment) - Result: Docs tab now works again
- Discovered some kind of theme object/Context conflict imposed by the fact Storybook wraps our components with its own ThemeProvider. (Echoes of Theme-UI vs MUI issue from before) - Resolution: learning info from storybookjs/storybook#10231 + a small change storybookjs/storybook#10231 (comment) - Result: Docs tab now works again
- Discovered some kind of theme object/Context conflict imposed by the fact Storybook wraps our components with its own ThemeProvider. (Echoes of Theme-UI vs MUI issue from before) - Resolution: learning info from storybookjs/storybook#10231 + a small change storybookjs/storybook#10231 (comment) - Result: Docs tab now works again
My problem revolves around the fact that
Any component that uses
My dependencies are:
Potentially unrelated but I also depend on |
We have the exact same issue @cabello. The @mavlikwowa's solution only makes theme available in the emotion styled-components but it looks like |
Edit: Ok, on top of @onpaws's workaround, I also had to add the following in order to get them to work: webpackFinal: async (config) => {
config.resolve.alias = {
...config.resolve.alias,
"@emotion/core": resolvePath("node_modules/@emotion/react"),
"emotion-theming": resolvePath("node_modules/@emotion/react")
}
return config;
} Original: import React from 'react';
import { ThemeProvider as MuiThemeProvider, CssBaseline } from '@mui/material';
import { ThemeProvider } from 'styled-components';
import { GlobalStyle } from './index';
...
<StyledEngineProvider injectFirst>
<MuiThemeProvider theme={props.theme}>
<ThemeProvider theme={props.theme}>
<GlobalStyle />
<CssBaseline />
{props.children}
</ThemeProvider>
</MuiThemeProvider>
</StyledEngineProvider> But the typography setting configured for MUI is not passing down... If I run my project directly with |
Storybook has provided a feature-flag for storybook users that works around this issue for now, see the other issue: #13145 For those who spend time looking for a fix for this after me. Or to skip to the docs:
|
@rrsai thanks so much for spreading the word!!! 🙏 🙏 🙏 |
I ran to that problem recently, so everything that need to be upgraded need to be upgraded |
I'm using emotion v11 and storybook v7 and I face the same issue:
|
Describe the bug
I use @emotion/react ThemeProvier to access the theme prop when styling a component. When I open my app with "npm start" everything works smoothly. With "npm run storybook", however, the theme object for my styled emotion components is empty.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The pre-defined theme object is displayed in the console, so that you can access it when styling.
Screenshots
Code snippets
GitHub repo: https://github.com/fabian-hiller/a7hs5hsk2
System:
Environment Info:
System:
OS: macOS 10.15.3
CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Binaries:
Node: 12.13.1 - /usr/local/bin/node
npm: 6.14.4 - ~/.npm-global/bin/npm
Browsers:
Chrome: 80.0.3987.149
Firefox: 74.0
Safari: 13.0.5
npmPackages:
@storybook/addon-actions: ^5.3.17 => 5.3.17
@storybook/addon-links: ^5.3.17 => 5.3.17
@storybook/addons: ^5.3.17 => 5.3.17
@storybook/preset-create-react-app: ^2.1.1 => 2.1.1
@storybook/react: ^5.3.17 => 5.3.17
The text was updated successfully, but these errors were encountered: