Smart components for using parts of BEM methodology with React. Used best together with styled-components.
You can play with everything at this CodePen playground!
There are a lot of things bemto-components
would do in the future, but for now here are a few main features:
-
bemto-components
allow you to use BEM-style modifiers for your React components using the _modifier prop syntax. For ecample, if you'd do this (where the Foo is bemto-component):<Foo _bar />
, each className of the Foo component would be duplicated with an addition of the_bar
modifier. That allows you to use the BEM modifiers in your CSS (both any external, or using styled-components). -
bemto-components
gives you a way to easily create a component from a simple string that can contain an optional tag name (for now it defaults todiv
if omitted, but more on it coming, see the [3.]) and a bunch of classNames:bemto('span.myClass1.myClass2')
would create a span component with themyClass1 myClass2
, which would have all the other bemto features (like the applying of modifiers). -
bemto-components
gives you a way to easily create BEM βElementsβ for your components. -
coming soon
bemto-components
would allow you to think less about handling your components' tag names by embracing some prop-based polymorphism. More on it when it would be ready!
Work in progress. Everything could change, don't treat as a stable thingy. I did not do any performance metrics and did not do any premature optimisations. Also: no tests for now. You're welcome to test, benchmark and overall think about this; create issues and PRs.
npm install --save bemto-components
At definition:
import bemto from 'bemto-components';
const Block = bemto('div.myBlock');
Usage:
<Block _mod>
Hello
</Block>
This would output
<div class='myBlock myBlock_mod'>Hello</div>
Both boolean and string values are supported for modifiers:
<Block _mod1 _mod2='mod2value' />
Just pass a bemto-component inside styled-components:
import bemto from 'bemto-components'
const Block = styled(bemto('div'))`
background: red;
&_mod {
background: lime;
}
`)
Usage:
<Block _mod />
Just like this.
For bemto-components you can call .elem()
method to create an element:
import bemto from 'bemto-components';
const Block = bemto('.myBlock');
Block.Element = Block.elem('myElement');
And then use it like this:
<Block>
<Block.Element>Hello</Block.Element>
</Block>
Which would output
<div class='myBlock'><div class='myBlock__myElement'>Hello</div></div>
Like with creation of Blocks, you can use a tagString, passing it as a second param when creating an element:
import bemto from 'bemto-components';
const Block = bemto('.myBlock');
Block.Element = Block.elem('myElement', 'span.extraElemClass');
Again,
<Block>
<Block.Element>Hello</Block.Element>
</Block>
Would output
<div class='myBlock'><span class='myBlock__myElement extraElemClass'>Hello</span></div>
As after wrapping with styled-component you would lose the elem
method, there is an extra way to create elements:
import bemto from 'bemto-components'
const Block = styled(bemto())`
background: red;
&_mod {
background: lime;
}
&__myElement {
background: blue;
}
`);
Block.Element = bemto.elem(Block, 'myElement', 'span.extraElemClass');
And there you'd even get the styled-components' names as block names.
It is already possible to kinda use Elements from BEM with react and/or styled components without adding anything extra:
const Block = styled.div`
background: red;
`
Block.Element = styled.span`
background: blue;
${Block}:hover & {
background: lime;
}
`
And in usage:
<Block>
<Block.Element>Hewwo!</Block.Element>
</Block>
This way you can easily couple the element with its block. I have some plans on how we could use more familiar to BEM __elements
, so keep in touch if interested!