Introduction
In this tutorial, we will build a Social Media Theme Switcher using React. This project demonstrates how to implement light and dark themes in a React application, making it ideal for users who want to toggle between different styles for improved user experience and accessibility.
Project Overview
This theme switcher project allows users to toggle between light and dark themes on a social media-like interface. The application switches the colors of the entire user interface, including the background, text, and button colors, based on the selected theme.
Features
- Light/Dark Mode Toggle: Switch between light and dark modes to suit user preferences.
- Responsive Design: Ensures the layout adjusts smoothly across different devices.
-
Persist Theme: The chosen theme is saved to
localStorage
, allowing users to maintain their preferred theme across sessions.
Technologies Used
- React: For building the user interface and handling the theme switch functionality.
- CSS: For styling the different themes and ensuring a responsive design.
- localStorage: To persist the theme selection across sessions.
Project Structure
The project is structured as follows:
├── public
├── src
│ │
│ ├── App.jsx
│ ├── App.css
│ ├── index.js
│ └── index.css
├── package.json
└── README.md
Key Components
- App.jsx: Contain the theme switcher and manages the overall layout of the application.
- App.css: Contains the styles for both light and dark themes.
Code Explanation
App Component
The App
is have code of social media content and applies global styles based on the current theme.
import { useState } from "react";
import "./App.css";
import upLogo from "./assets/images/icon-up.svg";
import downLogo from "./assets/images/icon-down.svg";
import fbLogo from "./assets/images/icon-facebook.svg";
import igLogo from "./assets/images/icon-instagram.svg";
import twLogo from "./assets/images/icon-twitter.svg";
import ytLogo from "./assets/images/icon-youtube.svg";
const App = () => {
const [isDarkMode, setIsDarkMode] = useState(false);
const toggleTheme = () => {
setIsDarkMode(!isDarkMode);
};
return (
<>
<div className={`body ${isDarkMode ? "light" : "dark"}`}>
<div className="app">
<div className="header">
<div className="dashboard">
<h1>Social Media Dashboard</h1>
<p>Total Followers: 23,004</p>
</div>
<div className="mode">
<p>{isDarkMode ? "Light Mode" : "Dark Mode"}</p>
<div className="toggle-area">
<div
onClick={toggleTheme}
className={`${
isDarkMode ? "left-toggle-btn" : "right-toggle-btn"
}`}
></div>
</div>
</div>
</div>
<div className="social-cards">
<div className="social-card-section">
<div className="card">
<div className="user">
<img src={fbLogo} alt="logo" />
<p>@nathnaf</p>
</div>
<div className="follower">
<h1>1987</h1>
<p>FOLLOWERS</p>
</div>
<div className="view">
<img src={upLogo} alt="up" />
<p>12 Today</p>
</div>
</div>
<div className="card">
<div className="user">
<img src={twLogo} alt="logo" />
<p>@nathnaf</p>
</div>
<div className="follower">
<h1>1044</h1>
<p>FOLLOWERS</p>
</div>
<div className="view">
<img src={upLogo} alt="up" />
<p>99 Today</p>
</div>
</div>
</div>
<div className="social-card-section">
<div className="card">
<div className="user">
<img src={igLogo} alt="logo" />
<p>@nathnaf</p>
</div>
<div className="follower">
<h1>11k</h1>
<p>FOLLOWERS</p>
</div>
<div className="view">
<img src={upLogo} alt="up" />
<p>1987 Today</p>
</div>
</div>
<div className="card">
<div className="user">
<img src={ytLogo} alt="logo" />
<p>Nathan F</p>
</div>
<div className="follower">
<h1>8239</h1>
<p>SUBSCRIBER</p>
</div>
<div className="view down">
<img src={downLogo} alt="up" />
<p>144 Today</p>
</div>
</div>
</div>
</div>
<div className="overView">
<h1>Overview - Today</h1>
</div>
<div className="reach">
<div className="analytics">
<div className="section-a">
<div className="a-card">
<div className="views">
<p>Page view</p>
<h1>87</h1>
</div>
<div className="logosImage">
<img src={fbLogo} alt="" />
<p>
<img src={upLogo} alt="" />
3%
</p>
</div>
</div>
<div className="a-card">
<div className="views">
<p>Likes</p>
<h1>52</h1>
</div>
<div className="logosImage">
<img src={fbLogo} alt="" />
<p>
<img src={upLogo} alt="" />
2%
</p>
</div>
</div>
</div>
<div className="section-a">
<div className="a-card">
<div className="views">
<p>Likes</p>
<h1>5462</h1>
</div>
<div className="logosImage">
<img src={igLogo} alt="" />
<p>
<img src={upLogo} alt="" />
2257%
</p>
</div>
</div>
<div className="a-card">
<div className="views">
<p>Page view</p>
<h1>52k</h1>
</div>
<div className="logosImage">
<img src={fbLogo} alt="" />
<p>
<img src={upLogo} alt="" />
1375%
</p>
</div>
</div>
</div>
</div>
<div className="analytics">
<div className="section-a">
<div className="a-card">
<div className="views">
<p>Retweets</p>
<h1>117</h1>
</div>
<div className="logosImage">
<img src={twLogo} alt="" />
<p>
<img src={upLogo} alt="" />
303%
</p>
</div>
</div>
<div className="a-card">
<div className="views">
<p>Likes</p>
<h1>507</h1>
</div>
<div className="logosImage">
<img src={fbLogo} alt="" />
<p>
<img src={upLogo} alt="" />
303%
</p>
</div>
</div>
</div>
<div className="section-a">
<div className="a-card">
<div className="views">
<p>Likes</p>
<h1>107</h1>
</div>
<div className="logosImage">
<img src={ytLogo} alt="" />
<p>
<img src={downLogo} alt="" />
19%
</p>
</div>
</div>
<div className="a-card">
<div className="views">
<p>Total Views</p>
<h1>1407</h1>
</div>
<div className="logosImage">
<img src={fbLogo} alt="" />
<p>
<img src={downLogo} alt="" />
12%
</p>
</div>
</div>
</div>
</div>
</div>
<p>Made with ❤️ by Abhishek Gurjar</p>
</div>
</div>
</>
);
};
export default App;
CSS Styling
In the CSS file, we define styles for both the light and dark themes and apply them dynamically based on the body
class.
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
.body {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Inter', sans-serif;
}
.app {
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
}
.header {
width: 100%;
margin-block: 40px;
display: flex;
align-items: center;
justify-content: center;
}
.dashboard h1 {
font-size: 1.7rem;
line-height: 0;
}
.dashboard p {
font-size: 0.9rem;
color: #8b97c6;
}
.mode {
width: 50%;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 10px;
}
.mode p {
color: #8b97c6;
}
.toggle-area {
width: 50px;
height: 22px;
border-radius: 20px;
background: linear-gradient(90deg, hsl(210, 78%, 56%) 5%, hsl(146, 68%, 55%) 100%);
display: flex;
align-items: center;
}
.left-toggle-btn {
background-color: #1f212e;
width: 18px;
height: 18px;
border-radius: 50%;
margin-left: 29px;
}
.right-toggle-btn {
margin-left: 1px;
background-color: #1f212e;
width: 18px;
height: 18px;
border-radius: 50%;
}
.social-cards {
display: flex;
align-items: center;
gap: 30px;
}
.social-card-section {
display: flex;
align-items: center;
gap: 30px;
}
.card {
width: 280px;
height: 240px;
background-color: #252a41;
border-radius: 8px;
display: flex;
align-items: center;
flex-direction: column;
transition: transform 0.3s ease-in-out;
}
.card:hover {
transform: scale(1.1);
}
.user {
display: flex;
align-items: center;
gap: 10px;
}
.follower {
display: flex;
align-items: center;
flex-direction: column;
}
.follower h1 {
font-size: 60px;
line-height: 0;
}
.follower p {
font-size: 16px;
line-height: 0;
color: rgb(98, 107, 174);
letter-spacing: 2px;
}
.view {
display: flex;
align-items: center;
gap: 4px;
}
.view img {
width: 14px;
}
.view p {
color: #1eb589;
}
.overView {
width: 100%;
margin-block: 40px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 850px;
}
.overView h1 {
font-size: 1.7rem;
}
.reach {
display: flex;
align-items: center;
flex-direction: column;
gap: 30px;
margin-bottom: 100px;
}
.analytics {
display: flex;
align-items: center;
gap: 30px;
}
.section-a {
display: flex;
align-items: center;
gap: 30px;
}
.a-card {
background-color: #252a41;
width: 280px;
height: 140px;
display: flex;
align-items: center;
justify-content: space-evenly;
border-radius: 10px;
gap: 30px;
transition: transform 0.3s ease-in-out;
}
.a-card:hover {
transform: scale(1.1);
}
.logosImage p {
color: #1eb589;
}
.logosImage p img {
width: 15px;
}
.down p {
color: #dc414c;
}
@media (max-width: 1230px) {
.social-card-section {
flex-direction: column;
}
.section-a {
flex-direction: column;
}
.overView {
margin-right: 0;
}
.header {
text-align: center;
flex-direction: column;
}
.mode {
justify-content: center;
}
}
@media (max-width: 660px) {
.social-cards {
flex-direction: column;
}
.analytics {
flex-direction: column;
}
}
/* Light Mode */
.body.light .card {
background-color: #f0f2fa;
}
.body.light .a-card {
background-color: #f0f2fa;
}
.body.light .toggle-area {
background: #aeb3cb;
}
.body.light {
background-color: white;
color: black;
}
.body.dark {
background-color: #1f212e;
color: white;
}
Installation and Usage
To get started with this project, clone the repository and install the necessary dependencies:
git clone https://github.com/abhishekgurjar-in/Social-Media-Theme-Switcher.git
cd social-media-theme-switcher
npm install
npm start
This will start the development server and open the application in your default web browser.
Live Demo
Check out the live demo of the Social Media Theme Switcher here.
Conclusion
The Social Media Theme Switcher is a great project to learn about handling user preferences in React and storing data in localStorage
. You can extend this project by adding more themes or applying different styles for each theme.
Credits
- Inspiration: This project was inspired by modern social media platforms that offer a theme toggle feature to enhance the user experience.
Author
Abhishek Gurjar is a dedicated web developer passionate about building accessible and user-friendly web applications. Check out more of his work on GitHub.
Top comments (0)