- base
[{Object|Array}]
– base class (block or element) and/or array of mixins - prototypeProps
{Object}
– instance's fields and methods - staticProps
{Object}
– static fields and methods - wrapper
{Function}
- произвольная функция-обертка для использования HOC. Вы можете использовать эту функцию для оборачивания компонентов, так какdecl
не возвращает React-компонент. Эта функция будет вызвана после того как все декларации применятся и будет создан React-компонент.
- predicate
{Object|Function}
– modifier matcher or custom match function - prototypeProps
{Object}
– instance's fields and methods - staticProps
{Object}
– static fields and methods
When you use modifier matcher object as a first argument, the mods
will be set automatically.
// MyBlock_myMod1_myVal1.js
import { declMod } from 'bem-react-core';
export default declMod({ myMod1 : 'myVal1' }, {
block : 'MyBlock',
content() {
return [
'Modification for myMod1 with value myVal1.',
this.__base(...arguments)
];
}
});
// MyBlock_myMod1.js
import { declMod } from 'bem-react-core';
export default declMod({ myMod1 : '*' }, {
block : 'MyBlock',
content() {
return [
'Modification for myMod1 with any value.',
this.__base(...arguments)
];
}
});
// MyBlock_myMod1.js
import { declMod } from 'bem-react-core';
export default declMod({ myMod1 : 'myVal1', myMod2 : 'myVal2' }, {
block : 'MyBlock',
content() {
return [
'Modification for myMod1 with value myVal1 and myMod2 with value myVal2.',
this.__base(...arguments)
];
}
});
// MyBlock_myMod1.js
import { declMod } from 'bem-react-core';
export default declMod({ myMod1 : ({ myMod1, customProp }) => myMod1 === customProp }, {
block : 'MyBlock',
content() {
return [
'Modification for myMod1 with custom match function.',
this.__base(...arguments)
];
}
});
Modifier declaration may get custom match function as a first argument.
This function gets props as an argument and it should return boolean result.
If this function returns true
, declaration will be applied to the component.
In this case if you need CSS classes, you have to operate with mods
implicitly.
// MyBlock_myMod1.js
import { declMod } from 'bem-react-core';
export default declMod(({ myMod1 }) => myMod1 && myMod1 !== 'myVal1', {
block : 'MyBlock',
mods({ myMod1 }) {
return { ...this.__base(...arguments), myMod1 };
},
content() {
return [
'Modification for myMod1 with any value except myVal1.',
this.__base(...arguments)
];
}
});
All methods get props as an argument. Only wrap
and content
work with the different arguments.
Block name. It's used for CSS class generation.
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock'
});
<MyBlock/>
<div class="MyBlock"></div>
Elem name. It's used for CSS class generation.
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
elem : 'MyElem'
});
// <MyBlockElem/>
<MyBlockElem/>
<div class="MyBlock-MyElem"></div>
HTML tag for component, default: div
.
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
tag : 'span'
});
<MyBlock/>
<span class="MyBlock"></span>
HTML attributes and React bindings.
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
attrs({ id }) {
return {
id,
tabIndex : -1,
onClick : () => console.log('clicked')
};
}
});
<MyBlock id="the-id"/>
<div class="MyBlock" id="the-id" tabindex="-1"></div>
Additional custom CSS class.
From JSX:
<MyBlock cls="custom-class"/>
<div class="MyBlock custom-class"></div>
From declaration:
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
cls({ customClass }) {
return `${customClass} decl-custom-class`;
}
});
<MyBlock customClass="props-custom-class"/>
<div class="MyBlock props-custom-class decl-custom-class"></div>
Block or elem modifiers. All keys are used for CSS class generation.
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
mods({ disabled }) {
return {
disabled,
forever : 'together'
};
}
});
<MyBlock disabled/>
<div class="MyBlock MyBlock_disabled MyBlock_forever_together"></div>
From JSX:
<MyBlock mix={{ block : 'MixedBlock' }}/>
<MyBlock mix={[{ block : 'MixedBlock' }, { block : 'MixedBlock2', elem : 'MixedElem2' }]}/>
<div class="MyBlock MixedBlock"></div>
<div class="MyBlock MixedBlock MixedBlock2-MixedElem2"></div>
From declaration:
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
mix({ mixedElem }) {
return { block : 'MixedBlock2', elem : mixedElem };
}
});
<MyBlock mixedElem="MixedElem2"/>
<div class="MyBlock MixedBlock2-MixedElem2"></div>
From declaration and from JSX:
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
addMix({ mixedElem }) {
return { block : 'MixedBlock2', elem : mixedElem };
}
});
<MyBlock mixedElem="MixedElem2" mix={{ block : 'MixedBlock' }}/>
<div class="MyBlock MixedBlock2-MixedElem2 MixedBlock"></div>
The content of the component. This method gets props as a first argument and this.props.children
as a second one.
This method should return: string, React component, array of strings and/or React components.
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
content({ greeting }, children) {
return `${greeting}. ${children}`;
}
});
<MyBlock greeting="Mr">Black</MyBlock>
<div class="MyBlock">Mr. Black</div>
This method helps to wrap current component to another component, DOM element or any other combination of them.
The wrap
gets current React component as a first argument.
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
wrap(component) {
return <section>{component}</section>;
}
});
<MyBlock/>
<section>
<div class="MyBlock"></div>
</section>
It's default lifecycle methods
of React component, but we removed word component
from methods names.
All of this methods can be redefined on other levels or by modifiers like any other fields and methods.
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock',
willInit() {
// original name: constructor
},
willMount() {
// original name: componentWillMount
},
didMount() {
// original name: componentDidMount
},
willReceiveProps() {
// original name: componentWillReceiveProps
},
shouldUpdate() {
// original name: shouldComponentUpdate
},
willUpdate() {
// original name: componentWillUpdate
},
didUpdate() {
// original name: componentDidUpdate
},
willUnmount() {
// original name: componentWillUnmount
},
render() {
// Current component will be rewrited. CSS class generation,
// default fields and methods will be ignored.
}
});
Should be declared in the staic fields.
import PropTypes from 'prop-types';
import { decl } from 'bem-react-core';
export default decl({
block : 'MyBlock'
}, {
propTypes : {
theme : PropTypes.string.isRequired,
size : PropTypes.oneOf(['s', 'm', 'l'])
},
defaultProps : {
theme : 'normal'
}
});