Skip to content

Instantly share code, notes, and snippets.

@gianlucacandiotti
Last active May 26, 2018 16:36
Show Gist options
  • Save gianlucacandiotti/b4db55b7f80af5872994dc4641e3f6bf to your computer and use it in GitHub Desktop.
Save gianlucacandiotti/b4db55b7f80af5872994dc4641e3f6bf to your computer and use it in GitHub Desktop.
Higher Order Function that returns a HOC to attach Components as static props based on a set of values.
import React, { PureComponent } from 'react';
import values from 'lodash/fp/values';
import flow from 'lodash/fp/flow';
import forEach from 'lodash/fp/forEach';
import getDisplayName from '@/utils/getDisplayName';
/**
* Higher Order Function that returns a HOC to attach Components as static props based on a
* set of values.
* It allows you to go from:
* <Button type={Button.types.primary} />
* to:
* <Button.Primary />
* @param {String} propName Name of the property.
* @param {Object} propValues Values of said property. We will transform key value pairs into
* an array of values. Values should be in camelCase as a convention.
* @param {ReactComponent} Component Base component.
*/
const withAttachedProps = ({ propName, propValues }) => Component => {
class withAttachedPropsHOC extends PureComponent {
static initialize() {
flow(
values,
forEach(propValue => {
const [firstLetter, ...rest] = propValue;
const displayNameForValue = `${firstLetter.toUpperCase()}${rest.join(
'',
)}`;
const propToAttach = { [propName]: propValue };
const ComponentWithProp = componentProps => (
<Component {...componentProps} {...propToAttach} />
);
ComponentWithProp.displayName = `${getDisplayName(
Component,
)}.${displayNameForValue}`;
this[displayNameForValue] = ComponentWithProp;
}),
)(propValues);
}
render() {
return <Component {...this.props} />;
}
}
withAttachedPropsHOC.displayName = `withAttachedProps(${getDisplayName(
Component,
)})`;
withAttachedPropsHOC.initialize();
return withAttachedPropsHOC;
};
export default withAttachedProps;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment