1.0.0 • Published 7 years ago

provide-theme v1.0.0

Weekly downloads
1
License
MIT
Repository
github
Last release
7 years ago

provide-theme

build status npm version npm downloads

Provides interchangeable themes as classes, images, and icons to React components.

Each theme should simply be a bundled CSS file and a bundled JS file containing a mapping of the class names (as classes), at the very least. This means you can bundle your themes using plain CSS, inline styles, css-modules, jss, or any other format of your choosing. The system behind this provider is designed with code-splitting in mind so that you're only loading the selected theme when you need it.

Table of contents

  1. Installation
  2. Actions
  3. Reducers
  4. Hot reloading
  5. Quick example
  6. Full example with server rendering

Installation

npm install provide-theme --save

Actions

Your components may be provided the following actions as propTypes:

setThemes (Object themes)

This should typically only be used server-side. You probably won't ever need to call this action since your themes reducer is typically set via the initial state.

setThemesFiles (Object themesFiles)

You probably won't ever need to call this action as well, since your themesFiles reducer is typically set via the initial state. The client uses the themesFiles reducer to know which files to load for their selected theme.

initTheme (String themeName, Object themeFiles, Object theme)

This is typically used to initialize the theme before rendering the app so that components can immediately have the the theme's classes, images, icons, etc. It is automatically called via an enhancer when the store is created. On the client, it will find any matching link and script elements matching the themeFiles so that their respective reducers may be properly initialized after server-side rendering.

loadTheme (String themeName, Object themeFiles)

This is typically used client-side to load a theme dynamically and is likely the only action you'll ever need to call within your components.

Reducers

Your components may also be provided the following reduced propTypes:

themes

An object containing all themes. You'll probably never need this, and if you do, it is probably best to limit it to the server.

themesFiles

An object containing a mapping of the themes' names to their respective jsFile and cssFile. You probably won't use this within your components, as it's mostly used internally for dynamically loading themes on the client.

themeFiles

An object containing the currently selected theme's jsFile and cssFile. You probably won't use this within your components, as it's mostly used internally for dynamically loading themes on the client.

themeName

The currently selected theme's name.

theme

This object contains the currently selected theme's properties: classes, images, icons, and any other custom properties you may need.

classes

A mapping of simplified class names to their namespaced versions. Derived from the theme object. This has its own reducer to minimize the amount of boilerplate required when retrieving your theme's properties within your components.

images

Derived from the theme object. This has its own reducer to minimize the amount of boilerplate required when retrieving your theme's properties within your components.

icons

Derived from the theme object. This has its own reducer to minimize the amount of boilerplate required when retrieving your theme's properties within your components.

link

The current theme's respective link element, mostly used internally when dynamically loading themes on the client. This element gets removed and another put in its place when changing themes.

script

The current theme's respective script element, mostly used internally when dynamically loading themes on the client. This element gets removed and another put in its place when changing themes.

Hot reloading

This provider includes an export you can use to hot reload your bundled themes when in the development environment.

reloadTheme (String themeName, Object theme)

You can use this with something like webpack's module.hot.accept function.

// src/themes/dark/dark.js

import classes from './dark.css';

export default {
  classes
};

if (process.env.NODE_ENV !== 'production') {
  if (module.hot) {
    const reloadTheme = require('provide-theme').reloadTheme;

    module.hot.accept('./dark.css', () => {
      reloadTheme('DarkTheme', {
        classes: require('./dark.css')
      });
    });
  }
}

Quick example

import React from 'react';
import { render } from 'react-dom';
import { App } from './components/index';
import * as providers from './providers/index';
import themesFiles from './themes/files';

const themeName = Object.keys(themesFiles).shift();
const themeFiles = themesFiles[themeName];

const defaultProps = {
  providers: {
    ...providers,
    theme: {
      ...providers.theme,
      state: {
        themesFiles,
        themeFiles,
        themeName
      }
    }
  }
};

render(<App { ...defaultProps } />, document.getElementById('root'));

And for an example of bundled themes in their most basic form, see test/themes.

And for an example of how to select a different theme, see bloggur's ThemeSelector component.

Full example with server rendering

See bloggur. Protip: Remember that you can include images with your theme's bundle and that React can handle svg (vector graphics) elements, so it's good practice to use them where possible!