npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

bera

v0.1.2

Published

A simple utility function inspired by classnames to handle ABEM naming

Downloads

52

Readme

Bera

Build Status

A simple JavaScript utility for generating classnames following the ABEM principles.

Usage:

import abem from "bera";

abem("button", "label", ["visible", "active"]);
// => 'button__label -visible -active'

The library can also be used directly on the page just including the index.js in a standalone <script> tag; or by RequireJS.

About

Bera is a variant of bero, a utility created by Matteo Ferretti. What bero is to BEM, bera is to ABEM: It follows the same non-invasive approach inspired by classnames to generate classnames for the ABEM naming convention.

Why "bera"?

In line with Matteo's inspiration for naming bero, it's a character from Yōkai Ningen Bem (妖怪人間ベム Yōkai Ningen Bemu, translated officially as Humanoid Monster Bem).

Usage

The abem function is a curried function, takes up to three arguments.

The simplest usage is the basic signature with two arguments, identifier and modifiers:

abem(identifier: String, modifiers: Array|Object) : String

identifier: String

The identifier can be either a block, or an element.

If an element is specified, the full identifier has to be written, in the form of block__elem. For example:

abem("button__label", ["visible", "active"]);
// => 'button__label  -visible -active'

Since abem is a curried function, it also possible write the code above as:

const label = abem("button__label");

label(["visible", "active"]);
// => 'button__label -visible -active'

This form would be rarely used for elements; it's more common having block functions, when the signature with three arguments is used:

abem(block: String, elem: String, modifiers: Array|Object) : String

In this form, the equivalent of the code above would be:

abem("button", "label", ["visible", "active"]);
// => 'button__label -visible -active'

But it would be more common used as curried function for block functions:

const button = abem("button");

button("label", ["visible", "active"]);
// => 'button__label -visible -active'

This form is useful especially in components, where there is likely only one block per component, but multiple elements as children of that block.

modifiers: Array|Object

The modifiers arguments can be either an Array or an Object. The logic is the same of @JedWatson's classnames module.

If it's an Array, every element that is considered truthy, would be added as modifier in the resulting classname:

abem("button__label", [false, "visible", 0, , "", undefined, "active"]);
// =>  button__label -visible -active'

However, modifiers really shines when an Object is given:

abem("button__label", {
  visible: isVisible,
  active: isActive
});
// with `isVisible`: true, `isActive`: true
// => button__label -visible -active'

// with `isVisible`: true, `isActive`: false
// => button__label -visible'

// with `isVisible`: false, `isActive`: true
// => button__label -active'

// with `isVisible`: false, `isActive`: false
// => button__label

With computed property names you can also have modifiers as such:

abem("button__label", {
  [`text-${color}`]: !!color
});
// with `color`: undefined:
// => button__label

// with `color`: "red"
// => button__label -textRed

camelCase modifiers

All modifiers are automatically converted to camel case:

abem("button__label", {
  'has-focus': true
});
// with `has-focus`: true
// => button__label -hasFocus

// with "text-red": red
abem("button__label", ["ColorRed"]);
// => button__label -colorRed

Likely cases of abbreviation will be retained:

abem("button__label", ["DOMLoaded"]);
// => button__label -DOMLoaded

Any number of hyphens at the beginning of the string will be removed:

abem("button__label", ["-foo", "--bar", "---baz"]);
// => button__label -foo -bar -baz

And any numbers of hyphen inside the string will be removed and the first letter of the suffix properly cased:

abem("button__label", ["foo----bar"]);
// => button__label -fooBar

So that even in those edge cases the ABEM naming convention is kept.

The join function

bera comes with an utility function that helps to concatenate several truthy values in one string. That's useful when the generated ABEM classname needs to be concatenate by external strings, such a className passed by props in React. See below for a real-world example.

Usage with React Component.

import abem, { join } from "bero";

const button = abem("button");

export default class Button {
  // ...
  render() {
    const { pressed, hover } = this.state;
    const { className, label, onClick } = this.props;

    return (
      <button
        className={join(button({ pressed, hover }), className)}
        onClick={onClick}
      >
        <label className={button("label", ["strong"])}>{label}</label>
      </button>
    );
  }
}

License

MIT. Copyright (c) 2018 Nuey San Waldman