Библиотека для описания React-компонентов в виде деклараций БЭМ-сущностей. Библиотека работает поверх обычных React-компонентов и предоставляет API для описания деклараций блоков, элементов и их модификаторов. Блоки и элементы созданные с помощью этой библиотеки полностью совместимы с любыми React-компонентами: могут использовать внутри себя готовые React-компоненты и могут быть использованы сами в коде на React.
Если вы используете i-bem.js и хотите получить преимущества React-подхода, не потеряв привычные БЭМ-термины и декларативность.
Если вы используете React и хотите получить преимущества БЭМ-методологии.
Сокращение синтаксического шума.
import React from 'react';
export default class MyBlock extends React.Component {
render() {
const { myMod1, myMod2, children } = this.props;
return (
<div className={`MyBlock MyBlock_myMod1_${myMod1} MyBlock_myMod2_${myMod2}`}>
{children}
</div>
);
}
};import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
mods({ myMod1, myMod2 }) {
return { myMod1, myMod2 };
}
});NB Альтернативно для генерации CSS-классов можно использовать библиотеки:
Модификаторы, это одно из ключевых понятий БЭМ-методологии, помогающее создавать вариации одного и того же компонента. bem-react-core позволяет удобно декларировать функциональность для модификаторов (подробнее в документации).
import React from 'react';
export default class MyBlock extends React.Component {
render() {
const { myMod1, myMod2, children } = this.props;
let className = 'MyBlock',
content = [children];
if(myMod1 === 'myVal1') {
className += `MyBlock_myMod1_${myMod1}`;
content.unshift('Modification for myMod1 with value myVal1.');
}
if(myMod2 === 'myVal2') {
className += `MyBlock_myMod1_${myMod2}`;
content.unshift('Modification for myMod2 with value myVal2.');
}
return (
<div className={className}>
{content}
</div>
);
}
};Добавление модификаций требует добавления условий в основной код. Можно было бы использовать создание наследуемых классов, но тогда затруднительно выражать несколько одновременно присутствующих модификаторов.
// MyBlock.js
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
mods({ myMod1, myMod2 }) {
return { myMod1, myMod2 };
}
});
// MyBlock_myMod1_myVal1.js
import { declMod } from 'bem-react-core';
export default declMod(({ myMod1 }) => myMod1 === 'myVal1', {
block : 'MyBlock',
content() {
return [
'Modification for myMod1 with value myVal1.',
this.__base.apply(this, arguments)
];
}
});
// MyBlock_myMod2_myVal2.js
import { declMod } from 'bem-react-core';
export default declMod(({ myMod2 }) => myMod2 === 'myVal2', {
block : 'MyBlock',
content() {
return [
'Modification for myMod2 with value myVal2.',
this.__base.apply(this, arguments)
];
}
});NB Для создания JS-классов используется библиотека Inherit с возможностью делать «super» вызов (this.__base.apply(this, arguments)) без указания имени метода (super.content.apply(this, arguments)).
Уровни переопределения – это инструмент БЭМ-методологии, который помогает разделять и переиспользовать код. Например разделять код для разных платформ. bem-react-core позволяет удобно декларировать React-компоненты на разных уровнях переопределения.
// common.blocks/MyBlock/MyBlock.js
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
tag : 'a',
attrs({ url }) {
return { href : url };
}
});
// decktop.blocks/MyBlock/MyBlock.js
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
willInit() {
this.state = {};
this.onMouseEnter = this.onMouseEnter.bind(this);
this.onMouseLeave = this.onMouseLeave.bind(this);
},
mods() {
return { hovered : this.state.hovered };
}
attrs({ url }) {
return {
...this.__base.apply(this, arguments),
onMouseEnter : this.onMouseEnter,
onMouseLeave : this.onMouseLeave
};
},
onMouseEnter() {
this.setState({ hovered : true });
},
onMouseLeave() {
this.setState({ hovered : false });
}
});Сборку можно сконфигурировать так, что функциональность, описанная в desktop.blocks попадет только в сборку common.blocks + desktop.blocks для десктопных браузеров и не попадёт в сборку common.blocks + touch.blocks для мобильных.
npm i -S bem-react-core
yarn add bem-react-core
Используя лоадер для webpack.
npm i -D webpack-bem-loader babel-core
webpack.config.js
// ...
module : {
loaders : [
{
test : /\.js$/,
exclude : /node_modules/,
loaders : ['webpack-bem', 'babel']
},
// ...
],
// ...
},
bemLoader : {
techs : ['js', 'css'],
levels : [
`${__dirname}/common.blocks`,
`${__dirname}/desktop.blocks`,
// ...
]
}
// ...Используя плагин для Babel.
npm i -D babel-plugin-bem-import
.babelrc
{
"plugins" : [
["bem-import", {
"levels" : [
"./common.blocks",
"./desktop.blocks"
],
"techs" : ["js", "css"]
}]
]
}© 2017 YANDEX LLC. Код лицензирован Mozilla Public License 2.0.