All Projects → flipace → react-themeit

flipace / react-themeit

Licence: MIT license
An easy way to theme your components using css modules and js css objects thanks to aphrodite. Also works with asynchronously loaded styles!

Programming Languages

javascript
184084 projects - #8 most used programming language
shell
77523 projects
CSS
56736 projects

Projects that are alternatives of or similar to react-themeit

React Ssr Setup
React Starter Project with Webpack 4, Babel 7, TypeScript, CSS Modules, Server Side Rendering, i18n and some more niceties
Stars: ✭ 678 (+2321.43%)
Mutual labels:  hmr, css-modules
posthtml-css-modules
Use CSS modules in HTML
Stars: ✭ 54 (+92.86%)
Mutual labels:  css-modules
Template Rwb
A full-featured Webpack setup with hot-reload
Stars: ✭ 165 (+489.29%)
Mutual labels:  hmr
react-css-modules-intellij-plugin
React CSS Modules support in IntelliJ IDEA and WebStorm for components written in JavaScript and TypeScript.
Stars: ✭ 41 (+46.43%)
Mutual labels:  css-modules
Koa Webpack Middleware
webpack dev&hot middleware for koa2
Stars: ✭ 215 (+667.86%)
Mutual labels:  hmr
webpack-boilerplate
Webpack 4 boilerplate (babel, eslint, prettier, jest, sass, postcss, hmr, browsersync)
Stars: ✭ 33 (+17.86%)
Mutual labels:  hmr
Create Elm App
🍃 Create Elm apps with zero configuration
Stars: ✭ 1,650 (+5792.86%)
Mutual labels:  hmr
nextjs-with-jest-typescript
A very simple example of Next.js-based website with Jest tests, all written in TypeScript
Stars: ✭ 70 (+150%)
Mutual labels:  css-modules
vital
Starter template for Vite with React (TypeScript). Supports Tailwind with CSS-Modules. Jest and @react/testing-library configured and ready to go. Also ESLint, Prettier, Husky, Commit-lint and Atomic Design for components.
Stars: ✭ 151 (+439.29%)
Mutual labels:  css-modules
webpack-hmr
🔨Easy implementation of webpack Hot-Module-Replacement(hmr)
Stars: ✭ 120 (+328.57%)
Mutual labels:  hmr
koa-webpack-server
Koa2 webpack all-in-one environment for universal development
Stars: ✭ 14 (-50%)
Mutual labels:  hmr
React Starter Kit
React, Redux, Webpack, Material UI, Boostrap 4, Code Splitting, HMR
Stars: ✭ 229 (+717.86%)
Mutual labels:  hmr
next-plugin-antd
A @zeit/next-less patch with full support for Ant Design, Less and CSS modules
Stars: ✭ 27 (-3.57%)
Mutual labels:  css-modules
React Hot Loader Loader
A Webpack Loader that automatically inserts react-hot-loader to your App 👨‍🔬
Stars: ✭ 176 (+528.57%)
Mutual labels:  hmr
Mailbox
🌸🎉使用react+redux+webpack搭建的邮箱应用🎉🌸
Stars: ✭ 16 (-42.86%)
Mutual labels:  css-modules
Kirby Webpack
💪 A Kirby CMS starter-kit with modern frontend tools
Stars: ✭ 150 (+435.71%)
Mutual labels:  hmr
Prefresh
Hot Module Reloading for Preact
Stars: ✭ 247 (+782.14%)
Mutual labels:  hmr
rollup-plugin-stylus-css-modules
A Rollup.js plugin to compile Stylus and inject CSS Modules
Stars: ✭ 15 (-46.43%)
Mutual labels:  css-modules
react-ui-kit-boilerplate
A minimal React UI Kit boilerplate with Storybook, hot reloading, Styled Components, Typescript and Jest
Stars: ✭ 88 (+214.29%)
Mutual labels:  hmr
hot-redux-chassis
Modern React/Redux/RxJS application using all the latest and greatest stuff from the community 🔥
Stars: ✭ 20 (-28.57%)
Mutual labels:  css-modules

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.

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].