The approach never fully solved the problem => Project archived!
BETA VERSION: Not released yet! See issue #1
This module allows for a seamless integration of CSS-Modules
(also known as local CSS) with React components. It provides a styleName attribute for any JSX element,
which automatically maps styles from a CSS-Modules object to the className attribute.
It is an improved version of React CSS Modules. Please compare alternatives.
As a prerequisite you need to have the following things installed and configured in your project:
- Babel in version 6 and above
- A CSS-Module aware bundler:
Install via npm:
npm install --save react-stylename
Configure React StyleName as Babel plugin, which you would typically do in your .babelrc:
{
"presets": ["react", "es2015"],
"plugins": [
"babel-plugin-transform-decorators-legacy",
"react-stylename/lib/transform"
]
}
React StyleName can be used as decorator for your ES6 classes. Full example:
import React, {Component} from "react";
import StyleName from "react-stylename";
import styles from "./myComponent.scss";
// example for styles content:
// styles = {
// "ci-heading": "ci-heading_32osj",
// "ci-bold": "ci-bold_2w27N"
// }
@StyleName(styles)
class MyComponent extends Component {
render() {
return <div styleName="ci-heading ci-bold" />
// this will transform to:
// return <div className="ci-heading_32osj ci-bold_2w27n" />
}
}
export default MyComponent;
React StyleName can also be called programmatically, e.g. for stateless functions:
import React from "react";
import StyleName from "react-stylename";
import styles from "./myComponent.less";
const MyComponent = function(
return <div styleName="" />
);
exports.MyComponent = StyleName(MyComponent, styles);
NOTE: This technique won't work for arrow functions: See Caveats.
Under the hoods, React StyleName is using classnames to concatenate multiple styleNames. So it is readily available and should be used for conditional logic regarding styleNames:
import StyleName, {joinNames} from "react-stylename";
const x = "2";
const styleNames = joinNames(
"ci-test-1",
`ci-test$-{x}`,
["ci-test-3", "ci-test-4"],
{"ci-test-5": true, "ci-test-6": false},
false
);
// result:
// styleNames = "ci-test-1 ci-test-2 ci-test-3 ci-test-4 ci-test-5"
- Falsy values (null, undefined, empty string, ...) supplied to the
styleNameattribute will not get rendered asclassNamevalue - Style names which don't have any mapping in the provided CSS module style object will not get rendered
as
classNamevalue; additionallyReact StyleNamewill warn about those unknown style names - Values of an existing
classNameattribute are respected and always come first - If no
classNameattribute exists, it won't be generated if only falsy or unknown styleNames are provided
Stateless functions which are defined as arrow functions cannot be decorated at the moment.
I don't have a strong opinion about this, but at least using arrow functions for stateless functions has the drawback that you cannot identify your components in React Dev Tools: Arrow functions are anonymous by definition.
If you're lacking this feature, please open an issue.
The core idea of using styleName as mapping source for CSS-Modules styles stems from
React CSS Modules.
In contrast to React CSS Modules React StyleName transforms the styleName attribute via Babel
to the className attribute. This approach results in
- better runtime performance, since decorated classes and functions don't need to be wrapped
- is not restricted to the
renderfunction (see this section of the documentation)
The classnames library is a super useful tool to concatenate class names and it allows for conditional logic. It also has a binding feature for CSS-Modules styles.
React StyleName uses classnames internally and also exposes it. Actually this tiny library could serve all your needs. It falls short, however, for my needs, i.e. in regards to the following two points:
- convenience: the main use case is simply to use one simple string; additionally
styleNamevs.classNamereally highlights the distinction between local and global css class names. - behavior: classnames returns style names which don't have any mapping in the provided CSS module style object. React StyleName drops those unknown style names and warns about them (see Behavior)