Skip to content

arham766/Toogle_theme

Repository files navigation

Theme Switcher - Project Documentation

Table of Contents

  1. Overview
  2. Project Structure
  3. Installation
  4. Features
  5. Component Architecture
  6. Theme System
  7. Usage Guide
  8. Customization
  9. API Reference
  10. Troubleshooting
  11. Best Practices
  12. Contributing
  13. Advanced Configuration
  14. Additional Resources

1. Overview

Theme Switcher is a React application that allows users to switch between multiple themes with both light and dark modes. It features a responsive design, customizable UI elements, and persistent user preferences. The project leverages JSON for dynamic theme management, enabling easy addition and modification of themes without altering the core application code.

Tech Stack:

  • React 18+
  • Tailwind CSS
  • Lucide React (for icons)
  • JSON for external theme definitions

2. Project Structure

The project is organized to separate concerns clearly, with a focus on maintainability and scalability.

theme-switcher/
├── node_modules/
├── public/
│   ├── index.html
│   ├── favicon.ico
│   ├── manifest.json
│   └── themes.json           # <-- External theme definitions
├── src/
│   ├── components/           # Reusable React components
│   │   ├── Header.jsx
│   │   ├── CustomizationModal.jsx
│   │   ├── InteractiveCard.jsx
│   │   ├── ThemeCarousel.jsx
│   │   └── ThemePreview.jsx
│   ├── App.jsx               # Main application component
│   ├── index.js              # Entry point
│   └── index.css             # Tailwind CSS imports
├── package.json              # Dependencies and scripts
├── tailwind.config.js        # Tailwind configuration
└── README.md                 # Project documentation

3. Installation

Follow these steps to set up and run the Theme Switcher project locally.

Prerequisites

  • Node.js (v14.0.0 or higher)
  • npm (v6.0.0 or higher)

Steps

  1. Clone the Repository

    git clone <repository-url>
    cd theme-switcher
  2. Install Dependencies

    npm install
  3. Add themes.json

    • Ensure that themes.json is placed inside the public/ directory. An example themes.json is provided below.
  4. Start Development Server

    npm start
  5. Build for Production

    npm run build
    • The optimized production build will be in the build/ directory.

Common Issues During Installation

  • 404 Errors When Loading themes.json
    • Ensure that themes.json is correctly placed in the public/ directory.
    • Verify that the file is named exactly themes.json (case-sensitive).
    • Check for correct JSON syntax to prevent parsing errors.

4. Features

Core Features

  • Dynamic Theme Loading: Themes are defined externally in a JSON file, allowing easy additions and modifications.
  • Multiple Theme Options: Supports various themes with light and dark variants.
  • Persistent Preferences: User-selected themes and customization settings are saved in localStorage.
  • Responsive Design: Optimized for various screen sizes.
  • Customizable UI Elements: Adjust font sizes and spacing preferences.
  • Interactive Previews: Real-time preview of themes and customizations.

Theme Options

  • Classic Light/Dark
  • Warm Light/Dark
  • Cool Light/Dark
  • Forest Light/Dark
  • Rose Light/Dark
  • And more variations (e.g., Ocean Light/Dark)

Customization Options

  • Font Size Adjustment: Choose between small, medium, and large font sizes.
  • Spacing Controls: Adjust spacing levels to suit your preference.
  • Color Scheme Selection: Pick from a range of predefined color schemes.
  • Layout Preferences: Modify layout settings as needed.

5. Component Architecture

The application is built using modular React components, each responsible for specific functionality.

Main Components

App
├── ThemeContext.Provider
│   ├── Header
│   │   └── SettingsModal
│   └── ThemeCarousel
       └── ThemePreview

State Management

  • React Context: Utilized for theme management and passing down state through the component tree.
  • Local Storage: Used to persist user preferences across sessions.
  • Component-Level State: Manages UI interactions within individual components.

6. Theme System

External Theme Definitions with JSON

Themes are now managed externally using a themes.json file located in the public/ directory. This approach allows for easy scalability and maintenance.

Theme Structure (themes.json)

{
  "light1": {
    "name": "Classic Light",
    "colors": {
      "primary": "#2563eb",
      "background": "#ffffff",
      "text": "#1f2937",
      "secondary": "#f3f4f6",
      "accent": "#3b82f6"
    }
  },
  "light2": {
    "name": "Warm Light",
    "colors": {
      "primary": "#d97706",
      "background": "#fffbeb",
      "text": "#292524",
      "secondary": "#fef3c7",
      "accent": "#f59e0b"
    }
  },
  "light3": {
    "name": "Cool Light",
    "colors": {
      "primary": "#0891b2",
      "background": "#f0fdfa",
      "text": "#134e4a",
      "secondary": "#ccfbf1",
      "accent": "#06b6d4"
    }
  },
  "light4": {
    "name": "Forest Light",
    "colors": {
      "primary": "#059669",
      "background": "#f0fdf4",
      "text": "#064e3b",
      "secondary": "#dcfce7",
      "accent": "#10b981"
    }
  },
  "light5": {
    "name": "Rose Light",
    "colors": {
      "primary": "#e11d48",
      "background": "#fff1f2",
      "text": "#881337",
      "secondary": "#ffe4e6",
      "accent": "#f43f5e"
    }
  },
  "dark1": {
    "name": "Classic Dark",
    "colors": {
      "primary": "#60a5fa",
      "background": "#1f2937",
      "text": "#f3f4f6",
      "secondary": "#374151",
      "accent": "#3b82f6"
    }
  },
  "dark2": {
    "name": "Deep Dark",
    "colors": {
      "primary": "#8b5cf6",
      "background": "#18181b",
      "text": "#fafafa",
      "secondary": "#27272a",
      "accent": "#a78bfa"
    }
  },
  "dark3": {
    "name": "Midnight",
    "colors": {
      "primary": "#6366f1",
      "background": "#020617",
      "text": "#e2e8f0",
      "secondary": "#1e293b",
      "accent": "#818cf8"
    }
  },
  "dark4": {
    "name": "Forest Dark",
    "colors": {
      "primary": "#10b981",
      "background": "#022c22",
      "text": "#ecfdf5",
      "secondary": "#064e3b",
      "accent": "#34d399"
    }
  },
  "dark5": {
    "name": "Ruby Dark",
    "colors": {
      "primary": "#f43f5e",
      "background": "#1c1917",
      "text": "#fecdd3",
      "secondary": "#292524",
      "accent": "#fb7185"
    }
  }
}

Theme Loading Mechanism

  1. Fetch themes.json:

    • The application fetches themes.json from the public/ directory during initialization.
  2. Parse and Store Themes:

    • Parsed themes are stored in the application state and provided via React Context.
  3. Dynamic Theme Application:

    • Components consume the current theme from Context and apply styles accordingly.

Advantages of Using JSON:

  • Scalability: Easily add or modify themes without altering application code.
  • Maintainability: Centralized theme definitions simplify management.
  • Flexibility: Supports nested properties and complex data structures.

7. Usage Guide

Basic Usage

  1. Start the Application
    npm start
  2. Access the Application
  3. Switch Themes
    • Use the theme carousel to browse and select different themes.
  4. Customize Settings
    • Click the settings icon in the header to adjust font sizes and spacing preferences.
  5. Interact with UI Elements
    • Explore interactive components like buttons and color palettes to see the active theme in action.

Adding New Themes

  1. Update themes.json

    • Open public/themes.json and add a new theme following the existing structure.

    Example: Adding "Ocean Light" and "Ocean Dark" Themes

    {
      "light6": {
        "name": "Ocean Light",
        "colors": {
          "primary": "#0ea5e9",
          "background": "#e0f2fe",
          "text": "#034e7b",
          "secondary": "#bae6fd",
          "accent": "#0284c7"
        }
      },
      "dark6": {
        "name": "Ocean Dark",
        "colors": {
          "primary": "#0284c7",
          "background": "#0e7490",
          "text": "#f0fdfa",
          "secondary": "#075985",
          "accent": "#0369a1"
        }
      }
    }
    • Ensure that each new theme has a unique key and includes all required color properties.
  2. Save themes.json

    • Changes to themes.json are automatically fetched when the application reloads.
  3. Reload the Application

    • Refresh your browser to see the new themes appear in the carousel.

Customizing UI Elements

  1. Open Settings Modal
    • Click the settings icon in the header.
  2. Adjust Font Size
    • Select between small, medium, or large font sizes.
  3. Adjust Spacing
    • Use the slider to modify spacing levels.
  4. Save Changes
    • Click "Save Changes" to apply and persist your preferences.

Persistent Preferences

  • User selections for theme, font size, and spacing are saved in localStorage and persist across sessions.

8. Customization

Adding New Themes via themes.json

  1. Open themes.json

    • Located in the public/ directory.
  2. Add a New Theme Entry

    • Follow the existing structure to define a new theme.

    Example: Adding "Sunset Light" and "Sunset Dark" Themes

    {
      "light7": {
        "name": "Sunset Light",
        "colors": {
          "primary": "#fb923c",
          "background": "#fff7ed",
          "text": "#7c2d12",
          "secondary": "#fef3c7",
          "accent": "#ea580c"
        }
      },
      "dark7": {
        "name": "Sunset Dark",
        "colors": {
          "primary": "#ea580c",
          "background": "#7c2d12",
          "text": "#fef3c7",
          "secondary": "#a16207",
          "accent": "#c2410c"
        }
      }
    }
  3. Save and Refresh

    • Save themes.json and refresh the application to see the new themes.

Custom Components

Ensure that any custom components utilize the current theme from ThemeContext for styling.

Example: Creating a Custom Component with Dynamic Styles

import React, { useContext } from 'react';
import { ThemeContext } from './App';

const CustomButton = () => {
  const { currentTheme, themes } = useContext(ThemeContext);

  return (
    <button
      className="px-4 py-2 rounded text-white"
      style={{ backgroundColor: themes[currentTheme].colors.primary }}
    >
      Custom Button
    </button>
  );
};

export default CustomButton;

9. API Reference

ThemeContext

Provides theme-related data and functions to the application.

{
  currentTheme: string,         // Current active theme key
  setCurrentTheme: function,    // Function to update the current theme
  isDark: boolean,              // Indicates if the current theme is dark
  toggleDark: function,         // Function to toggle between light and dark themes
  fontSize: string,             // Current font size setting ('small', 'medium', 'large')
  setFontSize: function,        // Function to update font size
  spacing: number,              // Current spacing level (1-8)
  setSpacing: function,         // Function to update spacing
  themes: object                // Object containing all theme definitions
}

Theme Object Structure

Defines the properties of each theme.

{
  "light1": {
    "name": "Classic Light",
    "colors": {
      "primary": "#2563eb",
      "background": "#ffffff",
      "text": "#1f2937",
      "secondary": "#f3f4f6",
      "accent": "#3b82f6"
    }
  },
  // ...additional themes
}

Properties:

  • name: Human-readable name of the theme.
  • colors: Object containing color properties.
    • primary: Main color for primary actions.
    • background: Background color of the application.
    • text: Primary text color.
    • secondary: Secondary color for less prominent elements.
    • accent: Accent color for highlights and emphasis.

10. Troubleshooting

A. 404 Errors When Loading themes.json

  • Issue: The application fails to fetch themes.json, resulting in a 404 error.

  • Possible Causes:

    1. Incorrect File Placement
      • Ensure themes.json is located in the public/ directory.
    2. Incorrect File Naming
      • Verify the file is named exactly themes.json (case-sensitive).
    3. JSON Syntax Errors
      • Ensure themes.json is valid JSON. Use a JSON validator if necessary.
    4. Server Issues
      • If running a local server, ensure it's correctly serving the public/ directory.
  • Solutions:

    1. Verify File Location
      • Confirm that public/themes.json exists.
    2. Check File Naming
      • Ensure there are no typos in the filename.
    3. Validate JSON
      • Use tools like JSONLint to validate the syntax.
    4. Restart Development Server
      • Sometimes, restarting the server can resolve path issues.
      npm start

B. Themes Not Applying Correctly

  • Issue: Selected themes do not reflect the defined colors or styles.

  • Possible Causes:

    1. Incorrect Theme Key
      • Ensure the theme key used in setCurrentTheme matches one in themes.json.
    2. Missing Color Properties
      • Each theme must include all required color properties (primary, background, text, secondary, accent).
    3. Caching Issues
      • Browser caching might prevent updated themes from loading.
  • Solutions:

    1. Verify Theme Keys
      • Check that theme keys are consistent across themes.json and the application.
    2. Ensure Complete Theme Definitions
      • All themes should include all necessary color properties.
    3. Clear Browser Cache
      • Clear cache or perform a hard refresh to load the latest themes.json.
      • Hard Refresh Shortcut:
        • Windows/Linux: Ctrl + F5
        • Mac: Cmd + Shift + R

C. Application Crashes or Fails to Render

  • Issue: The application encounters errors during runtime, causing it to crash or fail to render.

  • Possible Causes:

    1. Malformed themes.json
      • Syntax errors or missing properties can cause parsing issues.
    2. Incorrect Context Usage
      • Components might not be correctly consuming ThemeContext.
    3. State Initialization Issues
      • Themes may not be loaded before components try to access them.
  • Solutions:

    1. Validate themes.json
      • Ensure JSON is well-formed and complete.
    2. Check Context Providers and Consumers
      • Verify that all components accessing ThemeContext are wrapped within the provider.
    3. Implement Loading States
      • Ensure the application waits for themes to load before rendering dependent components.

D. Styles Not Updating After Theme Change

  • Issue: Changing themes does not update the UI as expected.

  • Possible Causes:

    1. Inline Styles Not Applied Correctly
      • Ensure that components are applying styles based on the current theme.
    2. Incorrect State Updates
      • The state might not be updating correctly when a new theme is selected.
  • Solutions:

    1. Review Style Bindings
      • Check that styles are dynamically bound to themes[currentTheme].colors.
    2. Ensure Proper State Management
      • Verify that setCurrentTheme correctly updates the state and triggers re-renders.

11. Best Practices

A. Code Style

  • Meaningful Component Names
    • Use descriptive names for components to enhance readability.
  • Follow React Hooks Rules
    • Adhere to the rules of hooks to prevent unexpected behavior.
  • Consistent Formatting
    • Maintain uniform code formatting using tools like Prettier.
  • Comment Complex Logic
    • Add comments to explain non-trivial parts of the code.

B. Performance Optimization

  • Optimize Re-Renders
    • Use React.memo or useMemo where appropriate to prevent unnecessary re-renders.
  • Lazy Load Components
    • Implement code-splitting for large components to improve initial load times.
  • Memoization
    • Utilize useCallback and useMemo to memoize functions and values.
  • Minimize Bundle Size
    • Remove unused dependencies and optimize imports.

C. Accessibility

  • Semantic HTML
    • Use appropriate HTML elements to convey meaning.
  • Color Contrast
    • Ensure sufficient contrast between text and background colors for readability.
  • Keyboard Navigation
    • Make interactive elements accessible via keyboard.
  • ARIA Labels
    • Implement ARIA attributes to enhance screen reader compatibility.

12. Contributing

A. Development Process

  1. Fork the Repository
  2. Create a Feature Branch
    git checkout -b feature/your-feature-name
  3. Make Changes
  4. Commit Changes
    git commit -m "Add your descriptive commit message"
  5. Push to Forked Repository
    git push origin feature/your-feature-name
  6. Submit a Pull Request
    • Provide a clear description of the changes and reference any relevant issues.

B. Code Standards

  • Follow ESLint Configuration
    • Adhere to the project's ESLint rules for consistent code quality.
  • Meaningful Commit Messages
    • Write clear and concise commit messages that describe the changes.
  • Include Tests for New Features
    • Ensure new features are accompanied by relevant tests.
  • Update Documentation
    • Reflect any changes or additions in the project documentation.

C. Testing

# Run tests
npm test

# Run linter
npm run lint

# Check formatting
npm run format

13. Advanced Configuration

A. Environment Variables

Manage configuration settings using environment variables.

REACT_APP_THEME_STORAGE_KEY=theme_preference
REACT_APP_DEFAULT_THEME=light1

B. Build Configuration

Customize build processes for different environments.

# Development build
npm run build:dev

# Production build
npm run build:prod

# Generate stats
npm run build:stats

C. Deployment

Deploy the production build to your chosen hosting service.

# Build for production
npm run build

# Deploy to hosting service
npm run deploy

D. Custom Build Scripts

Define additional scripts in package.json for specialized build tasks.

"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "build:dev": "react-scripts build --mode development",
  "build:prod": "react-scripts build --mode production",
  "build:stats": "react-scripts build --stats",
  "deploy": "your-deployment-script-here",
  "test": "react-scripts test",
  "lint": "eslint ./src",
  "format": "prettier --write ./src"
}

14. Additional Resources


15. Complete themes.json File

Ensure that your themes.json file is correctly formatted and placed inside the public/ directory. Below is the complete themes.json based on your initial theme definitions, along with examples of how to add new themes.

public/themes.json

{
  "light1": {
    "name": "Classic Light",
    "colors": {
      "primary": "#2563eb",
      "background": "#ffffff",
      "text": "#1f2937",
      "secondary": "#f3f4f6",
      "accent": "#3b82f6"
    }
  },
  "light2": {
    "name": "Warm Light",
    "colors": {
      "primary": "#d97706",
      "background": "#fffbeb",
      "text": "#292524",
      "secondary": "#fef3c7",
      "accent": "#f59e0b"
    }
  },
  "light3": {
    "name": "Cool Light",
    "colors": {
      "primary": "#0891b2",
      "background": "#f0fdfa",
      "text": "#134e4a",
      "secondary": "#ccfbf1",
      "accent": "#06b6d4"
    }
  },
  "light4": {
    "name": "Forest Light",
    "colors": {
      "primary": "#059669",
      "background": "#f0fdf4",
      "text": "#064e3b",
      "secondary": "#dcfce7",
      "accent": "#10b981"
    }
  },
  "light5": {
    "name": "Rose Light",
    "colors": {
      "primary": "#e11d48",
      "background": "#fff1f2",
      "text": "#881337",
      "secondary": "#ffe4e6",
      "accent": "#f43f5e"
    }
  },
  "dark1": {
    "name": "Classic Dark",
    "colors": {
      "primary": "#60a5fa",
      "background": "#1f2937",
      "text": "#f3f4f6",
      "secondary": "#374151",
      "accent": "#3b82f6"
    }
  },
  "dark2": {
    "name": "Deep Dark",
    "colors": {
      "primary": "#8b5cf6",
      "background": "#18181b",
      "text": "#fafafa",
      "secondary": "#27272a",
      "accent": "#a78bfa"
    }
  },
  "dark3": {
    "name": "Midnight",
    "colors": {
      "primary": "#6366f1",
      "background": "#020617",
      "text": "#e2e8f0",
      "secondary": "#1e293b",
      "accent": "#818cf8"
    }
  },
  "dark4": {
    "name": "Forest Dark",
    "colors": {
      "primary": "#10b981",
      "background": "#022c22",
      "text": "#ecfdf5",
      "secondary": "#064e3b",
      "accent": "#34d399"
    }
  },
  "dark5": {
    "name": "Ruby Dark",
    "colors": {
      "primary": "#f43f5e",
      "background": "#1c1917",
      "text": "#fecdd3",
      "secondary": "#292524",
      "accent": "#fb7185"
    }
  },
  "light6": {
    "name": "Ocean Light",
    "colors": {
      "primary": "#0ea5e9",
      "background": "#e0f2fe",
      "text": "#034e7b",
      "secondary": "#bae6fd",
      "accent": "#0284c7"
    }
  },
  "dark6": {
    "name": "Ocean Dark",
    "colors": {
      "primary": "#0284c7",
      "background": "#0e7490",
      "text": "#f0fdfa",
      "secondary": "#075985",
      "accent": "#0369a1"
    }
  },
  "light7": {
    "name": "Sunset Light",
    "colors": {
      "primary": "#fb923c",
      "background": "#fff7ed",
      "text": "#7c2d12",
      "secondary": "#fef3c7",
      "accent": "#ea580c"
    }
  },
  "dark7": {
    "name": "Sunset Dark",
    "colors": {
      "primary": "#ea580c",
      "background": "#7c2d12",
      "text": "#fef3c7",
      "secondary": "#a16207",
      "accent": "#c2410c"
    }
  }
}

Notes:

  • Unique Keys: Ensure each theme has a unique key (e.g., light1, dark1, light6, etc.).
  • Complete Properties: Every theme must define all required color properties (primary, background, text, secondary, accent).
  • JSON Syntax: Maintain correct JSON syntax to prevent parsing errors.

16. Final Verification and Running the Project

After setting up themes.json and updating App.jsx, follow these steps to ensure everything works correctly.

Steps to Rebuild and Run the Project

  1. Navigate to Project Directory

    cd path/to/theme-switcher
  2. Install Dependencies

    npm install
  3. Start Development Server

    npm start
    • Open http://localhost:3000 in your browser.
    • Ensure that the application loads without 404 errors.
    • Verify that themes are correctly loaded and selectable from the carousel.
  4. Build for Production

    npm run build
    • This creates an optimized build in the build/ directory.
    • Deploy the contents of build/ to your preferred hosting service.

Addressing Common Build Issues

  • 404 Errors for themes.json

    • Ensure Correct Placement: themes.json must be inside the public/ directory.
    • Check File Naming: The file should be named exactly themes.json.
    • Validate JSON: Use a JSON validator to ensure there are no syntax errors.
    • Restart Server: Sometimes, restarting the development server can resolve path-related issues.
      npm start
  • Styles Not Applying Correctly

    • Verify Theme Keys: Ensure the theme keys used in the application match those in themes.json.
    • Inspect Elements: Use browser developer tools to check if styles are correctly applied based on the selected theme.
    • Clear Cache: Perform a hard refresh to eliminate cached data.
      • Windows/Linux: Ctrl + F5
      • Mac: Cmd + Shift + R
  • Application Crashes or Fails to Render

    • Check Console for Errors: Look for any runtime errors in the browser console.
    • Ensure Proper Context Usage: All components relying on ThemeContext should be correctly wrapped within the provider.
    • Validate Theme Data: Ensure all themes have the necessary properties to prevent undefined errors.

17. Conclusion

By transitioning to JSON-based theme management, the Theme Switcher project has become more scalable and maintainable. This setup allows you to effortlessly add, modify, or remove themes by simply updating the themes.json file without delving into the core application code. Additionally, leveraging React Context ensures seamless propagation of theme data across the component tree, enhancing the application's responsiveness and user experience.

Key Benefits:

  • Scalability: Easily manage a growing number of themes.
  • Maintainability: Centralized theme definitions simplify updates.
  • Flexibility: Supports complex and nested theme properties.
  • User Experience: Persistent preferences and real-time customization enhance usability.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors