Skip to content

infoxicator/gatsby-plugin-theme-switcher

Repository files navigation

Because Dark Mode is not enough!

A Gatsby plugin to switch between multiple themes, including dark mode and more! And the best part? No "white flash of death"!

theme-switcher-demo

Demo

Live Example

Example Repo

Install

yarn add gatsby-plugin-theme-switcher

Usage

Add the plugin to your gatsby-config.js.

module.exports = {
  plugins: [
    'gatsby-plugin-theme-switcher',
  ],
};

Add your themes

This plugin adds a custom class name to the body element of your site and uses CSS variables to customise your color scheme. Add your themes with the .theme-* format:

.theme-twitter {
  --color-bg-primary: #15202B;
  --color-bg-primary-light: #172D3F;
  --color-bg-accent: #1B91DA; 
  --color-bg-accent-light: #1B91DA; 
  --color-bg-secondary: #657786;
  --color-text-link: #1B91DA;    
  --color-bg-compliment: #112b48;
  --color-bg-default: #192734;
  --color-bg-inverse: #1B91DA;
  --color-text-primary: #fff;
  --color-text-secondary: #f2f2f2;
  --color-text-default: #e9e9e9;
  --color-text-default-soft: #6a6a6a;
  --color-text-inverse: #1B91DA;
  --color-text-inverse-soft: #1B91DA;
}

Switching Themes

To switch themes, use the ThemeSwitcher Context

import React, { useContext } from "react"
import { ThemeContext } from 'gatsby-plugin-theme-switcher';

const { theme, switchTheme } = useContext(ThemeContext);

Add A Theme Switcher Component

You can implement your own theme switcher component but here is a basic example:

import React from "react";

const myThemes = [
    {
        id: "theme-midnightgreen",
        name: "Midnight Green",
    },
    {
        id: "theme-spacegray",
        name: "Space Gray",
    },
    {
        id: "theme-twitter",
        name: "Twitter Dark",
    }
]

const ThemePicker = ({ theme, setTheme }) => {
    if (theme) {
        return (
            <div>
            {myThemes.map((item, index) => {
                const nextTheme = myThemes.length -1 === index ? myThemes[0].id : myThemes[index+1].id;
                
                return item.id === theme ? (
                    <div key={item.id} className={item.id}>
                    <button
                        aria-label={`Theme ${item.name}`}
                        onClick={() => setTheme(nextTheme)}
                    >
                        {item.name}
                    </button>
                    </div>
                ) : null;
                    }
                )}
            </div>
        );
    }
    return null;
};

export default ThemePicker;

Advanced Usage

Add your default theme options in gatsby-config.js.

module.exports = {
  plugins: [
   {
      resolve: 'gatsby-plugin-theme-switcher',
      options: {
        defaultDarkTheme: 'theme-dark',
        defaultLightTheme: 'theme-light',
        themeStorageKey: 'my-key',
        minify: true,
      }
    }
  ],
};

Parameters

Option Description
defaultDarkTheme Initial theme name when prefers-color-scheme: dark
defaultLightTheme Initial theme name when preference cannot be determined
themeStorageKey Key to persist the theme name in localStorage. Default = "theme".
minify Minify the injected script using Terser. Default = true.

Credit

This plugin is based on the work and inspired by Sam Larsen-Disney and Josh Comeau

LICENSE

MIT LICENSE

About

A Theme switcher plugin to enable multiple themes

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published