BEM library for React
$ npm install --save @redneckz/react-bem-helper
$ yarn add @redneckz/react-bem-helper
This utility helps to declare BEM entities in terms of React components. Primarily it useful for projects with CSS artifacts (Sass, Less, PostCSS, ...).
Also compared to other libraries this one is aimed at simplicity and incremental adaptation of BEM (even for proprietary projects).
- Configurable
- BEM mixins support
- Modular CSS support
- Flow definitions
- Very small bundle ~8Kb
- Almost no dependencies
.some-button
padding: 8px
&--major
background: blue
&--size
&--small
padding: 4px
&--large
padding: 16px
import React from 'react';
import { BEM } from '@redneckz/react-bem-helper';
import styles from './some-button.sass';
const someButton = BEM(styles);
export const SomeButton = someButton(({ className, disabled, children }) => (
<button className={className} disabled={disabled}>
{children}
</button>
));
<React.Fragment>
<SomeButton major>Major</SomeButton>
<SomeButton size="small">Small</SomeButton>
<SomeButton major size="large">
Large
</SomeButton>
<SomeButton disabled>Disabled</SomeButton>
</React.Fragment>
will produce
<button class="some-button some-button--major">Major</button>
<button class="some-button some-button--size--small">Small</button>
<button class="some-button some-button--major some-button--size--large">Large</button>
<button class="some-button" disabled>Disabled</button>
Any valid component can be used to declare block or its elements
export const SomeButton = someButton(
class extends React.PureComponent {
render() {
const { className, disabled, children } = this.props;
return (
<button className={className} disabled={disabled}>
{children}
</button>
);
}
},
);
export const SomeButton = someButton('button'); // DOM component
Also library provides several factory functions to declare DOM components with restricted attributes list (div, span, form, button, input, label, textarea)
import React from 'react';
import { BEM, div } from '@redneckz/react-bem-helper';
import styles from './some-button.sass';
const someButton = BEM(styles);
export const SomeButton = someButton(div({ role: 'button' }));
Block with elements
.panel
display: flex
&__item
flex-grow: 0
&--align
&--start
align-self: flex-start
&--center
align-self: center
&--end
align-self: flex-end
&__spread
flex-grow: 1
import React from 'react';
import { BEM, div } from '@redneckz/react-bem-helper';
import styles from './panel.sass';
const panel = BEM(styles);
export const Panel = panel('div');
export const PanelItem = panel.item(div());
export const PanelSpread = panel.spread('div');
import React from 'react';
import { Config } from '@redneckz/react-bem-helper';
Config.ELEMENT_SEPARATOR = '__';
Config.MODIFIER_SEPARATOR = '--';
Generate stub for classnames
$ flow-typed create-stub classnames@x.x.x
Do not forget to configure includes and ignores to put library into scope.