leinelissen / laravel-mix-react-css-modules

A wrapper for babel-plugin-react-css-modules for Laravel Mix
MIT License
22 stars 9 forks source link

Cannot make styleName property work #2

Closed dariuszwisniewski closed 5 years ago

dariuszwisniewski commented 6 years ago

Description: I'm trying to make use of styleName property combined with className to separate global and local styles. It looks like styleName property doesn't work as expected or I'm missing something. Only classes from className property are attached into the html element.

Css:

.container {
  background: pink;
}
.xxx {
  background: yellow;
}

React Component:

import styles from './styles.scss';
...
render(){
...
            <div styleName='styles.xxx' className={`container ${styles.container}`}></div>
            <div styleName='xxx' className={`container ${styles.container}`}>
...

Rendered HTML:

<div class="container Directory-container-3DTYl "></div>
<div class="container Directory-container-3DTYl "></div>

My webpack.mix.js file:

let mix = require('laravel-mix');
require('laravel-mix-react-css-modules');

if (mix.inProduction()) {
    mix.version();
}
mix.setPublicPath('public/w2').setResourceRoot('/w2/');

mix.react('resources/js/app.js', 'public/w2/js')
    .extract(['bootstrap'])
    .reactCSSModules('[folder]-[local]-[hash:base64:5]');

mix.sass('resources/sass/app.scss', 'public/w2/css');

It looks like styleName property is removed completely and not attached into the classes list. Thanks in advance for any suggestions.

leinelissen commented 6 years ago

Hi @WisienDot !

This is because styleName is actually a proxy for className. It will try to find a styles object, and then use it to generate a className property (see: https://github.com/gajus/babel-plugin-react-css-modules). This is intended behaviour, and there is no way to combine className and styleName on a single component.

As for solutions, you could consider the following:

leinelissen commented 6 years ago

BTW, another approach could be to scope any global styles in a separate React component, and adding a className prop onto that component. You could then combine both classes using some in-component magic.

container.jsx

import styles from './styles.scss';

component Container extends Component {
  render() {
    return (
       <div className={`${styles.container} ${this.props.className}`}>{this.props.children}</div>
    );
  }
}

RandomComponent.jsx

import styles from './styles.scss';
import Container from 'components/Container';

class RandomComponent extends Component {
  render() {
    return (
       <Container styleName="rand-component">Magic!</Container>
    );
  }
}