Skip to content

Instantly share code, notes, and snippets.

@resistdesign
Created July 16, 2018 13:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save resistdesign/ec2ab98c1826a32cf25e4b2eeac13d2c to your computer and use it in GitHub Desktop.
Save resistdesign/ec2ab98c1826a32cf25e4b2eeac13d2c to your computer and use it in GitHub Desktop.
Named Children (FramedContainer) HOC
import T from 'prop-types';
import React, {Children, PureComponent} from 'react';
function getChildMapPropObject(child = {}) {
const newProps = {};
const {type, props: {children: propValue} = {}} = child;
if (typeof type === 'string') {
newProps[type] = propValue;
}
return newProps;
}
function getMappedChildProps(children) {
if (children instanceof Array) {
return Children
.toArray(children)
.reduce(
(acc, item) => ({
...acc,
...getChildMapPropObject(item)
}),
{}
);
} else if (children instanceof Object) {
return getChildMapPropObject(children);
} else {
return {};
}
}
export default function FramedContainer(WrappedComponent) {
return class extends PureComponent {
static propTypes = {
children: T.node
};
render() {
const {children} = this.props;
const newProps = {
...this.props,
...getMappedChildProps(children)
};
return (
<WrappedComponent
{...newProps}
/>
);
}
};
}
import T from 'prop-types';
import React, {PureComponent} from 'react';
import FramedContainer from './FramedContainer';
import Grid from '@material-ui/core/Grid';
class BaseScreen extends PureComponent {
static propTypes = {
header: T.node,
content: T.node,
footer: T.node
};
render() {
const {
header,
content,
footer
} = this.props;
return (
<Grid
container
direction='column'
>
<Grid>
{header}
</Grid>
<Grid>
{content}
</Grid>
<Grid>
{footer}
</Grid>
</Grid>
);
}
}
const Screen = FramedContainer(BaseScreen);
export default Screen;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment