styled-components: withTheme should not break if a default theme is provided
We are migrating a quite big React UI-kit to styled components 🎉 🎉 🎉 but found the following problem, every time we want to do some theming, the code for our components looks like this:
import * as theme from '../Theme'; // this is our fallback theme
const Title = styled.span`
font-weight: bold;
color: ${props => props.theme.color || theme.color};
font-size: {props => props.theme.fontSizeMedium || theme.fontSizeMedium}
`;
And the code gets even uglier when you have to adjust the styling to conditional prop values… you can imagine.
Besides that, when using withTheme HOC in components and you don’t wrap everything in a ThemeProvider the component itself breaks.
Is there a better/nicer way to provide a default ThemeProvider without having to do all that boilerplate code?
Thanks in advance and awesome work btw! ❤️
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 1
- Comments: 18 (18 by maintainers)
I would recommend you export your own
ThemeProviderthat sets a default theme in case the users don’t provide a custom one. Don’t even need.defaultPropseverywhere in that case, but of course if you prefer users are aware of you usingstyled-componentsusingdefaultPropswill work perfectly too!See this draft documentation we never finished: https://github.com/styled-components/styled-components-experimentation/blob/master/component-libraries/shared-component-libraries.md
You can use the
defaultPropsto define fallbacks.It shouldn’t actually break but just output a
console.error:https://github.com/styled-components/styled-components/blob/master/src/hoc/withTheme.js#L37
No worries, just merge the passed-in theme with the default theme:
That way your users can override specific parts of the theme, but for all the rest (or if none is provided, the whole thing) the default theme stays in place!
Ok, I want to give this a try but feel a bit lost about the codebase, could someone give me a short tour? 😄
@kutyel @mxstbr
To be referring to my last comment, there’s no error being thrown inside
withTheme:https://github.com/styled-components/styled-components/blob/master/src/hoc/withTheme.js#L35
But I agree that it’s confusing that we are logging an error even if the prop is defined. This however also reminded me that the behaviour of
withThemeis very counterintuitive in general as it doesn’t match theStyledComponentss usage of thethemeprop/defaultProp.https://github.com/styled-components/styled-components/blob/master/src/models/StyledComponent.js#L100
These lines here should be adapted to be a generic, reusable function, since it’s already used twice inside the component. We can reuse this error and log a warning if there’s both no context, and no
themeprop.The resulting component from the
withThemeHOC should match the logic exactly so that:themeprop takes precedence over the provided theme (from context) and use it instead, if it was passedthemeprop doesn’t take precedence over the provided theme (from context)themeprop at all timesSo overall this should be a sufficient overview of how to match the
withThemeimplementation to theStyledComponentimplementation.cc @mxstbr: Just making sure, I hope this makes more sense than just getting rid of the
console.error?