BEM Sample

https://habrahabr.ru/company/yandex/blog/276035/#comment_8761643

by ilyar

HTML

<link rel="stylesheet" href="https://yastatic.net/bem-components/2.4.0/desktop/bem-components.css">
<script src="https://yastatic.net/bem-components/2.4.0/desktop/bem-components.js+bemhtml.js"></script>
<body class="page page_theme_islands">
<script type="text/bemjson" class="bemjson i-bem" data-bem="{&quot;bemjson&quot;: {}}">
{
 "block": "date-form",
 "content": [
    {
        "elem": "item",
        "elemMods": { "type": "day" },
        "content": "Day"
    },
    {
        "elem": "item",
        "elemMods": { "type": "month" },
        "content": "Month"
    },
    {
        "elem": "item",
        "elemMods": { "type": "year" },
        "content": "Year"
    }
 ]
}
</script>
</body>

SCSS

.date-form
{
 
  &__item
  {
    &_type {
      &_day {
        color: red;
      }
      &_month {
        color: green;
      }
      &_year {
        color: blue;
      }
    }
  }
  
  &__label
  {}
  
  &__input
  {} 
}

JavaScript

/**
 * @module date-form
 */
modules.define(
  'date-form', // a block name
  ['i-bem__dom'], // dependence connection
  function(provide, BEMDOM) { // a function that received names of the used modules

    /**
     * @exports
     * @class date-form
     * @bem
     */
    provide(BEMDOM.decl(this.name, /** @lends date-form.prototype */ { // a block declaration
      onSetMod: { // a constructor that describes reaction on an event
        'js': {
          'inited': function() {
              // TODO init
          }
        }
      }
    }));
  }
);

/**
 * Template
 */
modules.define( 'BEMHTML', [], function ( provide, BEMHTML ) {
  BEMHTML.compile(function() {
    block('date-form')(
      js()(true)
    );
    
    block('date-form').elem('item')(
      content()(function(){
        var ctx = this.ctx;
        return [
            { "elem": "label", "content": ctx.content },
            { "elem": "input", attrs: { type: 'text', name: ctx.elemMods.type } }
        ]
      })
    );
    
    block('date-form').elem('input')(
      tag()('input')
    );
  });
  provide( BEMHTML );
} );


/**
 * @module bemjson
 */
modules.define(
  'bemjson', ['i-bem__dom', 'BEMHTML'],
  function(provide, BEMDOM, BEMHTML) {

    /**
     * @exports
     * @class bemjson
     * @bem
     */
    provide(BEMDOM.decl(this.name, /** @lends bemjson.prototype */ {
      onSetMod: {
        js: {
          inited: function() {
            BEMDOM.replace(this.domElem, BEMHTML.apply(JSON.parse(this.domElem.text())));
          }
        }
      }
    }));
  }
);