Freak out! Showcasing Chic Modules 1.0 ✨ A Styled-like CSS-Modules API
Tags: react, css, webdev, news
Published: 2021-10-25 15:11:53

> #### A familiar styled-like API for working with css-modules in React

Another week, another announcement. While the wind may have been taken out of my sails by Facebook talking about their own styling solution, I'm pleased to announce that my own take on managing components styles in React has reached stable status. Introducing [Chic Modules](https://github.com/eels/chic-modules)! 

#### What is `chic-modules`

While I adore the styled pattern for composing React components, I also love css-modules and separating concerns. Life isn't all sunshine and roses though. Complex class compositions often result in ugly inline ternary operators for conditional class names and style modifiers. I wanted to create a compromise, or "best-of-both-worlds" solution, that wraps a standard css-modules implementation in a well-established API.

This project isn't meant to supersede others like styled-components, and doesn't attempt to join the conversation around css-in-js vs css-modules (there's _literally_ thousands of articles for that), it's simply meant to be a different solution and alternative approach. My attitude is, if you're going to use css-modules anyway then why not give `chic-modules` a whirl.

#### Features

- 🧠 Intelligent prop-based style modifiers
- 🤝 Extending/sharing styles between components
- ⛓ Static prop management via `attrs` constructor 
- 🏃‍♂️ Dynamic run-time style management
- 🔎 Full TypeScript support

#### Basic Example

```scss
// application.module.css

.wrapper {
  padding: 4em;
  background: papayawhip;
}

.title {
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
}
```

```jsx
// application.jsx

import React from 'react';

import styles from './application.module.css';

import { create } from 'chic-modules';

// Call the chic-modules `create` factory and pass the
// required styles object as an argument
const styled = create(styles);

// Create a <Wrapper> React component that inherits the `.wrapper`
// class from the styles object and renders a <section> html element
const Wrapper = styled.section('wrapper');

// Create a <Title> React component that inherits the `.title`
// class from the styles object and renders a <h1> html element
const Title = styled.h1('title');

// Use them like regular React components – except they're styled!
function Application() {
  return (
    <Wrapper>
      <Title>Hello World, this is my first chic component!</Title>
    </Wrapper>
  );
}
```

This is what you'll see in your browser:

![Chic Modules example usage](https://user-images.githubusercontent.com/86960670/131226145-180aadcc-4805-409d-9a57-81d7dc94d69a.png)

[Open in CodeSandbox](https://codesandbox.io/s/brave-lewin-ofw92?file=/src/components/application.jsx)

#### Style Modifiers

As I briefly touched upon in the opening statement, my biggest gripe when using css-modules is the cumbersome nature of adding "modifier" class names to components. Where I believe `chic-modules` really shines is in its attempt to solve this problem.

Taking a look at this pretty standard setup using the [classnames](https://www.npmjs.com/package/classnames) package, you can see that a lot of extra steps are required to attach conditional class names to a component. This problem only gets worse when you try to go it alone without a class name utility package.

### :no_good_woman: Cumbersome

```jsx
import classnames from 'classnames';
import styles from './button.module.css';

function MyButton({ children, isPrimary }) {
  const classes = classnames(
    'button',
    {
      [styles['button--primary']]: isPrimary
    }
  );

  return <button classNames={classes}>{children}</button>;
}

// outputs <button class="button button--primary">
```

On the other hand, `chic-modules` can infer when a prop is being used as a style modifier and automagically add the relevant modifier class if it exists in the styles object to the component.

### :sunglasses: Chic

```jsx
import styles from './button.module.css';
import { create } from 'chic-modules';

const styled = create(styles);
const Button = styled.button('button');

function MyButton({ children, isPrimary }) {
  return <Button isPrimary={isPrimary}>{children}</Button>;
}

// outputs <button class="button button--primary">
```

Any prop can be used to infer a style modifier as long as it starts with `has`, `is` or `with` and its value evaluates as truthy. You can also pass string values to props prefixed with `with` and have that value used in the constructed modifier class.

`chic-modules` expects that your styles follow the [BEM](http://getbem.com/naming/) naming convention, so when using this package ensure that your stylesheet aligns with this structure.

```jsx
<Button hasBorder isPrimary withTextColor="black" />
// outputs <button class="button button--border button--primary button--text-color-black">
```

#### Documentation

- [Using `as` prop](https://github.com/eels/chic-modules#using-as)
- [Using `attrs` constructor](https://github.com/eels/chic-modules#using-attrs)
- [Additional Styles](https://github.com/eels/chic-modules#additional-styles)
- [Multiple Base Class Names](https://github.com/eels/chic-modules#multiple-base-class-names)
- [TypeScript](https://github.com/eels/chic-modules#typescript)
- [Dynamic Styles](https://github.com/eels/chic-modules#dynamic-styles)
  - [Server-Side Rendering](https://github.com/eels/chic-modules#server-side-rendering)

Interested? Read the full [documentation here](https://github.com/eels/chic-modules#readme).

#### The Future / Helping Out

My main focus for the project at the moment is performance improvements over additional features. I think the initial feature-set is in a good place and I would like to get more insights on any real world usage before thinking about adding more. There's also definitely parts of the code base that could do with being fine-tuned and abstracted a little more.

If you find `chic-modules` interesting and would like to help out then feel free to take a look over the code and suggest any improvements. Additionally, it would be a big help if you could star, tweet or mention this project to raise some awareness!

And of course, if you do end up building anything with `chic-modules` then definitely send it my way! I'd love to see what's being made and I'll even include it in the [README](https://github.com/eels/chic-modules#built-with-chic-modules). 

Thanks for your time.

C'est chic!

[https://github.com/eels/chic-modules](https://github.com/eels/chic-modules)