diff --git a/README.md b/README.md
index 81c7afd..75fa8e9 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,7 @@ API
* [valueOf()](#valueof)
* [toJSON()](#tojson)
* [isBemCell(cell)](#isbemcellcell)
+* [create(object)](#createobject)
### constructor(obj)
@@ -191,6 +192,40 @@ BemCell.isBemCell(cell); // true
BemCell.isBemCell({}); // false
```
+### #create(object)
+
+Creates BemCell instance by the any object representation.
+
+Helper for sugar-free simplicity.
+
+Parameter | Type | Description
+-------------|----------|--------------------------
+`object` | `object` | Representation of entity name.
+
+Passed Object can have fields for BemEntityName and cell itself:
+
+Object field | Type | Description
+-------------|----------|------------------------------
+`block` | `string` | The block name of entity.
+`elem` | `string` | The element name of entity.
+`mod` | `string`, `object` | The modifier of entity.
If specified value is `string` then it will be equivalent to `{ name: string, val: true }`.
+`val` | `string` | The modifier value of entity. Used if `mod` is a string.
+`mod.name` | `string` | The modifier name of entity.
+`mod.val` | `*` | The modifier value of entity.
+`modName` | `string` | The modifier name of entity. Used if `mod.name` wasn't specified.
+`modVal` | `*` | The modifier value of entity. Used if neither `mod.val` nor `val` were not specified.
+`tech` | `string` | Technology of cell.
+`layer` | `string` | Layer of cell.
+
+```js
+const BemCell = require('@bem/cell');
+
+BemCell.create({ block: 'my-button', mod: 'theme', val: 'red', tech: 'css', layer: 'common' });
+BemCell.create({ block: 'my-button', modName: 'theme', modVal: 'red', tech: 'css', layer: 'common' });
+BemCell.create({ entity: { block: 'my-button', modName: 'theme', modVal: 'red' }, tech: 'css' }); // valueOf() format
+// BemCell { entity: { block: 'my-button', mod: { name: 'theme', val: 'red' } }, tech: 'css', layer: 'common' }
+```
+
Debuggability
-------------
diff --git a/index.js b/index.js
index c42badb..17ac663 100644
--- a/index.js
+++ b/index.js
@@ -211,4 +211,42 @@ module.exports = class BemCell {
static isBemCell(cell) {
return cell && this.name === cell.constructor.name;
}
+
+ /**
+ * Creates BemCell instance by the any object representation.
+ *
+ * @param {object} obj — representation of cell.
+ * @param {string} obj.block — the block name of entity.
+ * @param {string} [obj.elem] — the element name of entity.
+ * @param {object|string} [obj.mod] — the modifier of entity.
+ * @param {string} obj.mod.name — the modifier name of entity.
+ * @param {string} [obj.mod.val] — the modifier value of entity.
+ * @param {string} [obj.modName] — the modifier name of entity.
+ * @param {string} [obj.modVal] — the modifier value of entity.
+ * @param {string} [obj.tech] — technology of cell.
+ * @param {string} [obj.layer] — layer of cell.
+ *
+ * @returns {BemCell} An object representing cell.
+ * @example
+ * const BemCell = require('@bem/cell');
+ *
+ * BemCell.create({ block: 'my-button', mod: 'theme', val: 'red', tech: 'css' });
+ * BemCell.create({ block: 'my-button', modName: 'theme', modVal: 'red', tech: 'css' });
+ * BemCell.create({ entity: { block: 'my-button', modName: 'theme', modVal: 'red' }, tech: 'css' });
+ * // BemCell { block: 'my-button', mod: { name: 'theme', val: 'red' }, tech: 'css' }
+ */
+ static create(obj) {
+ if (BemCell.isBemCell(obj)) {
+ return obj;
+ }
+
+ const data = {};
+
+ data.entity = BemEntityName.create(obj.entity || obj);
+
+ obj.tech && (data.tech = obj.tech);
+ obj.layer && (data.layer = obj.layer);
+
+ return new BemCell(data);
+ }
};
diff --git a/package.json b/package.json
index af237ab..0831ae7 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "0.2.1",
"description": "Representation of identifier of a part of BEM entity.",
"license": "MPL-2.0",
- "repository": "bem-sdk/cell",
+ "repository": "bem-sdk/bem-cell",
"author": "Andrew Abramov (github.com/blond)",
"keywords": [
"bem",
@@ -24,7 +24,7 @@
"node": ">= 4.0"
},
"dependencies": {
- "@bem/entity-name": "1.1.0"
+ "@bem/entity-name": "1.2.0"
},
"devDependencies": {
"ava": "^0.17.0",
diff --git a/test/create.test.js b/test/create.test.js
new file mode 100644
index 0000000..4987968
--- /dev/null
+++ b/test/create.test.js
@@ -0,0 +1,63 @@
+const test = require('ava');
+
+const BemEntityName = require('@bem/entity-name');
+
+const BemCell = require('../index');
+
+test('should return object as is if it`s a BemCell', t => {
+ const cell = new BemCell({ entity: new BemEntityName({ block: 'b' }) });
+
+ t.is(BemCell.create(cell), cell);
+});
+
+test('should create BemCell for block from obj', t => {
+ const cell = BemCell.create({ block: 'b' });
+
+ t.pass(cell instanceof BemCell, 'Should be an instance of BemCell');
+ t.is(cell.entity.block, 'b', 'Should create entity with BemEntityName.create');
+});
+
+test('should create cell for elem from obj', t => {
+ const cell = BemCell.create({ block: 'b', elem: 'e' });
+
+ t.deepEqual(cell.entity.valueOf(), { block: 'b', elem: 'e' });
+});
+
+test('should create cell with tech', t => {
+ const cell = BemCell.create({ block: 'block', tech: 'css' });
+
+ t.is(cell.tech, 'css');
+});
+
+test('should create cell with layer', t => {
+ const cell = BemCell.create({ block: 'block', layer: 'desktop' });
+
+ t.is(cell.layer, 'desktop');
+});
+
+test('should create cell with layer', t => {
+ const cell = BemCell.create({ block: 'block', tech: 'css', layer: 'desktop' });
+
+ t.is(cell.tech, 'css');
+ t.is(cell.layer, 'desktop');
+});
+
+test('should create BemCell for block from obj', t => {
+ const cell = BemCell.create({ block: 'b', elem: 'e', mod: 'm', val: 'v', tech: 't', layer: 'l' });
+
+ t.deepEqual(cell.valueOf(), {
+ entity: { block: 'b', elem: 'e', mod: { name: 'm', val: 'v' } },
+ tech: 't',
+ layer: 'l'
+ });
+});
+
+test('should create BemCell for entity with tech and layer from obj', t => {
+ const cell = BemCell.create({ entity: { block: 'b', mod: 'm', val: 'v' }, tech: 't', layer: 'l' });
+
+ t.deepEqual(cell.valueOf(), {
+ entity: { block: 'b', mod: { name: 'm', val: 'v' } },
+ tech: 't',
+ layer: 'l'
+ });
+});