Skip to content

Instantly share code, notes, and snippets.

@gaearon
Last active March 23, 2018 17:18
Show Gist options
  • Save gaearon/84f04ff35334ed80dcaf to your computer and use it in GitHub Desktop.
Save gaearon/84f04ff35334ed80dcaf to your computer and use it in GitHub Desktop.
BEM in React
'use strict';
var React = require('react'),
classSet = require('react/lib/cx'),
_ = require('underscore');
var ClassNameMixin = {
propTypes: {
className: React.PropTypes.string,
context: React.PropTypes.string
},
getClassName() {
var componentClassName = this.className || this.constructor.displayName,
classNames = [componentClassName],
context = this.props.context,
modifiers;
if (this.getCSSModifiers) {
modifiers = this.getCSSModifiers();
} else {
modifiers = [];
}
if (_.isObject(modifiers) && !_.isArray(modifiers)) {
modifiers = classSet(modifiers).split(' ');
}
if (context) {
modifiers.push('isIn' + context[0].toUpperCase() + context.slice(1));
}
if (this.props.className) {
classNames = classNames.concat(this.props.className.split(' '));
}
classNames = _.union(
classNames,
_.compact(modifiers).map(m => componentClassName + '--' + m)
);
return classNames.join(' ');
}
};
module.exports = ClassNameMixin;
@gaearon
Copy link
Author

gaearon commented Sep 20, 2014

@mjackson (are mentions broken here?), it sure looks cleaner that way!
Thank you 👍

@mjackson
Copy link

mjackson commented Oct 7, 2014

Haha, yeah I think mentions are broken :) yw!!

@ryanflorence
Copy link

this is convenient for the original author, but one of the reasons to use BEM is to make your code greppable, so that you can easily identify where selectors are used. If you're concatting them with JS, you lose this.

@Couto
Copy link

Couto commented Oct 13, 2014

@rpflorence Would you suggest some other approach, or do you just explicitly set all the classnames?

@Couto
Copy link

Couto commented Oct 13, 2014

Wow that file doesn't help legibility at all, but I think I can see your point. Thanks for the link :)

@gaearon
Copy link
Author

gaearon commented Nov 2, 2014

one of the reasons to use BEM is to make your code greppable, so that you can easily identify where selectors are used.

Well, maybe, but for me the win is mostly no cascading. I don't need it being greppable because of consistent naming. I know SomeComponent* styles always live in SomeComponent.less.

@gaearon
Copy link
Author

gaearon commented Nov 2, 2014

Also, class name is only used for root selectors (for components themselves). Children selectors (Something-somePart) stay greppable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment