React-styleguidist: Working with CSS Modules

Created on 19 Jun 2017  Ā·  16Comments  Ā·  Source: styleguidist/react-styleguidist

I'm trying to make this work with our project that is using both TypeScript and CSS Modules:

example component code:

import React from 'react';
import CSSModules from 'react-css-modules';

const styles = require('./style.scss');

interface IProps {
    condensed?: boolean;
}

const Logo = ({ condensed = false }: IProps) => (
    <a href="/?ref=header" styleName={condensed ? 'logo-condensed' : 'logo'}>my company</a>
);

export default CSSModules(Logo, styles);

When running styleguidist, problem is that the default export is wrapped with CSSModules.

Compiling…

Warning: src\components\Logo\Logo.tsx matches a pattern defined in ā€componentsā€ or ā€œsectionsā€ options in your style guide config but doesn’t export a component.

[at-loader] Checking started in a separate process...

[at-loader] Ok, 0.533 sec.
Compiled successfully!

Another thing is that we use styleName instead of className - that's the way that CSSModules applies its own scoped classes to the elements.

It all works if I export just the component (in this case export default Logo;)

Any suggestions as to how could we overcome that?

help wanted question request for comments

Most helpful comment

React Styleguidist does work with the original CSS Modules because that doesn't need a CSSModules decorator on export, so that's what I'm implementing for now. However, react-css-modules was created specifically for the use case of CSS Modules in React and improves the use of the package in that context.

I think this may be a feature request, but it's definitely worth considering making Styleguidist compatible with React CSS Modules. I did a lot of research about how best to go about making my company's living style guide/component lab (React Styleguidist came out on top for documentation and viewing the guide šŸ‘) and it seemed to me like CSS Modules is the way forward. Seeing as there is so much overlap between building modular CSS and building/documenting the components styled with it, it would be really great if React Styleguidist supported React CSS Modules!

All 16 comments

It all works if I export just the component (in this case export default Logo;)

What doesn’t work in this case?

šŸ™Œ This is _exactly_ the problem I'm wrangling with right now!

The issue is that in order to use react-css-modules, at the bottom of the file you call export default CSSModules(Table, styles); instead of just export default Table;.

From their example:

import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './table.css';

class Table extends React.Component {
    render () {
        return <div styleName='table'>
            <div styleName='row'>
                <div styleName='cell'>A0</div>
                <div styleName='cell'>B0</div>
            </div>
        </div>;
    }
}

export default CSSModules(Table, styles);

CSSModules is used to decorate Table component using ./table.css CSS Modules. When Table component is rendered, it will use the properties of the styles object to construct className values.

Like @kasperoo, in trying to make a Button component with both react-css-modules and styleguidist, my code successfully compiles but I get this warning: Warning: src/components/Elements/Button/Button.jsx matches a pattern defined in ā€componentsā€ or ā€œsectionsā€ options in your style guide config but doesn’t export a component. and my button component isn't added to the styleguide. It is, however, exported successfully and rendering in my app outside of my styleguide. Likewise, if I remove the CSSModules bit from the export statement, my component does then appear in the styleguide, but it no longer uses CSS Modules.

React Styleguidist does work with the original CSS Modules because that doesn't need a CSSModules decorator on export, so that's what I'm implementing for now. However, react-css-modules was created specifically for the use case of CSS Modules in React and improves the use of the package in that context.

I think this may be a feature request, but it's definitely worth considering making Styleguidist compatible with React CSS Modules. I did a lot of research about how best to go about making my company's living style guide/component lab (React Styleguidist came out on top for documentation and viewing the guide šŸ‘) and it seemed to me like CSS Modules is the way forward. Seeing as there is so much overlap between building modular CSS and building/documenting the components styled with it, it would be really great if React Styleguidist supported React CSS Modules!

It’s a limitation of react-docgen that we use to parse source code, you can read more in the docs. I’m not sure there’s a simpler way to solve this than writing custom react-docgen resolver like suggested here.

I’ve never tried to do that but I suppose it could be not that hard to do for a particular use case. Make it in a more generic way would be much harder. I’d also create an issue at react-docgen — maybe they would suggest a better solution.

@sapegin Thanks for your quick response! I'll look into this more now that I know what the issue is on the Styleguidist side and see if I'm able to find a solution, although I may settle on sticking with the basic CSS Modules.

@apennell Awesome!

Personally I don’t see any benefit in react-css-modules and use CSS Modules directly ;-)

Yeah, I was trying to figure the benefits out initially and decided to go with that because CSS Modules recommended it for use with React. As far as I can tell, the main difference is that it's easier to work with and have multiple classNames, which isn't a huge deal.

For multiple class names I use classnames — works well ;-)

One important benefit of react-css-modules is that it will warn you when trying to apply an undefined style, whereas with "pure" CSS Modules those undefined are just silently swallowed. It's a nice benefit for larger codebases. But I agree, perhaps not worth adding yet another layer of abstraction šŸ˜„

I’m trying it right now and it works fine. Am I missing something?

import React from 'react';
import CSSModules from 'react-css-modules';
import s from './Button.css';

export function Button({ color, size, children }) { /* ... */ }
export default CSSModules(Button, s);

image 2017-06-26 at 9 50 22 am

PERFECT @sapegin ! Adding that second export on the function line (export const Button = ({}) => { /* ... */ })was what fixed it for me.

I've been lost in the weeds of the web, trying to patch together docs, examples, blogs, and tutorials--none of which, of course, are using the exact same stack and approach as I am. I love the issue you just added for documenting usage with various styling libraries! The Button.js files in your examples introduced me to stateless functional components, so I was using those but with an arrow function. I just had const Button = ({props}) => { /* ... */ }. Is the additional export something specific to the way Styleguidist or react-docgen, or a simple basic React thing that I missed?

In case anyone happens to be using my exact setup and has run into this problem, here is my working solution, which also implements the multiple class option from react-css-modules):

import React from 'react';
import PropTypes from 'prop-types';
import CSSModules from 'react-css-modules';
import styles from './Button.css';

export const Button = ({children, onClick, buttonStyle, size, isFullWidth, disabled, loading}) => {
    return (
        <button 
            onClick={onClick}   
            styleName={`${buttonStyle} ${size}Size ${isFullWidth ? "block" : ""} ${disabled ? "disabled" : ""} ${loading ? "loading" : ""}`}
        >
            {children}
        </button>
    );
}

Button.propTypes = {
    /** ... */
}

Button.defaultProps = {
    /** ... */
}

export default CSSModules(Button, styles, {allowMultiple: true});

...side note: if that code isn't done in the best way, feel free to tell me/future readers what I should refactor! I don't have a senior frontend dev to review my code, hence getting lost in the web weeds 😁

@apennell I’ve added a new guide to the docs — I hope it explains how this works better.

Feel free to improve it further ;-)

I'll update my experience after going in some loops around this issue. I got react-css-modules working (in a project started with Create React App), but once I tried testing I found that there were issues with Jest. This led me to this issue in the react-css-modules repo and the creator says in a comment that while he isn't deprecating the project,

I personally don't develop any project at the moment that would use react-css-modules. There is simply no good reason to use react-css-modules over babel-plugin-react-css-modules. There is no good reason to use react-css-modules over styled-components either. Though, there are a few good reasons to use babel-plugin-react-css-modules over styled-components (notably – performance).

Seeing that, I decided to try out babel-plugin-react-css-modules. I spent a good while trying to configure that but in the end I just couldn't get it to pull up my stylesheets and had to abandon that. I went back to regular old CSS Modules, and that's where I'll be until/unless someone presents me with a solution to my babel-plugin issues! Although there are benefits to that and it's much easier to use the syntactic sugar it applies, in the end CSS Modules is the one that I could get working.

@sapegin Can this closed ?

@apennell I managed to get webpack + babel-plugin-react-css-modules + styleguidist working together

styleguide.dev.js:

 test: /\.css$/,
        exclude: /node_modules/, // not sure this is needed?
        use: [
          {
            loader: 'css-loader',
            options: {
              sourceMap: true,
              modules: true,
              localIdentName: '[local]_[hash:base64:2]'
            }
          }
        ]

.babelrc:

  "presets": [
    "react", "env"
  ],
  "plugins": [
    [
       "react-css-modules",
       {
         "generateScopedName": "[local]_[hash:base64:2]"
       }
     ]

styleguidist server --config styleguide.dev.js

... if this example sucks I can try to make something clearer

@sapegin need help here
@gnarmedia is your examples work?
I use typescript, scss, babel-plugin-react-css-modules together
but seems like styleguidist do not resolve stylesheet dependencies in the first place
i need to manually require('.../**.scss') in my example markdown file so the style can be loaded after

what should I do for fixing this?

here is component (likely)

import styles from './Example.scss';

import * as React from 'react';

export type Props = Readonly<{}>;

export class Example extends React.Component<Props, {}> {
  render() {
    return <div styleName='styles.root'>this is a example</div>;
  }
}

here is the example

Example

  \```
  <Example />
  \```

style of Example are not loaded after.

but after do this, it can load then

\```
require('./Example.scss')
\```
Was this page helpful?
0 / 5 - 0 ratings

Related issues

mheathcote1977 picture mheathcote1977  Ā·  3Comments

magicmark picture magicmark  Ā·  3Comments

vslinko picture vslinko  Ā·  3Comments

davidjb picture davidjb  Ā·  3Comments

mealeyst picture mealeyst  Ā·  3Comments