Create themes for your app using styled-components
Read the introductory blog post
yarn add styled-components styled-theming
import React from 'react';
import styled, {ThemeProvider} from 'styled-components';
import theme from 'styled-theming';
const boxBackgroundColor = theme('mode', {
light: '#fff',
dark: '#000',
});
const Box = styled.div`
background-color: ${boxBackgroundColor};
`;
export default function App() {
return (
<ThemeProvider theme={{ mode: 'light' }}>
<Box>
Hello World
</Box>
</ThemeProvider>
);
}
<ThemeProvider>
is part of styled-components, but is required for styled-theming.
import {ThemeProvider} from 'styled-components';
<ThemeProvider>
accepts a single prop theme
which you should pass an object
with either strings or getter functions. For example:
<ThemeProvider theme={{ mode: 'dark', size: 'large' }}>
<ThemeProvider theme={{ mode: modes => modes.dark, size: sizes => sizes.large }}>
You should generally set up a <ThemeProvider>
at the root of your app:
function App() {
return (
<ThemeProvider theme={...}>
{/* rest of your app */}
</ThemeProvider>
);
}
Most of your theming will be done with this function.
name
should match one of the keys in your <ThemeProvider>
theme.
<ThemeProvider theme={{ whatever: '...' }}/>
theme('whatever', {...});
values
should be an object where one of the keys will be selected by the
value provided to <ThemeProvider>
theme.
<ThemeProvider theme={{ mode: 'light' }}/>
<ThemeProvider theme={{ mode: 'dark' }}/>
theme('mode', {
light: '...',
dark: '...',
});
The values of this object can be any CSS value.
theme('mode', {
light: '#fff',
dark: '#000',
});
theme('font', {
sansSerif: '"Helvetica Neue", Helvetica, Arial, sans-serif',
serif: 'Georgia, Times, "Times New Roman", serif',
monoSpaced: 'Consolas, monaco, monospace',
});
These values can also be functions that return CSS values.
theme('mode', {
light: props => props.theme.userProfileAccentColor.light,
dark: props => props.theme.userProfileAccentColor.dark,
});
theme
will create a function that you can use as a value in
styled-component's styled
function.
import styled from 'styled-components';
import theme from 'styled-theming';
const backgroundColor = theme('mode', {
light: '#fff',
dark: '#000',
});
const Box = styled.div`
background-color: ${backgroundColor}
`;
The values will be passed through like any other interpolation
in styled-components. You can use the css
helper to add entire
blocks of styles, including their own interpolations.
import styled, {css} from 'styled-components';
import theme from 'styled-theming';
const white = "#fff";
const black = "#000";
const boxStyles = theme('mode', {
light: css`
background: ${white};
color: ${black};
`,
dark: css`
background: ${black};
color: ${white};
`,
});
const Box = styled.div`
${boxStyles}
`;
It's often useful to create variants of the same component that are selected via an additional prop.
To make this easier with theming, styled-theming provides a theme.variants
function.
import styled from 'styled-components';
import theme from 'styled-theming';
const backgroundColor = theme.variants('mode', 'variant', {
default: { light: 'gray', dark: 'darkgray' },
primary: { light: 'blue', dark: 'darkblue' },
success: { light: 'green', dark: 'darkgreen' },
warning: { light: 'orange', dark: 'darkorange' },
});
const Button = styled.button`
background-color: ${backgroundColor};
`;
Button.propTypes = {
variant: PropTypes.oneOf(['default', 'primary', 'success', 'warning'])
};
Button.defaultProps = {
variant: 'default',
};
<Button/>
<Button variant="primary"/>
<Button variant="success"/>
<Button variant="warning"/>