Use template literals to build out class names.
const variant = "dark";
const classList = cn`button ${variant}`; // -> "button dark";
You can insert an object anywhere in the string to convert the keys of those objects into class names, depending on if the value was truthy or not.
const classList = cn`button ${{ dark: true }}`; // -> "button dark";
const classList = cn`button ${{ dark: false }}`; // -> "button";
If the object is directly next to a string (meaning no whitespace between it), the keys will all be prefixed with that string.
const classList = cn`button button--${{ dark: true, disabled: true }}`;
// -> "button button--dark button--disabled";
Note, that you can specify any separator (instead of "--") or no separator at all for the modifiers. It just repeats the previous string it sees as the prefix.
cn`item item--${{ selected: true }}`; // -> "item item--selected"
cn`item ${{ selected: true }}`; // -> "item selected"
cn`item ${{ selected: false }}`; // -> "item"
npm install class-name-literal
yarn add class-name-literal
import cn from "class-name-literal";
const selected = true;
const classList = cn`item item--${{
selected,
hovered: false,
}}`; // item item--selected