The problem
Existing css from @emotion/react doesn't support accessing theme props as such:
const mixin = css`
color: ${props => props.theme.colors.primary}
`'
Proposed solution
Please support it as it is helpful for React developers:
No specific solution from me but styled-components is a good example.
Alternative solutions
N/A
Additional context
Similar issue: #801
I see a few other options as temporary workarounds:
useTheme can be used inside a component.useTheme hook.You can also just refactor this to:
const mixin = theme => css`
color: ${theme.colors.primary}
`'
An example of @Andarist answer implemented in typescript can be found here.
I think the answer has been given - if you have any further questions please open a discussion thread.
@rickstaa Your link does not seems to be working. Can anyone give me an example of a typescript implementation?
When I do
const mixin = theme => css`
color: ${theme.colors.primary}
`
I get the error Parameter 'theme' implicitly has an 'any' type.
And when I do
const mixin = ({ theme }) => css`
color: ${theme.colors.primary}
`
I get the error Binding element 'theme' implicitly has an 'any' type.
I've made a codesandbox of the problem:
https://codesandbox.io/s/emotion-11-css-api-typescript-6dv8r?file=/src/Div.styled.ts
@StevenVerbiest, I think I changed the code-sandbox name somewhere after I posted the example. I updated the link to https://codesandbox.io/s/emotion-material-ui-example-ni92b?file=/src/App.tsx. I think for your example you should use the following syntax:
// 3. Use the material-ui theme inside the CSS api
// Re-declare the Emotion theme to the Material-ui theme
declare module "@emotion/react" {
export interface Theme extends MaterialUITheme {}
}
// Use theme inside the CSS api
const ButtonStyle = (theme: MaterialUITheme) => css`
background: ${theme.palette.info.main};
`;
You can then use the buttonstyle as follow:
<Button css={ButtonStyle(themeHooked)}>
CSS API (useTheme) button
</Button>
Let me know if that solves your problem.
@rickstaa Thank you for the update!
Your solution is similar to a workaround we had to do when implementing a custom theme interface (which is fixed in version 11).
It would be nice if the css api would also use the custom Theme interface instead of having to pass it every time we use it.
@StevenVerbiest I'm not sure if I understand the improvement your suggesting. Maybe you can elaborate a bit on it. When you use solution 3 in the sandbox the CSS API is able to use the custom theme without us having to pass it. The type declaration is there just to make typescript happy. Due to how typescript is typed I think there is no way to get rid of this type of definition.
I think the improvement your looking for is similar to what I asked in https://github.com/emotion-js/emotion/discussions/2291. After a discussion with @Andarist, I however agree that the module declaration overload is currently the cleanest solution we can support.
Most helpful comment
You can also just refactor this to: