You can use the useTheme hook since v5.0:
import React, { useTheme } from 'styled-components';
export function MyComponent() {
const theme = useTheme();
return <p style={{ color: theme.color }}>Text</p>;
}
You can also use the withTheme higher order component that I contributed a long time ago since v1.2:
import { withTheme } from 'styled-components'
class MyComponent extends React.Component {
render() {
const { theme } = this.props
console.log('Current theme: ', theme);
// ...
}
}
export default withTheme(MyComponent)
original response below (ignore this!)
While there is no official solution, I came up by now:
Create a Higher Order Component that will be responsable to get the current theme and pass as a prop to a component:
import React from 'react';
import { CHANNEL } from 'styled-components/lib/models/ThemeProvider';
export default Component => class extends React.Component {
static contextTypes = {
[CHANNEL]: React.PropTypes.func,
};
state = {
theme: undefined,
};
componentWillMount() {
const subscribe = this.context[CHANNEL];
this.unsubscribe = subscribe(theme => {
this.setState({ theme })
});
}
componentWillUnmount() {
if (typeof this.unsubscribe === 'function') this.unsubscribe();
}
render() {
const { theme } = this.state;
return <Component theme={theme} {...this.props} />
}
}
Then, call it on the component you need to access the theme:
import Themable from './Themable.js'
const Component = ({ theme }) => <Card color={theme.color} />
export default Themable(Component);
Answer from Bruno Lemos on Stack OverflowDefault theme for components without parent ThemeProvider
reactjs - How to get the theme outside styled-components? - Stack Overflow
Implement different themes using styled components
Using Styled-Components with a theme provider. How should I organize my colors?
Videos
You can use the useTheme hook since v5.0:
import React, { useTheme } from 'styled-components';
export function MyComponent() {
const theme = useTheme();
return <p style={{ color: theme.color }}>Text</p>;
}
You can also use the withTheme higher order component that I contributed a long time ago since v1.2:
import { withTheme } from 'styled-components'
class MyComponent extends React.Component {
render() {
const { theme } = this.props
console.log('Current theme: ', theme);
// ...
}
}
export default withTheme(MyComponent)
original response below (ignore this!)
While there is no official solution, I came up by now:
Create a Higher Order Component that will be responsable to get the current theme and pass as a prop to a component:
import React from 'react';
import { CHANNEL } from 'styled-components/lib/models/ThemeProvider';
export default Component => class extends React.Component {
static contextTypes = {
[CHANNEL]: React.PropTypes.func,
};
state = {
theme: undefined,
};
componentWillMount() {
const subscribe = this.context[CHANNEL];
this.unsubscribe = subscribe(theme => {
this.setState({ theme })
});
}
componentWillUnmount() {
if (typeof this.unsubscribe === 'function') this.unsubscribe();
}
render() {
const { theme } = this.state;
return <Component theme={theme} {...this.props} />
}
}
Then, call it on the component you need to access the theme:
import Themable from './Themable.js'
const Component = ({ theme }) => <Card color={theme.color} />
export default Themable(Component);
You can use useTheme hook
import { useTheme } from 'styled-components';
const ExampleComponent = () => {
const theme = useTheme();
return (
<View>
<Card aCustomColorProperty={theme.color.sampleColor} />
</View>
);
};
I'm making a design system for our company using Styled Components. I can create a theme and use that theme for any component that needs to reuse padding, colors, etc.
export const Theme = (props) => (
<ThemeProvider theme={{
fontWeights: {
bold: 700;
normal: 400,
light: 100
},
...
}}>{props.children}</ThemeProvider>
);
export const Button = styled.button(props => `
font-weight: props.theme.fontWeight.normal,
...
`);The problem I'm having is colors. I don't want to specify the same HTML color codes everywhere, so I want to have them in the theme. But how do I organize them?
If I try this solution, then when I find a new situation I need to amend the color object, and it grows out of control with duplicated values and inconsistent variable names:
theme = {
colors: {
success: {
font: "#2dce89",
disabledBackground: "#abebd0",
glow: ...
active: ...
borderDisabled: ...
...
}
}
}Design sites suggest using numbers. But if I have to style a button, how do I know which color weight to use? And where do greyed versions for disabled go? What about other variants?
success: {
100: "#d5f5e7",
200: "#abebd0",
300: "#81e2b8",
400: "#57d8a1",
500: "#2dce89",
600: "#24a56e",
700: "#1b7c52",
800: "#125237",
900: "#09291b",
},Is there a better way to organize my colors so it is easy to be consistent across multiple components without having an explosion of one-off variables or duplicated values?