Skip to content

Instantly share code, notes, and snippets.

@rafaelrinaldi
Last active April 24, 2018 15:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rafaelrinaldi/9116741aa81d9eb0fe1c389177cd1823 to your computer and use it in GitHub Desktop.
Save rafaelrinaldi/9116741aa81d9eb0fe1c389177cd1823 to your computer and use it in GitHub Desktop.
import React from 'react';
import { StyleSheet, css } from 'aphrodite/no-important';
import helpers from '../theme/helpers';
/**
* Base component that reduces boilerplate and enforces consistency.
* Highly inspired by the work done by the Hyperterm team.
*/
const hoc = Component =>
class BaseComponent extends Component {
constructor(props) {
super(props);
this._styles = this._createStyleSheet();
this._parseClassNames = this._parseClassNames.bind(this);
}
_createStyleSheet() {
return StyleSheet.create(this.styles ? this.styles(this.props) : {});
}
_parseClassNames(...args) {
const classes = args
/**
* 1. Try to match a class definied within the component itself.
* 2. Try to match the provided class name as a CSS helper.
* 3. Nothing was found, fallback is to print whatever the input was as a class name.
*/
.map(className => css(this._styles[className]) || css(helpers[className]) || className)
.filter(value => Boolean(value))
.reduce((accumulator, current) => accumulator.concat(current), []);
return classes.length ? classes.join(' ') : null;
}
componentWillUpdate() {
if (!process.env.PRODUCTION) {
this._styles = this._createStyleSheet();
}
}
render() {
if (!this.template) throw new TypeError("Component doesn't define `template`");
return this.template(this._parseClassNames);
}
};
export const PureComponent = hoc(React.PureComponent);
export const Component = hoc(React.Component);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment