-
Notifications
You must be signed in to change notification settings - Fork 13
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
Dynamic theme #84
Comments
Hi @Danilqa, thank you very much for the issue! It's a very interesting topic, and I hope you will not mind if I try to dive a little deeper into the subject. There are a couple of ways to apply some styles to the Component:
The first two are well known in the context of React applications, and the last one is something that we've introduced with reshadow (but of course it might be achievable somehow else) and I'll try to explain these parts better. Component's modifiersComponent's modifiers - is a clear and simple way to implement the styling. We just need to write the Component's behaviour depends on that modifiers, and I won't focus on this approach at the moment (but with reshadow there are also some interesting things). This is a great way to declare Component's own styling behaviour by design system, but it's important to mention that this approach is not really flexible, because if you need to change something on styling, you need to change Component's styles or change its API (add modifier or change modifier for example). So, this is the basic idea and it's often combined with others. ThemingWith theme we can "detach" some styling parts from the Component to the theme and make styling more flexible. There are also some limits, like Theme's API, because if you need to style something that's not supported by theme, you need to extend theme's API or, again, change Component's code. It is also might be tricky sometimes to design the Theme API the best way. Anyway, it looks like the most common way to apply different styles in React application, Context Theming Variables is a popular kind of implementation. Context Theming VariablesThis approach is very popular on In fact, with In example, with import {ThemeProvider} from 'theming';
const theme = {bg: 'white', fg: 'black'};
<ThemeProvider theme={theme}>
<App />
</ThemeProvider> import styled from 'reshadow'
import {withTheme} from 'theming';
const Button = ({theme, children, ...props}) => styled`
button {
color: ${theme.fg};
background-color: ${theme.bg};
border: 2px solid;
padding: 0.25em 1em;
}
`(
<button {...props}>
{children}
</button>
)
export default withTheme(Button) Dynamic values will fallback to the
Important to note, that because of Context ThemeThe previous approach might look natural and classic, but there are also some interesting things that might be nice to consider. A theme might be not just about some set of different variables for sizes, fonts, colors and so on, but it also affects the style behaviour of the component. Moreover, it might be no real intersection between Component styles in different themes (imagine, if we'd like to have But we can adjust the Component to the Button/index.js import styled, {css} from 'styled-components'
const themes = {
light: props => css` /* light theme */ `,
dark: props => css` /* dark theme */ `,
}
export const Button = styled.button`
${props => themes[props.theme]}
` With reshadow it might be implemented this way: import {ThemeProvider} from 'theming';
const theme = 'light';
<ThemeProvider theme={theme}>
<App />
</ThemeProvider> Button/themes.js export * as light from './light.css'
export * as dark from './dark.css' Button/index.js import styled from 'reshadow'
import {withTheme} from 'theming';
import themes from './themes'
const Button = ({theme, children, ...props}) => styled(themes[theme])(
<button {...props}>{children}</button>
)
export default withTheme(Button) This is the basic example in an attempt to show an idea, but we can take a step forward and load themes in a lazy way by Thus, we can compose different styles, themes for Components in the isolated ways and share our components independently. In contrast to StylingIf we'll take a look on the example with Context Theme, we can notice that our styles were detached from Component to the separate values. Let's take a little next step and inject our styles from props, for example: Button/index.js import styled from 'reshadow'
export const Button = ({styles, children, ...props}) => styled(styles)(
<button {...props}>
<content>{children}</content>
</button>
) With reshadow you can just write your markup and map the Component's state to it without carrying about the styling, and style the Component somewhere outside: import {css} from 'reshadow'
const styles = css`
button { ... }
button[disabled] { ... }
content { ... }
`
<Button styles={styles} ... /> It is possible to put the styles to DI and achieve the Styles Injection by the context. It is useful for styling components with the same UI logic and markup, but with really different styles, like this: But that's another interesting topic 😄 I hope I've understandably described different dynamic theme approaches with |
How I think. It is not work, because when you calculate hash for class name will be other, if use local style in |
Hi! Thank you for your wonderful job! :)
I haven't found approaches for creating a dynamic theme as we've usually done it in Style Component. What do you think about this solution? Does another more correct way exist?
Each component I wrap by
withTheme
and get need properties inside it.The text was updated successfully, but these errors were encountered: