Search code examples
reactjsreactstrapreact-css-modules

How to get CSS Modules to work with Reactstrap cssModule propType?


I noticed most form elements in the Reactstrap documentation have a PropType of a cssModule. I would assume that means I could override the default Reactstrap styles and do something like this:

Formtext.module.css

.formtext {
  background-color: blue;
  border: 2px solid black;
  margin: 10px;
}

SimpleForm.jsx

import styles from "./Formtext.module.css";
...

<FormText cssModule={styles.formtext}>
   This is some placeholder help text...
</FormText>

```

However, this doesn't seem to work. Checking my react dev tools the cssModule prop evaluates to undefined.

I'm using Using Reactstrap 5.0 and create-react-app 1.1.5

Is there something I'm unaware of that I need to do? Do I need to eject to be able to use css-modules? Can someone point me to an example of how to use the Reactstrap's cssModule prop correctly?


For reference here is the proptypes definition from Reactstrap docs

FormText.propTypes = {
  children: PropTypes.node,
  inline: PropTypes.bool,
  tag: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), // default: 'small'
  color: PropTypes.string, // default: 'muted'
  className: PropTypes.string,
  cssModule: PropTypes.object,
};

Solution

  • On cssModule

    It looks like cssModules doesn't behave quite like you would think; the prop doesn't take a single, overriding class - it takes a rejected class and a replacement class.

    Reactstrap uses mapToCssModules to get this done. See its documentation here. Take note of the usage example:

    <Example tag="div" cssModule={{ 'w-100': 'w-75' }} />
    

    So your case would look something like this:

    <FormText cssModule={{ 'form-text' : styles.formtext }} />
    

    This will completely surpress the 'form-text' class though (which in your case, only contributes display: block. If you'd like to override more selectively, see below.


    Try this instead

    In the FormText source code, it looks like you may be able to do your overrides in a different way:

    • If you want to omit the form-text class altogether, include inline as a prop,
    • If you want to omit any color-related bootstrap classes, set 'color' to false (or something falsy),
    • set the className prop to your CSS Module object (styles.formtext).

    <FormText className={styles.formText} color='' inline> Test formtext </FormText>

    The most important part here is actually the className prop. You can also further override styling by including a tag prop (again, check the FormText docs).


    Hope this was helpful! Happy holidays! 🦃🎅