gajus / babel-plugin-react-css-modules

Transforms styleName to className using compile time CSS module resolution.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Establish a convention for extending the styles object at the runtime

gajus opened this issue · comments

react-css-modules uses styles property to overwrite the default component styles.

generateClassName could look for props.styles and this.props.styles when constructing the className value to determine whether a style needs to be overwritten.

There could be an option to force use of generateClassName even when styleName is a string literal value.

I came up with a style like this that i'm extremely happy with

import cx from "classnames";
function mergeStyles(...styles) {
    const style = {};
    const cxStyle = cx.bind(style);
    for (const sty of styles) {
        if (!sty) {
            continue;
        }
        for (const [key, val] of Object.entries(sty)) {
            if (style[key]) {
                style[key] += ' ' + val;
            } else {
                style[key] = val;
            }
            cxStyle[key] = style[key];
        }
    }
    return cxStyle;
};

In my comp I then do

import styles from "./mainStyles.css";
import otherStyles from "./otherStyles.css";

this.styles = mergeStyles(styles, otherStyles /* additional styles*/, props.styles /* optional HOC style overrides*/);

Combining this with classnames, this lets me do:

<div className={this.styles.someClass}
    <div className={this.styles('class1', {class2: false}, {class3: this.state.someState})}>
     ....
    </div>
</div>

Then if the style is defined in the modules CSS, it uses the modularized now, else keep the original CSS label (see #47)

I feel like this takes the simplicity of this version of react modules and provides the same override power of the non babel version, bringing the best of both worlds.

It would be good if the styleName attribute was able to use a local scope styles property instead of the global one.

I tried overriding the global one by using import mainStyles at top and doing const styles = this.styles; to then use styleName, but that didn't work...

Thoughts?

Did you try using the classnames/bind pattern? This seems like a re-implementation of that same idea.

If that doesn't work with this, do you know why?

I hope this gets implemented, I need this functionality so I'm going to have to use react-css-modules instead.