Sabtu, 15 Maret 2025

How to Create Themes (light/dark) with React & Styled-components

| Sabtu, 15 Maret 2025

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!


Related Posts

Tidak ada komentar:

Posting Komentar