Skip to content

BEM class names generator for TypeScript

License

Notifications You must be signed in to change notification settings

ybiquitous/bem-ts

This branch is up to date with main.

Folders and files

NameName
Last commit message
Last commit date
Dec 2, 2024
Apr 1, 2024
Jan 4, 2023
Feb 2, 2023
Nov 18, 2018
Jan 31, 2019
Apr 1, 2024
Jan 30, 2018
Dec 2, 2022
Apr 1, 2024
Dec 2, 2022
Dec 3, 2024
Dec 3, 2024
Apr 21, 2021
Nov 5, 2024
Feb 2, 2023

Repository files navigation

bem-ts

npm npm bundle size node

BEM (Block Element Modifier) class names generator for TypeScript.

Inspired by bem-cn.

Policy

  • No extra features.
  • No dependencies.
  • TypeScript support.

Install

npm install bem-ts

Usage

A basic usage:

import bem from "bem-ts";

const b = bem("block");

b();
//=> "block"

b({ mod1: true, mod2: false });
//=> "block block--mod1"

b({ mod1: true, mod2: false, mod3: true });
//=> "block block--mod1 block--mod3"

b(["mod1", null, "mod3"]);
//=> "block block--mod1 block--mod3"

b("element");
//=> "block__element"

b("element", { mod1: true, mod2: false });
//=> "block__element block__element--mod1"

b("element", { mod1: true, mod2: false, mod3: true });
//=> "block__element block__element--mod1 block__element--mod3"

b("element", ["mod1", null, "mod3"]);
//=> "block__element block__element--mod1 block__element--mod3"

A more complex example using React and CSS (closer to the real world):

// Button.tsx
import React from "react";
import bem from "bem-ts";
import "./Button.css";

const b = bem("Button");

type Props = {
  state: "success" | "danger";
  icon: React.ReactNode;
  children: React.ReactNode;
};

export function Button({ state, icon, children }: Props) {
  return (
    <button className={b([state])}>
      <i className={b("icon", [state])}>{icon}</i>
      {children}
    </button>
  );
}
/* Button.css */
.Button {
  /* Block */
}
.Button--success {
  /* Modifier */
}
.Button--danger {
  /* Modifier */
}
.Button__icon {
  /* Element */
}
.Button__icon--success {
  /* Element's modifier */
}
.Button__icon--danger {
  /* Element's modifier */
}

Demo

Edit bem-ts demo

API

bem()

The bem() function receives a block name and creates a new function that generates class names. The created function can receive elements or modifiers.

The function can receive the following options:

Name Type Default
elementDelimiter string "__"
modifierDelimiter string "--"
namespace string, string[] ""
namespaceDelimiter string "-"
strict boolean true

elementDelimiter

const b = bem("block", { elementDelimiter: "_" });

b("element");
//=> "block_element"

modifierDelimiter

const b = bem("block", { modifierDelimiter: "-" });

b({ mod: true });
//=> block "block-mod"

b("element", { mod: true });
//=> "block__element block__element-mod"

namespace

const b = bem("block", { namespace: "ns" });

b();
//=> "ns-block"

b("element", { mod1: true, mod2: true });
//=> "ns-block__element ns-block__element--mod1 ns-block__element--mod2"
const b = bem("block", { namespace: ["ns1", "ns2"] });

b();
//=> "ns1-ns2-block"

b("element", { mod1: true, mod2: true });
//=> "ns1-ns2-block__element ns1-ns2-block__element--mod1 ns1-ns2-block__element--mod2"

namespaceDelimiter

const b = bem("block", { namespace: "ns", namespaceDelimiter: "---" });

b();
//=> "ns---block"

b("element", { mod1: true, mod2: true });
//=> "ns---block__element ns---block__element--mod1 ns---block__element--mod2"

When namespace is not given, namespaceDelimiter will be ignored.

const b = bem("block", { namespaceDelimiter: "---" });

b();
//=> "block"

b("element", { mod1: true, mod2: true });
//=> "block__element block__element--mod1 block__element--mod2"

strict

When you set true to this option, given elements or modifiers are checked. And if the check fails, then a runtime error is thrown.

For example, when setting true, the following code throws an error.

const b = bem("foo", { strict: true });
b("element__");
b({ modifier--: true });

When setting false, the following code throws no errors.

const b = bem("foo", { strict: false });
b("element__");
//=> foo__element__
b({ modifier_: true });
//=> foo__modifier_

setup()

The setup() function can change the default options.

import bem, { setup } from "bem-ts";

setup({
  elementDelimiter: "_",
  modifierDelimiter: "-",
  namespace: "ns",
  namespaceDelimiter: "---",
  strict: false,
});

const b = bem("block");

b("element", { mod: true });
//=> "ns---block_element ns---block_element-mod"

License

MIT © Masafumi Koba