Creating a dark/light theme toggle is a great way to improve user experience — and it’s simpler than it looks, especially when using styled-components.
Today, I'll show you a quick and practical way to set up a theme system in React + styled-components, including how to dynamically switch between themes.
✅ The Problem: Multiple color schemes, but maintainable
When building components, it's common to need different color schemes (like light and dark mode).
Instead of hardcoding colors everywhere, how can we define and reuse them in a clean and flexible way?
💻 The Solution: ThemeProvider + theme objects
The ThemeProvider
from styled-components allows us to pass a theme object that can be used inside all components.
Let's see how to do it step by step.
Step 1: Define your themes
// theme.ts
export const lightTheme = {
background: '#ffffff',
text: '#333333',
};
export const darkTheme = {
background: '#333333',
text: '#ffffff',
};
Here we define a light and a dark theme, each containing background and text colors.
You can add more properties later (e.g., buttons, borders).
Step 2: Add ThemeProvider to your App
import { ThemeProvider } from 'styled-components';
import { useState } from 'react';
import { lightTheme, darkTheme } from './theme';
function App() {
const [isDarkMode, setIsDarkMode] = useState(false);
return (
<ThemeProvider theme={isDarkMode ? darkTheme : lightTheme}>
<YourComponents />
<button onClick={() => setIsDarkMode(!isDarkMode)}>
Toggle Theme
</button>
</ThemeProvider>
);
}
Here, we are toggling between darkTheme
and lightTheme
using a simple button.
Step 3: Use theme inside styled-components
Now, in your styled-components, you can access the theme values directly via props — no need to import them inside each component:
import styled from 'styled-components';
const Wrapper = styled.div`
background: ${({ theme }) => theme.background};
color: ${({ theme }) => theme.text};
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
`;
✅ Note: The theme
is injected automatically by ThemeProvider.
✅ Result: Dynamic theming!
With this approach:
- You avoid hardcoding colors in components.
- Components automatically adapt when the theme changes.
- The theme is centralized and easy to maintain.
⚙️ Why this approach is great?
- Centralized colors — no need to update each component when adjusting the theme.
- Clean separation between logic (theme toggle) and style.
- Scalable — easy to extend with more properties like buttons, borders, shadows.
- Works seamlessly with styled-components' ecosystem.
🔑 Example: Applying to a Button
To make the button consistent with the page, where background and text colors match the overall theme, you should NOT invert background
and color
.
So here is the corrected version:
const Button = styled.button`
background: ${({ theme }) => theme.background};
color: ${({ theme }) => theme.text};
padding: 10px 20px;
border: 1px solid ${({ theme }) => theme.text};
border-radius: 4px;
cursor: pointer;
&:hover {
opacity: 0.9;
}
`;
➡️ Note: I added a border
with theme.text
to make the button visible on both themes.
You can adjust or remove this depending on your design system.
✅ Optional: Creating a contrasting button (primary variant)
If you want a button that contrasts with the background, like a primary action button, you can extend your theme to add a primary
color:
export const lightTheme = {
background: '#ffffff',
text: '#333333',
primary: '#007bff',
};
export const darkTheme = {
background: '#333333',
text: '#ffffff',
primary: '#1e90ff',
};
And then use it in the button:
const PrimaryButton = styled.button`
background: ${({ theme }) => theme.primary};
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
opacity: 0.9;
}
`;
🚀 Final Thoughts
Using ThemeProvider with styled-components makes it simple to create dynamic themes that enhance user experience.
This pattern is useful for projects of any size, and a great way to keep styles organized, flexible, and easy to maintain.
👉 How do you handle themes in your React projects?
Let me know in the comments! 👇
🔗 Follow me for more React + styled-components tips!
Tidak ada komentar:
Posting Komentar