diff --git a/lib/helpers.js b/lib/helpers.js
index bc0ef9e9..d0a6d512 100644
--- a/lib/helpers.js
+++ b/lib/helpers.js
@@ -22,12 +22,26 @@ function propToStr (key, val) {
function objToStr(obj) {
const keys = Object.keys(obj);
- if (!keys.length) { return ''; }
+ if (!keys.length) { return '{}'; }
return `{ ${keys.map(k => propToStr(k, obj[k])).join(', ')} }`;
}
+function styleToObj(style) {
+ if (typeof style === 'string') {
+ return style.split(';').reduce((acc, st) => {
+ if (st.length) {
+ var prop = st.split(':');
+ acc[prop[0]] = prop[1];
+ }
+ return acc;
+ }, {});
+ }
+ return style;
+}
+
module.exports = {
objToStr,
arrToStr,
+ styleToObj,
valToStr
};
diff --git a/lib/index.js b/lib/index.js
index e8dc9893..56750851 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -4,6 +4,7 @@ var pascalCase = require('pascal-case');
var reactMappings = require('./reactMappings');
var valToStr = require('./helpers').valToStr;
+var styleToObj = require('./helpers').styleToObj;
var plugins = require('./plugins');
@@ -17,12 +18,12 @@ function JSXNode(tag, props, children) {
}
var propsToStr = props => Object.keys(props).reduce((acc, k) => {
- if (typeof props[k] === 'string') {
- return acc + ` ${k}=${valToStr(props[k])}`
- } else {
- return acc + ` ${k}={${valToStr(props[k])}}`
- }
- }, '');
+ if (typeof props[k] === 'string') {
+ return acc + ` ${k}=${valToStr(props[k])}`
+ } else {
+ return acc + ` ${k}={${valToStr(props[k])}}`
+ }
+}, '');
var tagToClass = tag => reactMappings[tag] ? tag : pascalCase(tag);
JSXNode.prototype.toString = function() {
@@ -43,7 +44,8 @@ JSXNode.prototype.toString = function() {
};
function Transformer(options) {
- this.plugins = plugins.defaultPlugins;
+ this.plugins = [];
+ this.use(plugins.defaultPlugins);
this.bemNaming = bn(options.naming || 'react');
}
@@ -51,6 +53,7 @@ Transformer.prototype.process = function(bemjson) {
var nodes = [{
json: bemjson,
id: 0,
+ blockName: '',
tree: []
}];
var root = nodes[0];
@@ -61,11 +64,12 @@ Transformer.prototype.process = function(bemjson) {
if (Array.isArray(json)) {
for (i = 0; i < json.length; i++) {
- nodes.push({ json: json[i], id: i, tree: node.tree });
+ nodes.push({ json: json[i], id: i, tree: node.tree, blockName: node.blockName});
}
} else {
var res = undefined;
var jsx = new JSXNode();
+ var blockName = json.block || node.blockName;
if (typeof json === 'string') {
jsx.isText = true;
@@ -74,17 +78,18 @@ Transformer.prototype.process = function(bemjson) {
if (json.tag) {
jsx.tag = json.tag;
- } else if (json.block) {
- jsx.bemEntity = new BemEntity({block: json.block, elem: json.elem});
+ } else if (json.block || json.elem) {
+ jsx.bemEntity = new BemEntity({ block: blockName, elem: json.elem });
jsx.tag = this.bemNaming.stringify(jsx.bemEntity);
}
for (i = 0; i < this.plugins.length; i++) {
var plugin = this.plugins[i];
- res = plugin(jsx, json);
+ res = plugin(jsx, Object.assign({ block: blockName }, json));
if (res !== undefined) {
json = res;
node.json = json;
+ node.blockName = blockName;
nodes.push(node);
break;
}
@@ -94,11 +99,13 @@ Transformer.prototype.process = function(bemjson) {
var content = json.content;
if (content) {
if (Array.isArray(content)) {
+ // flatten
+ json.content = content = content.concat.apply([], content);
for (i = 0; i < content.length; i++) {
- nodes.push({ json: content[i], id: i, tree: jsx.children });
+ nodes.push({ json: content[i], id: i, tree: jsx.children, blockName: blockName });
}
} else {
- nodes.push({ json: content, id: 'children', tree: jsx});
+ nodes.push({ json: content, id: 'children', tree: jsx, blockName: blockName });
}
} else {
jsx.children = undefined;
@@ -119,7 +126,7 @@ Transformer.prototype.process = function(bemjson) {
};
Transformer.prototype.use = function() {
- [].push.apply(this.plugins, arguments)
+ this.plugins = [].concat.apply(this.plugins, arguments)
return this;
};
@@ -134,5 +141,7 @@ Transformer.prototype.Transformer = Transformer;
module.exports = function(opts) {
return new Transformer(opts || {});
};
+
module.exports.tagToClass = tagToClass;
module.exports.plugins = plugins;
+module.exports.styleToObj = styleToObj;
diff --git a/lib/plugins.js b/lib/plugins.js
index fd108038..04bae475 100644
--- a/lib/plugins.js
+++ b/lib/plugins.js
@@ -1,3 +1,4 @@
+var styleToObj = require('./helpers').styleToObj;
module.exports.defaultPlugins = [
function copyMods(jsx, bemjson) {
@@ -8,9 +9,19 @@ module.exports.defaultPlugins = [
Object.keys(bemjson).forEach(k => {
if(~blackList.indexOf(k)) { return; }
+ if(k === 'attrs') {
+ bemjson[k]['style'] && (jsx.props['style'] = bemjson[k]['style']);
+ }
jsx.props[k] = bemjson[k];
});
+ },
+ function stylePropToObj(jsx) {
+ if (jsx.props['style']) {
+ jsx.props['style'] = styleToObj(jsx.props['style'])
+ jsx.props['attrs'] &&
+ (jsx.props['attrs']['style'] = jsx.props['style']);
+ }
}
];
@@ -24,3 +35,4 @@ module.exports.whiteList = function(options) {
}
}
};
+
diff --git a/package.json b/package.json
index 306a961a..ac6f6dde 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,7 @@
},
"homepage": "https://github.com/bem-sdk/bemjson-to-jsx#readme",
"dependencies": {
- "@bem/entity-name": "^1.4.0",
+ "@bem/entity-name": "github:bem-sdk/bem-entity-name",
"@bem/naming": "^2.0.0-6",
"pascal-case": "^2.0.1"
}
diff --git a/test/helpers.js b/test/helpers.js
index 1db9c0a4..539138d9 100644
--- a/test/helpers.js
+++ b/test/helpers.js
@@ -1,6 +1,8 @@
const expect = require('chai').expect;
-const objToStr = require('../lib/helpers').objToStr;
+const helpers = require('../lib/helpers');
+const objToStr = helpers.objToStr;
+const styleToObj = helpers.styleToObj;
describe('helpers: objToStr', () => {
@@ -8,8 +10,8 @@ describe('helpers: objToStr', () => {
expect(objToStr({ hello: 'world' })).to.equal('{ \'hello\': \'world\' }');
});
- it('should return empty string for empty obj', () => {
- expect(objToStr({})).to.equal('');
+ it('should return empty obj for empty obj', () => {
+ expect(objToStr({})).to.equal('{}');
});
it('should process many keys', () => {
@@ -58,3 +60,15 @@ describe('helpers: objToStr', () => {
});
});
});
+
+describe('helpers: styleToObj', () => {
+ it('should transform style string to style obj', () => {
+ var obj = styleToObj('width:200px;height:100px;');
+ expect(obj).to.eql({ width: '200px', height: '100px' });
+ });
+
+ it('should not transform style obj to smth else', () => {
+ var obj = styleToObj({ width: '200px', height: '100px' });
+ expect(obj).to.eql({ width: '200px', height: '100px' });
+ });
+});
diff --git a/test/index.js b/test/index.js
index 456e34c9..bccf2262 100644
--- a/test/index.js
+++ b/test/index.js
@@ -99,6 +99,12 @@ describe('transform', () => {
).to.equal(`\n\n\n`);
});
+ it('should transform elem in context of block', () => {
+ expect(
+ transform({ block: 'button2', content: { elem: 'text', content: 'Hello' } }).JSX
+ ).to.equal(`\n\nHello\n\n`);
+ });
+
it('should treat mods as props', () => {
expect(
transform({ block: 'button2', mods: {theme: 'normal', size: 's'} }).JSX
diff --git a/test/plugins.js b/test/plugins.js
index 9c707112..ff7465bd 100644
--- a/test/plugins.js
+++ b/test/plugins.js
@@ -1,16 +1,14 @@
const expect = require('chai').expect;
var T = require('../lib');
-var transformer = T();
var BemEntity = require('@bem/entity-name');
-// var transform = transformer.process.bind(transformer);
describe('pluginis', () => {
describe('whiteList', () => {
it('without opts', () => {
- var res = transformer
+ var res = T()
.use(T.plugins.whiteList())
.process({ block: 'button2' });
@@ -20,7 +18,7 @@ describe('pluginis', () => {
});
it('whiteList', () => {
- var res = transformer
+ var res = T()
.use(T.plugins.whiteList({ entities: [{ block: 'button2' }].map(BemEntity.create) }))
.process({ block: 'button2', content: [{ block: 'menu' }, { block: 'selec' }] });
@@ -30,4 +28,22 @@ describe('pluginis', () => {
});
});
+ describe('stylePropToObj', () => {
+ it('styleProp to obj', () => {
+ var res = T().process({ block: 'button2', style: 'width:200px' });
+
+ expect(res.JSX).to.equal(
+ ``
+ );
+ });
+
+ it('attrs style to obj', () => {
+ var res = T().process({ block: 'button2', attrs: { style: 'width:200px' } });
+
+ expect(res.JSX).to.equal(
+ ``
+ );
+ });
+ });
+
});