Composability with CSS Modules

That's not all that CSS Modules give us, although it's certainly one of the great parts of CSS Modules that we get immediately and with no fuss (seriously, we wrote zero configuration to make all of it happen; it was all just code). We also get CSS composability, which is the ability to inherit CSS classes off of other classes, whether they're in the main file or not! This can be incredibly useful when you're setting up more complicated nested components that all need to handle slightly different style sheets, but are not wildly different from each other. Let's say we want to have the ability to mark some components as critical instead of just regular Todos.

We don't want to change too much about the component; we want it to inherit the same basic rules as all of the other Todos. We'll need to set up some code to make this happen. Back in src/Todo/Todo.js, we're going to make some modifications to allow a new state property of critical. We'll start off in the constructor component, where we'll add our new state property and a bind tag for a function:

  constructor(props) {
super(props);
this.state = {
done: false,
critical: false
};

this.markAsDone = this.markAsDone.bind(this);
this.removeTodo = this.removeTodo.bind(this);
this.markCritical = this.markCritical.bind(this);
}

We add a new critical property in our state property, set it to a default value of false, and then we also reference a function (which we haven't written yet) called markCritical, and we bind this, since we'll be using it in an event handler later. Next, we'll tackle the markCritical() function:

  markCritical() {
this.setState({ critical: true });
}

We'll also need to modify our cssClasses() function so that it can react to this new state property. To demonstrate the composability function of CSS Modules, we'll set it so that classes is originally an empty array, and then the first item either becomes critical or todo, depending on whether or not the item is marked as critical:

  cssClasses() {
let classes = [];
if (this.state.critical) {
classes = [styles.critical];
} else {
classes = [styles.todo];
}
if (this.state.done) {
classes = [...classes, styles.done];
}
return classes.join(' ');
}

And finally, in our render function, we'll create the button tag to mark items as critical:

  render() {
return (
<div className={this.cssClasses()}>
{this.props.description}
<br />
<hr className={styles.hr} />
<button className="MarkDone" onClick={this.markAsDone}>
Mark as Done
</button>
<button className="RemoveTodo" onClick={this.removeTodo}>
Remove Me
</button>
<button className="MarkCritical" onClick={this.markCritical}>
Mark as Critical
</button>
</div>
);
}

We're not quite done yet, although we're at least 90% of the way there. We'll also want to go back to src/Todo/Todo.module.css and add a new block for the critical class name, and we'll use our composable property as well:

.critical {
composes: todo;
border: 4px dashed red;
}

To use composition, all you need to do is add a new CSS property called composes and give it a class name (or multiple class names) that you want it to compose. Compose, in this case, is a fancy way of saying that it inherits the behavior of the other class names and allows you to override others. In the previous case, we're saying critical is a CSS module class that is composed of a todo model as the base, and adds a border component of a big red dashed line since, well, we'll just say that this means it is critical. This previous code is the equivalent of us writing out the following:

.critical {
text-align: center;
background: #f5f5f5;
color: #333;
margin: 20px;
padding: 20px;
border: 4px dashed red;
}

Save and reload, as always, and you should be able to mark items as Mark as Done, Mark as Critical, or both, or remove them by clicking Remove Me, as in the following screenshot:

And that about covers it for our brief introduction to CSS Modules! There's certainly more that you could cover over time, but this is more intended to be a quickstart guide and we could probably fill up a second book just on CSS techniques and libraries!

Before you move on, you'll also want to quickly update your snapshots for your tests by hitting U in the yarn test screen!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.15.149