Examples
Common BEM class naming conventions.
Basic button
Create a block, then add elements or modifiers as needed:
import { createBem } from "@lai9fox/bem";
const bem = createBem({ namespace: "ui-" });
const btn = bem.block("button");
btn.block();
// 'ui-button'
btn.element("label");
// 'ui-button__label'
btn.modifier("primary");
// 'ui-button--primary'
Conditional className
Use classes() to build the full class string from props:
function buttonClassName({
disabled,
iconActive,
}: {
disabled: boolean;
iconActive: boolean;
}) {
const btn = createBem({ namespace: "ui-" }).block("button");
return btn.classes({
block: true,
elements: { icon: true },
modifiers: { disabled },
elementModifiers: {
icon: { active: iconActive },
},
});
}
buttonClassName({ disabled: true, iconActive: true });
// 'ui-button ui-button__icon ui-button--disabled ui-button__icon--active'
Batched elements / modifiers
For multi-part layouts like cards, list every sub-element or state in one call:
const card = createBem().block("card");
card.elements(["header", "body", "footer"]);
// 'card__header card__body card__footer'
card.modifiers(["elevated", "compact"]);
// 'card--elevated card--compact'
Custom separators
Namespace and separators follow whatever convention your project uses:
const bem = createBem({
namespace: "app_",
elementSeparator: "-",
modifierSeparator: "_",
});
const nav = bem.block("nav");
nav.elementModifier("item", "current");
// 'app_nav-item_current'