npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-themeit

v2.4.2

Published

themeit makes it easy to create and use different themes for your react components while using CSS Modules or JS style objects.

Downloads

26

Readme

themeit - react & css modules theming made easy

NPM Version Build Status License

themeit makes it easy to create and use different themes for your react components while using CSS Modules or JS style objects.

It's built with code splitting in mind and allows you to load only the themes you need at a time by utilizing code splitting.

You can also pass in a JS style object for themes which will be processed automatically with aphrodite.

Documentation

Installation

npm i -S react-themeit

Usage

(examples assume usage of webpack)

Component Declaration

import { themeit } from 'react-themeit';

const themeOptions = {
  base: cb => require(['./base.less'], cb),
  themes: {
    blue: cb => require(['./themes/blue.less'], cb),
    big: cb => require(['./themes/big.less'], cb),
    italic: {
      label: {
        fontStyle: 'italic'
      }
    }
  }
};

const MyComponent = props => (
  <div className={props.styles.container}>
    <label className={props.styles.label}>react-themeit</label>
  </div>
);

export default themeit(themeOptions)(MyComponent);

Component Usage

import MyComponent from './MyComponent';

export default () => (
  <MyComponent
    theme="blue big italic"
    styles={{ label: { textDecoration: 'underline' } }}
    addStyleFiles={cb => require(['./additionalStyles.less', './someMoreStyles.css'], cb) }
  />
);

Options

themeit({

  • themes (object): an object in which the keys represent theme names and the values can either be a function which should return a localized class map like { container: 'container_38h2f02h' } or a js style object like { container: { backgroundColor: '#000' } }
  • [default] (string): name of a default theme
  • [base] (func): base styles which should always be applied
  • [mergeContext (default: false)] (boolean): whether styles contexts should be merged })

A component which is wrapped with themeit accepts these additional props:

  • addStyleFiles (func): a function to pass additional theme classes to the component
  • styles (object): additional js css styles to be passed to the component (will be processed with aphrodite)

The target component will receive the combined style classes in a property called styles. It will also receive a prop named themeit which contains all options you passed to themeit and a function setTheme(name) which you can invoke to change the current theme of the component.

Automatic Storybook stories generation

If you use storybook you can use the babel plugin generate-stories to automatically generate stories for each of your components themes. Simply set the "withThemeit" option to true, make sure you're using themeit >= 2.4.0 and you're all set!

This will auto generate stories like this:

- theme: theme1
- theme: theme2
- theme: theme3

Passing style information down to child components

If you want to style nested components, react-themeit makes it super-simple to handle even more complex scenarios. You have two options for different situations:

Utilizing React Context

When you wrap a component with themeit(opts)(Comp), themeit will put the styles object which the component receives as a property into the child context too.

This means that all child components may access the same styles object (which contains all the classnames) via context.

To do this, you'd define your child component like so:

import React, { Component, PropTypes } from 'react';

const MyComponent = (props, context) => (
  <div className={context.styles.container} />
);

MyComponent.contextTypes = {
  styles: PropTypes.object
}

Nested themeable components

If you use themeit to wrap your child components too, there might be two ways you'd like themeit to handle context and passed style information:

a) Merge the eventual context.styles information from parent themeit components.

import React, { Component, PropTypes } from 'react';
import { themeit } from 'react-themeit';

const themeOptions = {
  mergeContext: true
};

const MyComponent = (props, context) => (
  <div className={context.styles.container} />
);

MyComponent.contextTypes = {
  styles: PropTypes.object
}

export default themeit(themeOptions)(MyComponent)

When is this useful? Imagine you have a calculator widget where the calculater itself is a themeable component and the individual keys in the calculator component are also themeable components.

You might want to define themes / style information for the keys with themeit. If you were to use the calculator widget however, you'd also want to pass new/additional style information for the keys to the calculator widget.

One way to deal with this would be to accept a separate prop like stylesForKeys or addStyleFilesForKeys and pass these props down to each individual key. However, this sucks.

Instead, you may just use the addStyleFiles prop to pass style information for the whole widget + its themeable child components. And utilize the mergeContext option to merge all style information for the Key components.

b) Ignore parent styles information and create a new styles context from the component

If you'd like to completely ignore parent styles information, you can just use themeit as usual. By default, it won't merge style information for nested themed components.

This is important, since it could lead to unwanted behavior when you use the same class names (e.g. "container") for totally different components. That's why themeit wants you to explicitly activate the behavior of merging styles information for nested themeable components.

FAQ

Does it work with hot reloading / HMR ?

Yes. Configuring async css files for HMR require a bit of more code though. To make it easier and shorter, react-themeit exports a hot(...) function which can be used.

Check this snippet for example:

import { themeit, hot } from 'react-themeit';

const themeOptions = {
  base: cb => require(['./base.less'], s => {
    hot(s, cb, c => module.hot.accept('./base.less', c))
  }),
  themes: {
    blue: cb => require(['./themes/blue.less'], cb)
  }
};

In this case, only the base .less will be hot reloadable. The hot function automatically checks whether module.hot is defined and only enables HMR if it is.

About

Initially built for use in the ovos play game designer to allow designers and developers to easily work together.

Contributions are very welcome!

License

MIT License