ThemeProvider in styled-components allows you to create a cohesive system of colors, sizes, and typography -- like a unified interface for the entire space fleet.
ThemeProvider is a component that provides a theme to all components inside it:1import { ThemeProvider } from 'styled-components';
2
3const spaceTheme = {
4 colors: {
5 primary: '#7c4dff',
6 secondary: '#64b5f6',
7 background: '#0a0a2e',
8 surface: '#1a1a4e',
9 text: '#e0e0e0',
10 success: '#00e676',
11 warning: '#ffa726',
12 danger: '#f44336',
13 },
14 spacing: {
15 xs: '4px',
16 sm: '8px',
17 md: '16px',
18 lg: '24px',
19 xl: '32px',
20 },
21 borderRadius: {
22 sm: '4px',
23 md: '8px',
24 lg: '12px',
25 round: '50%',
26 },
27 fontSize: {
28 sm: '12px',
29 md: '16px',
30 lg: '20px',
31 xl: '28px',
32 },
33};
34
35function App() {
36 return (
37 <ThemeProvider theme={spaceTheme}>
38 <Dashboard />
39 </ThemeProvider>
40 );
41}Every styled-component has automatic access to the theme through
props.theme:1const Panel = styled.div`
2 background: ${props => props.theme.colors.surface};
3 border-radius: ${props => props.theme.borderRadius.lg};
4 padding: ${props => props.theme.spacing.lg};
5 color: ${props => props.theme.colors.text};
6`;
7
8const Heading = styled.h2`
9 color: ${({ theme }) => theme.colors.primary};
10 font-size: ${({ theme }) => theme.fontSize.xl};
11 margin-bottom: ${({ theme }) => theme.spacing.md};
12`;Notice the destructuring --
({ theme }) is a shorthand for (props) => props.theme.One of the most popular uses of ThemeProvider is switching between dark and light themes:
1const darkTheme = {
2 colors: {
3 background: '#0a0a2e',
4 surface: '#1a1a4e',
5 text: '#e0e0e0',
6 primary: '#7c4dff',
7 },
8};
9
10const lightTheme = {
11 colors: {
12 background: '#f5f5f5',
13 surface: '#ffffff',
14 text: '#212121',
15 primary: '#5c6bc0',
16 },
17};
18
19function App() {
20 const [isDark, setIsDark] = useState(true);
21 const theme = isDark ? darkTheme : lightTheme;
22
23 return (
24 <ThemeProvider theme={theme}>
25 <AppContainer>
26 <button onClick={() => setIsDark(!isDark)}>
27 Toggle Theme
28 </button>
29 <Dashboard />
30 </AppContainer>
31 </ThemeProvider>
32 );
33}createGlobalStyle allows you to define global CSS styles that also have access to the theme:1import { createGlobalStyle } from 'styled-components';
2
3const GlobalStyles = createGlobalStyle`
4 * {
5 margin: 0;
6 padding: 0;
7 box-sizing: border-box;
8 }
9
10 body {
11 background: ${({ theme }) => theme.colors.background};
12 color: ${({ theme }) => theme.colors.text};
13 font-family: 'Segoe UI', sans-serif;
14 }
15`;
16
17function App() {
18 return (
19 <ThemeProvider theme={spaceTheme}>
20 <GlobalStyles />
21 <Dashboard />
22 </ThemeProvider>
23 );
24}If you need access to the theme in component logic (not just in styles), use the
useTheme hook:1import { useTheme } from 'styled-components';
2
3function StatusChart({ data }) {
4 const theme = useTheme();
5
6 // Use theme colors in logic, e.g., for Canvas, SVG, or conditions
7 const chartColor = data.isHealthy
8 ? theme.colors.success
9 : theme.colors.danger;
10
11 return (
12 <div>
13 <svg width="100" height="100">
14 <circle cx="50" cy="50" r="40" fill={chartColor} />
15 </svg>
16 <p style={{ color: theme.colors.text }}>
17 Status: {data.isHealthy ? 'OK' : 'Alert'}
18 </p>
19 </div>
20 );
21}useTheme is useful when you need theme values outside of styled-components -- for example, for drawing on Canvas, configuring chart libraries, or conditional logic based on theme colors.ThemeProvider can be nested so that different sections of the application have different themes:
1function App() {
2 return (
3 <ThemeProvider theme={darkTheme}>
4 <Header />
5 <ThemeProvider theme={lightTheme}>
6 <ContentArea /> {/* lightTheme applies here */}
7 </ThemeProvider>
8 <Footer /> {/* darkTheme is back here */}
9 </ThemeProvider>
10 );
11}It's like different sections of a spaceship with different lighting modes -- the command bridge can be dark while the laboratory is bright.