@mwm/scoper v1.5.0
Scoper
CSS Modules are a popular way to style your websites, but could be easier to use.
Enter, Scoper! 🎆
Scoper takes the mapping object tools like WebPack create when you import a CSS Module,
and generates a Tagged Template function that you can use to easily attach the generated class-names to your HTML elements.
Simply tag a template literal containing any valid className with that function, and Scoper will expand each class-name into its generated equivalent.
Getting Started
Add Scoper to your project using NPM:
> npm install --save @mwm/scoperThen import Scoper anywhere you're using CSS Modules.
import styles from './App.module.css' // our css
import scoper from '@mwm/scoper'           // Scoper!Scoper won't do anything on it's own;
it needs the mapping object WebPack creates.
Simply pass the imported styles object to the scoper function, and Scoper will return a tag function (which we named "scope"):
const scope = scoper(styles)Tagging function in hand, we can apply complicated scoped classes like this 😊:
<div className={scope`my-class otherClass`}>instead of this 😟:
<div className={styles['my-class'] + ' ' + styles.otherClass}>Finally, you can call the tagging function like a normal function, too!
<div className={scope('my-class otherClass')}>React Example
This is what the App.js component might look like if create-react-app used CSS Modules and Scoper tagging.
For this example, I've combined the root <div> and <header> elements to show how adding multiple classes works.
I've also renamed the "logo" class to "animated-logo", to show-off how easy kebab class-names are to use.
Finally, the class-names that WebPack generates are configured to include the "App" prefix by default, so I removed that prefix from them.
Here's the code!
import React, { Component } from 'react'
import logo from './logo.svg'
import styles from './App.module.css'
import scoper from '@mwm/scoper'
const scope = scoper(styles)
class App extends Component {
  render () {
    return (
      <header className={scope`root header`}>
        <img className={scope`animated-logo`} src={logo} alt='logo' />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className={scope`link`}
          href='https://reactjs.org'
          target='_blank'
          rel='noopener noreferrer'
        >
          Learn React
        </a>
      </header>
    )
  }
}
export default AppAdded alternate function, classer.
You can use the classer named export in React apps to avoid typing out className={scope`whatever`}.
Instead, combine classer with the spread operator for less typing:
const className = classer(someImportedCSSModule)
const someJSX = <div {...className`something`} />For example:
import React, { Component } from 'react'
import logo from './logo.svg'
import styles from './App.module.css'
import { classer } from '@mwm/scoper'
const className = classer(styles)
class App extends Component {
  render () {
    return (
      <header {...className`root header`}>
        <img {...className`animated-logo`} src={logo} alt='logo' />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          {...className`link`}
          href='https://reactjs.org'
          target='_blank'
          rel='noopener noreferrer'
        >
          Learn React
        </a>
      </header>
    )
  }
}
export default App