npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-c

v0.2.0

Published

Provides structure to your component's CSS by helping you write semantic class names.

Downloads

61

Readme

react-c

react-c provides structure to your component's CSS. To do so, it provides two methods to help you write properly-scoped CSS classes, an ES7 decorator to specify a namespace, and guidelines for writing clean CSS with LESS/SCSS.

With react-c, writing clean CSS for React is so simple that you no longer have any excuse to not do it.

Example

The best way to understand react-c is to see it in action, so let's have a look how it is used in a slightly simplified copy of numbat-ui's Paper component:

import React from "react"
import c from "react-c"

@c("nui")
class Paper extends React.Component {
  static propTypes = {
    rounded: React.PropTypes.bool,
  }

  static defaultProps = {
    rounded: true,
  }

  render() {
    return (
      <div className={this.cRoot({rounded: this.props.rounded})}>
        <div className={this.c('inner')}>
          {this.props.children}
        </div>
      </div>
    )
  }
}

Rendering a Paper component with the rounded property set to true will produce the following:

<div class="nui-Paper nui-Paper-rounded">
  <div class="nui-Paper-inner">
    ...
  </div>
</div>

This output in turn is styled using LESS or SCSS, using the &- selector to prevent Carpal Tunnel Syndrome:

.nui-Paper {
  //...

  &-rounded {
    //...
  }

  &-inner {
    //...
  }

  &-rounded &-inner {
    //...
  }
}

Usage

1. Install with NPM:

npm install react-c --save

2. Import the module:

import c from 'react-c' // ES6

or

var c = require('react-c') // CommonJS

3. Add react-c to your component:

You have two options to do this. If you're building modules by extending React.Component, I recommend using ES7 decorators:

@c("ns")
class MyComponent extends React.Component {
  ...
}

Otherwise, just pass your components to the c(prefix) manually:

var MyComponent = React.createClass({
  ...
})

c("ns")(MyComponent)

4. Add classes to your components using c and cRoot

  • c(...)

    Example output: 'ns-MyComponent-a ns-MyComponent-b'

    Generates a className string using the classnames module, but with all classes prefixed with the component's name and specified prefix.

  • cRoot(initial, final)

    Example output: 'ns-MyComponent ns-MyComponent-initial this-prop-className ns-MyComponent-final'

    Returns the component name, followed by the result of passing initial and final parameters through c(...), with the value of this.props.className (if any) sandwiched between.

    As browsers give the later classes higher priority, it is possible to give your classes higher or lower priority than those added from this.props.className.

    This function is generally used on the root component in your render() function, thus the name. You probably shouldn't use it more than once.

5. Write your LESS/SASS following the react-c guidelines

  1. Your component's stylesheet should have exactly one top level selector: the one generated by cRoot

    Example:

    /* Good */
    .MyComponent {
      /* ... */
    }
    
    /* Bad */
    .OtherComponent {
      /* ... */
    }
    
    /* Bad */
    #some-id {
      /* ... */
    }
  2. All other selectors (and parts of selectors) should start with &-

    Example:

    .MyComponent {
      /* good */
      &-inner &-input {
        /* ... */
      }
    
      /* bad */
      &-inner input {
        /* ... */
      }
    
      /* good */
      &-other-component {
        /* ... */
      }
    
      /* bad */
      .OtherComponent {
        /* ... */
      }
    }

These two rules have a number of flow-on effects:

  • You cannot select elements based on tag names or ids. Instead, select child elements by adding a class to them with c.
  • You cannot directly apply styles to child components. Instead, pass in class names generated with c to child components, and style them instead.

The result of this is that it is incredibly easy to reason about what styles are applied, and where they come from. As a bonus, "inspect element" in your favourite web-browser will immediately show where styles originate.

In order to make these guidelines easier to follow, I recommend placing your LESS/SCSS files in the same directory as your jsx, with one file per component. For an example of a project organised this way, see numbat-ui.

FAQ

How do c and cRoot know what my class is called?

react-c uses component.prototype.displayName || component.name to decide what your component is called. This can break down in the following cases:

  • You're using React.createClass, but not using JSX. This is because component.prototype.displayName is set by the JSX compiler. Set displayName manually in this case.
  • You're applying the ES7 decorator after another decorator which modifies component.name. This can happen if it returns a class which extends the original, for example.

Is react-c BEM compliant?

No.

BEM goes further than react-c, by distinguishing between classes for modifiers and elements.

For a BEM-based project, use something like react-bem.

Why should I use react-c over BEM-based modules like react-bem?

Given most React components are very small and have limited scope, BEM is overkill in this context. If you find your components are getting big enough that you think it might make sense to distinguish between elements and modifiers (like BEM), you probably instead should focus on factoring your components into smaller parts.

Related Projects

react-c is part of react-base - a collection of Higher-Order Components to make your life easier.

react-base (and react-c) were extracted from numbat-ui - a collection of UI components for React based on Google's Material Design.