bem-cn
    TypeScript icon, indicating that this package has built-in type declarations

    3.0.1 • Public • Published

    BEM class names generator

    Build Status code style: prettier

    Friendly BEM class names generator. Great for React.

    Bem-cn (aka BEM Class Name) is extra small (minified+gzipped less than 1.6Kb) and extremely simple client-side library and Node.js module.

    Important! Only bem-cn@3.x+ compatible with react@16+. Please do not use version 2.x or lower. More details about the problem.

    Inspired by b_.

    Justification

    I spent a lot of time finding BEM class name generator, that meets my needs:

    • Simple usage with React
    • Support modifiers without value
    • Mix multiple blocks
    • Friendly API

    When my efforts had led to naught I've created this micro library.

    Install

    With Node.js:

    npm i --save bem-cn
    yarn add bem-cn

    Works with webpack and browserify:

    // CommonJS
    var { block } = require('bem-cn');
     
    // ES6
    import { block } from 'bem-cn';

    API

    const b = block('button');
     
    // Block
    b(); // 'button'
     
    // Element
    b('icon'); // 'button__icon'
     
    // Modifier
    b({ type: 'text' });  // 'button button_type_text'
    b({ onlykey: true });  // 'button button_onlykey'
    b({ without: false });  // 'button'
     
    b('icon', { name: 'check' }); // 'button__icon button__icon_name_check'
     
    // Mix another classes
    b('icon').mix('another'); // 'button__icon another'
    b('icon').mix(['one', 'two']); // 'button__icon one two'
     
    // States like in SMACSS: https://smacss.com/book/type-state
    b.state({ hidden: true }); // 'button is-hidden'
    b.state({ hidden: false }); // 'button'
    b.state({ hidden: true, error: true }); // 'button is-hidden is-error'
     
    // More states!
    b.is({ loading: true }); // 'button is-loading'
    b.has({ content: true }); // 'button has-content'
    // Setup custom delimiters
    import { setup } from 'bem-cn';
     
    const block = setup({
        el: '~~',
        mod: '--',
        modValue: '-'
    });
     
    const b = block('block');
     
    b('element'); // 'block~~element'
    b({ mod: 'value' }); // 'block block--mod-value'
    // Setup namespace
    const block = setup({ ns: 'ns-' });
     
    const b = block('block');
     
    b(); // 'ns-block'
    b('element'); // 'ns-block__element'
    b({ mod: 'value' }); // 'ns-block ns-block_mod_value'

    Try it with React

    import block from 'bem-cn';
    import React from 'react';
    import ReactDOM from 'react-dom';
     
    const b = block('popup');
     
    const Popup = React.createClass({
        render() {
            const { skin, children } = this.props;
     
            return (
                <div className={b()}>
                 <span className={b('icon')} />
                 <div className={b('content', { skin })}>
                 {children}
                 </div>
                </div>
            );
        }
    });
     
    ReactDOM.render(<Popup skin="bright">Hello!</Popup>, target);
     
    /*
    <div class="popup">
        <span class="popup__icon"></span>
        <div class="popup__content popup__content_skin_bright">
            Hello!
        </div>
    </div>
     */

    Troubleshooting

    Maigrate to version 3.x

    @todo

    PropTypes warnings

    bem-cn@2.x or lower has specific chainable API. As a result, each call returns function for a further call. But most components are expecting property className as a string and using propTypes object for check this. In this case, you will see a warning. There are the couple of ways to avoid these warnings below.

    #1

    Use final call without arguments to get a string

    <CustomComponent className={b('icon')()} />

    #2

    Use explicit call of method toString():

    <CustomComponent className={b('icon').toString()} />

    #3

    Use less specific propTypes rules:

    let CustomComponent = React.createClass({
        propTypes: {
            className: React.PropTypes.oneOfType([
                React.PropTypes.string,
                React.PropTypes.func
            ])
        },
        // ...
    });

    ES3 browsers

    bem-cn is fully compatible with ES5 browsers. If you are going to support ES3 browsers than just use es5 shim.

    Install

    npm i bem-cn

    DownloadsWeekly Downloads

    6,829

    Version

    3.0.1

    License

    MIT

    Unpacked Size

    124 kB

    Total Files

    12

    Last publish

    Collaborators

    • albburtsev